一、堆栈溢出检测

问题:

  • 问题一:FreeRTOS堆栈溢出检测的方法?

解答:
参看:FreeRTOS学习 – FreeRTOSConfig.h介绍

两种堆栈溢出检测方法:
方法1:

  • 开启方法,configCHECK_FOR_STACK_OVERFLOW==1
  • 检测原理:通过在任务切换时,检测栈顶指针和栈起始指针,或者栈顶指针和栈结束指针是否越界,如果越界,在任务切换的时候触发堆栈溢出钩子Hook函数。

方法1的优点就是快。但是缺点就是不能检测所有的堆栈溢出。比如任务执行中确实出现了栈顶指针越界的情况,但是在任务切换之前栈顶指针又指回到了合法位置,这个时候就检测不到栈溢出了。

方法2:

  • 1、开启方法:configCHECK_FOR_STACK_OVERFLOW==2
  • 2、检测原理:在任务创建时,将任务栈所有的数据初始化为一个固定值0xa5,通过任务切换的时候,来判断栈底16个或20个字节是否都为0xa5,如果被修改过,会触发堆栈溢出钩子Hook函数。

方法2 比 方法 1要慢一些,但是对用户而言还是很快的。方法2能检测到几乎所有的堆栈溢出,但是也有一些情况检测不到,比如溢出值和标记值相同的情况。

二、优先级

问题:

  • 问题一:FreeRTOS的任务优先级是如何定义和使用的?

解答
定义:
在FreeRTOS中,任务优先级的范围通常是0到(configMAX_PRIORITIES-1),其中configMAX_PRIORITIES是FreeRTOS配置文件中定义的最大优先级数。用户可以根据实际需要设置这个值,以平衡实时性和内存使用效率。其中 0 是最低优先级,configMAX_PRIORITIES-1 是最高优先级。

宏 configMAX_PRIORITIES 不能超过 32 ! 也就是优先级不能超过 32 级。

#define configMAX_PRIORITIES (32) //可使用的最大优先级

使用:
创建任务时指定优先级:在创建任务时,可以通过vTaskCreate函数指定任务的优先级。

xTaskCreate(TaskFunction, "Task1", 1000, NULL, 2, NULL);

这里的 2 表示任务的优先级。

三、项目里RTOS是如何实现的?

问题:

  • 问题一:项目里RTOS是如何实现的?

解答

1、安装FreeRTOS库和配置工程。
2、创建任务
3、任务间的通信和同步:消息队列、信号量、事件标志
4、任务优先级和调度

任务的状态:
就绪(Ready)、运行(Running)、阻塞(Blocked)或挂起(Suspended)

任务切换:
1、执行系统调用
2、系统滴答定时器 (SysTick) 中断
3、PendSV 中断服务函数
4、FreeRTOS 时间片调度

四、FreeRTOS移植步骤?

问题:

  • 问题一:如何进行RTOS的移植?

解答
参看:GD32F4开发 – FreeRTOS移植
RTOS的移植需要根据目标硬件平台进行修改和适配。首先,了解目标硬件的体系结构、寄存器设置、中断机制第二个;然后修改RTOS的内核代码,使其能够在目标硬件上正确运行,包括任务调度、内核管理、中断处理等模块的适配;最后,进行测试和验证,确保RTOS在目标硬件上的稳定性和正确性。

五、串口、中断注意事项?

问题:

  • 问题一:串口、中断注意事项?

解答
串口设置包含:开启串口时钟、设置响应的IO口模式、设置波特率、数据位长度、奇偶校验位、DMA等信息。

1、需要清除标志位
2、不建议在中断里执行printf打印,并且RXNE中断如果执行代码太久(最大几十us,和波特率、位数有关系)就会丢数据。
3、中断服务函数尽可能的短,占用尽量少的时间,防止字符的丢失。
4、在中断服务函数中,不能返回值,因为中断服务函数的触发是随机的,不可调用,要是有返回值的话,就存在堆栈的问题,但是没有具体的一个内存来存放返回值,会造成混乱,所以不行;
5、不能在中断服务函数中进行浮点运算;
6、不能在中断服务函数中调用不可重入函数如printf等;
7、不能传递参数;

  • *问题一:在RTOS中,如何进行中断处理?
    解答
    首先,在中断服务程序中要尽量减少处理时间,避免长时间占用CPU,通常只进行简单的操作,然后设置标志或发送信号量等通知任务进行后续处理。在任务中根据标志或信号量来判断是否发生中断,并进行相应的处理。

六、请描述一下你使用过的调试工具和方法?

问题:

  • 问题一:请描述一下你使用过的调试工具和方法?

解答
使用过JTAG、串口调试、逻辑分析仪等调试工具。调试方法包括单步调试、断电调试、观察变量值、使用日志打印信息等。

七、FreeRTOS的抢占式调度和时间片调度有什么区别?

问题:

  • 问题一:FreeRTOS的抢占式调度和时间片调度有什么区别?

