使用FreeRTOS时的一些注意事项

1、临界区的使用

  临界区是一把“重型锁”,它的核心作用是:保护一段极短的代码,在执行时不被任何中断或其他任务干扰。
  简单说,就是创造一个临时的“真空地带”,保证操作的完整性。但要记住,它必须短,越短越好。
  🟢 什么时候必须用临界区?
  当操作一个既会被任务访问,又会被中断修改的共享资源时,就必须用。典型场景有:
    保护非原子操作:比如在32位CPU上读写一个64位变量,这个操作本身不是一条指令完成的,可能会被中断打断。
    保护共享外设寄存器:如果你在任务里配置某个外设,而中断服务程序也可能配置同一个外设,就需要保护。
    需要多条指令完成的原子逻辑:比如经典的“读-改-写”操作(global_var |= 0x01;),它包含多条汇编指令,必须整个流程不被中断。
  🔴 什么时候绝对不要用?
    调用API函数时:绝大多数 RTOS 函数(如 xQueueSend, xSemaphoreGive)内部已自带保护,你不需要再套一层。
    耗时长的操作:在临界区内进行计算、调用复杂函数、操作外设,会长时间屏蔽中断,破坏系统的实时性。
    调用可能会阻塞的函数:这是死路一条,当前任务持有临界区却进入阻塞,系统就卡死了。

  ✅ 正确的替代方案是什么?
  在很多场景下,有比直接屏蔽中断更好的方法,对系统影响更小。
  只保护数据,不保护任务切换(挂起调度器)
    如果数据只被多个任务共享,不会被中断使用,可以只用 vTaskSuspendAll() 和 xTaskResumeAll()。它只防止任务切换,中断还能响应,系统响应更快。
  用互斥量 (Mutex) 保护任务间资源
    这是推荐的做法。它只让访问同一资源的任务互斥,不影响其他任务和中断。但如果资源在中断里也要用,就只能用临界区。

 2、宏定义define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY

  #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5

  此宏定义用于设置 FreeRTOS可管理的最高中断优先级, 当中断的优先级数值小于此宏定义比如3时,此中断不受 FreeRTOS 管理。此宏定义用于辅助配置宏 configMAX_SYSCALL_INTERRUPT_PRIORITY。

3、宏定义define configTOTAL_HEAP_SIZE

  #define configTOTAL_HEAP_SIZE ((size_t)(60*1024))

  该宏定义用来设置系统所有堆的大小,即总共有多少堆,用于 FreeRTOS 动态内存管理的内存大小, 即 FreeRTOS 的内存堆, 单位为Byte。如果堆内存不够任务就会创建失败。

 

posted @ 2026-04-25 22:14  孤情剑客  阅读(58)  评论(0)    收藏  举报