推荐文档
【官方教程书-英文版】Mastering-the-FreeRTOS-Real-Time-Kernel.v1.1.0.pdf 【官方教程书-机翻版】Mastering-the-FreeRTOS-Real-Time-Kernel.v1.1.0 zh.pdf
RTOS(Real-time operating system)是什么,为什么我们需要它?
为什么我们需要它?
RTOS 中文名:实时操作系统,是Real-time operating system的缩写 想象一下你在开发一个单片机程序,如果只是流水灯之类的功能单一简单的程序还好 但是我如果要同时实现 - 10颗LED以不同频率呼吸 - 10颗按键来控制LED的开关 - 1个屏幕来显示信息 - 串口还连接了传感器,要不定时收发数据 - 还需要控制电机等设备
是不是就已经头疼了?单个任务不是很复杂,但是要结合在一起同时运行,裸机编写代码就很困难了。 如果这些任务能像PC上的应用程序一样能够独立同时运行就好了。 RTOS能够解决这个问题,如同windows能够允许不同应用程序同时运行一样,RTOS也允许不同任务同时运行,并且像管理应用程序一样管理任务,RTOS可以关闭任务,分配cpu时间给任务,实现类似多线程的效果。
RTOS是什么
FreeRTOS
为什么选择FreeRTOS
- 开源
- 免费
- 应用广泛
- 大家都在用
- 使用,移植简单
FreeRTOS一些原理
FreeRTOS本质上是一个介于硬件和“任务”之间的中间层程序,来"管理"任务的运行。 在上面的例子中我们发现,即使任务很多,CPU多数时间也处于"等待"的状态中 为什么我们不能让CPU在一个任务的"等待"阶段,去干另外一个任务事情呢? 这就是FreeRTOS实现的功能 (即使CPU不是空闲的也能执行多任务,下文会提到)
调度
在任务时间不冲突的场景中
FreeRTOS的调度很简单
那个任务的延时到期了该执行了就执行那个任务
注意此时需要让出CPU(如延时 删除任务 释放CPU等函数)

抢占式调度
即当有高优先级任务需要执行时,无论当前任务释放已经释放CPU都执行高优先级任务
在ESP32中该调度方式是默认开启的


时间片轮转
当任务优先级相同时,调度器每隔一个tick就会切换一次任务
(即使当前任务没有让出CPU)
类似linux和windows的多线程实现
该调度方式会在单个任务运行时长多于一个滴答时钟周期时影响任务实时性
锁
根据上文介绍即使是没有让出CPU时,CPU仍然可能执行其他任务 对于一些IO任务这是危险的! 例如 任务一在使用串口发送数据 任务二在任务一还没发完数据时就运行了 这样会导致同个外设被两个任务"同时"访问,造成不可预期的后果
互斥锁
此时我们就需要一个工具来保护这些访问过程 让某些资源只能"同时"被一个任务访问 我们可以利用一个标志位,当一个资源被访问时置1,空闲时置0 这样当任务需要访问资源时先读取该标志位如果为1就等待为0再访问,这样就保证了安全性。 互斥锁就是这个工具
1.xSemaphoreCreateMutex():
函数原型:SemaphoreHandle_t x SemaphoreCreateMutex( void );
功能:用于创建一个互斥锁。
返回值:返回一个指向新创建的互斥锁的句柄(handle)。
2.xSemaphoreTake():
函数原型:BaseType_t x SemaphoreTake(SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait);
功能:尝试获取互斥锁。如果互斥锁当前可用(未被锁定),则获取成功;否则,任务将被阻塞,直到互斥锁可用或达到超时时间。
参数:
xSemaphore:互斥锁的句柄。
xTicksToWait:等待获取互斥锁的最大时间,可以使用portMAX_DELAY来表示永久等待。
返回值:获取成功时返回pdTRUE,获取失败(超时或出错)时返回pdFALSE。
3.xSemaphoreGive():
函数原型:BaseType_t x SemaphoreGive(SemaphoreHandle_t xSemaphore);
功能:释放互斥锁,允许其他任务获取它。
参数:xSemaphore:互斥锁的句柄。
返回值:成功返回pdTRUE,失败返回pdFALSE。