解答

  • 1. 定义和使用场景
    抢占式调度: 适用于优先级不同的任务。高优先级任务可以抢占低优先级任务的执行权。在FreeRTOS中,任务优先级数值越大表示优先级越高。
    时间片调度: 适用于优先级相同的任务。当多个任务具有相同的优先级时,系统会在每个时间片结束切换到下一个任务,确保每个任务都能公平地获取CPU时间。在FreeRTOS中,时间片等于SysTick中断周期(滴答定时器中断)。
  • 2. 工作原理:
    抢占式调度: 每个任务都有一个优先级,系统总是运行优先级最高的就绪任务。当一个高优先级任务就绪时,当前运行的低优先级任务会被中断,高优先级任务开始执行。
    时间片调度: 当多个任务具有相同的优先级时,系统会在每个时间片结束后切换到下一个任务。例如,如果有三个同等优先级的任务Task1、Task2、Task3,它们会轮流执行,每个任务在一个时间片后切换到下一个任务。
  • 3. 优缺点:
    抢占式调度:
    优点: 能够快速响应高优先级任务,适合需要快速响应的应用场景。
    缺点: 可能会导致某些低优先级任务长时间得不到执行,造成不公平的现象。
    时间片调度:
    优点: 能够保证每个任务都能获得公平的CPU时间,适合需要公平分配的CPU时间的场景。
    缺点: 可能会增加上下文切换的开销,影响系统的整体效率。

八、如何保证FREERTOS 两个任务间数据完整性?

问题:

  • 问题一:如何保证FREERTOS 两个任务间数据完整性?

解答
在FreeRTOS中,为了保证两个任务间数据的完整性,可以使用以下方法:
1. 互斥锁(Mutex): 当任务需要访问共享资源时,可以获取互斥锁,保证在同一时刻只有一个任务可以访问该资源。
2. 信号量(Semaphore): 信号量可以用于任务间同步,也可以用来保护临界区,确保在同一个时刻只有一个任务可以执行特定的代码段。
3. 队列(Queue): 任务通过队列安全地传递数据,队列提供了一种机制,可以让一个任务将数据传递给另一个数据,而不会导致数据丢失或损坏。

九、任务优先级翻转

问题:

  • 问题一:什么是优先级翻转?
    解答:
    优先级翻转是指拥有低优先级的任务在等待一个拥有高优先级的任务释放共享资源时,导致高优先级任务被阻塞的现象。在FreeRTOS中,任务的优先级用于调度,优先级翻转可能导致实时性任务的执行延迟,从而影响系统的性能。
    导致优先级翻转的原因就是对任务之间共享资源的管控不严谨。
    举个例子:
    任务A、B、C三个任务,优先级从大到小排序A>B>C,其中任务C持有任务A需要的资源,导致任务A被迫等待,但是在等待期间,任务B是可以执行的,当任务B执行时,就打断了任务C而先于任务A运行(此时的任务A在等待资源),这样系统中的任务执行顺序就被打乱了,从而导致了优先级翻转。
  • 问题二:避免任务优先级翻转的方法有哪些?
    解答
    1. 优先级继承机制: 当高优先级任务因持有资源的低优先级任务被阻塞时,低优先级任务临时继承高优先级任务的优先级,直到资源释放,防止优先级翻转。
    2. 优先级天花板机制: 每个共享资源都有一个最高优先级(天花板优先级),当任务获取资源时,其优先级会暂时提升到资源的天花板级别,防止低优先级任务在资源释放之前被高优先任务抢占。

函数 uxTaskPriorityGet() 用来查询指定任务的优先级。
函数 vTaskPrioritySet() 用于改变某一个任务的任务优先级。

十、RTOS中信号量和互斥量的区别?

问题:

  • 问题一:RTOS中信号量和互斥量的区别?
    解答:
    信号量(Semaphore): 信号量是一种计数器,用于控制多个任务对共享资源的访问。它可以是一个计数信号量(多个状态),也可以是一个二值信号量(只有两个状态:0和1)。信号量允许多个任务同时访问资源,适用于资源数量大于1的情况,常用于资源管理和任务同步。
    互斥量(Mutex): 互斥量是一种二值信号量,其值只能是0和1。互斥量用于确保在任务时刻只有一个任务可以访问共享资源,主要防止资源的并发访问。适用于资源数量为1且需要独立访问的情况。常用于保护临界资源,防止数据竞争和不一致性。
  • 问题二:FreeRTOS中的信号量有哪些类型?
    解答:
    FreeRTOS中有三种主要类型的信号量:
    二值信号量: 用于锁定资源,类似于互斥锁,它们只能有两种状态:获取和释放。
    计数信号量: 可以用于管理多个相同的资源,或者用来同步多个任务。
    递归信号量: 是计数信号量的一种特殊形式,允许同一个任务多次获取同一个资源。

十一、如何在RTOS中实现任务之间的同步和通信?

问题:

  • 问题一:如何在RTOS中实现任务之间的同步和通信?
    解答:
    任务同步与通信:
    信号量: 用于同步任务间的操作或控制对共享资源的访问。
    消息队列: 允许任务之间传递消息,通过队列的形式传递数据和信号,适合复杂的数据通信。
    事件标志: 多个任务可以通过检查和设置事件标志组中的位来同步执行特定的事件。
    互斥锁: 用于保证资源的互斥访问,避免多个任务同时访问共享资源。
    邮箱: 用于任务之间的低延迟数据传递,适合中断服务程序和任务的通信。

十二、上下文切换?

问题:

  • 问题一:什么事上下文切换?
    解答:
    上下文切换是指多任务环境中,从当前执行的任务切换到另一个任务执行的过程。上下文切换包括保存当前任务的CPU状态(如寄存器、程序计数器),以及加载即将运行任务的CPU状态,这是多任务操作系统中实现任务并行的核心机制。
  • 问题二:如何在RTOS中减少任务的上下文切换开销?
    解答:
    优化调度算法: 选择适合任务模型的调度算法,减少不必要的任务切换。
    减少中断频率: 降低中断触发的频率,较少调度器频繁打断任务。
    使用长时间片: 增加时间片的长度,减少频繁的任务切换。