FreeRTOS是一个迷你的实时操作系统内核。FreeRTOS系统相当的小巧,最小化的FreeRTOS内核仅包括3个.c文件和少数头文件,总共不到9000行代码,编译后的映像小于10KB。
FreeRTOS的代码可以分解为三个主要区块:任务,通讯和硬件接口,可实现任务管理、时间管理、信号量、消息队列、内存管理、记录功能等功能。
主要讲讲任务和消息队列
1.任务控制模块(TCB)
当xTaskCreate()函数被调用时,一个任务被创建,并放入就绪列表。就绪列表是一个双向链表,在链表中每个任务按优先级排列,并且设置有记录相关信息的变量和进行各种操作的指针。
2.任务优先级
RTOS的基本工作单元是任务,所有任务都有一个用户优先级,如:从0到最高,如:0(最低),1,2,3 (最高) 在FreeRTOSConfig.h中设置优先级个数。
每一个优先级都是一个列表,其中可以包含多个任务。
3.任务调度
系统节拍:FreeRTOS有一个定期的时钟节拍(通常是MS级) (在FreeRTOSConfig.h中设置),每个节拍中断释放时vTaskSwitchContext()函数就会被调用。它就会选择优先级最高的就绪任务并抢占优先级低的任务的CPU让它执行。这就是可剥夺式多任务内核。
保证高优先级任务顺畅执行是FreeRTOS最核心的部分
//找出就绪列表中优先级最高的任务
while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )
{
configASSERT( uxTopReadyPriority );// uxTopReadyPriority设定好的高于或等于用户设置的最高优先级
--uxTopReadyPriority; //得到最高优先级数
}
listGET_OWNER_OF_NEXT_ENTRY(pxCurrentTCB,&( pxReadyTasksLists[ uxTopReadyPriority ] ) ); // pxCurrentTCB指向最高优先级任务
//抢占同一优先级的下一个任务。
4.消息队列:
FreeRTOS中消息队列是任务间数据交换的常用手段(中断服务程序同样使用队列来通信与同步),消息队列是生产者消费者模型的重要组成部分
消息队列的数据结构如下:
typedef struct QueueDefinition
{
signed char *pcHead; //队头
signed char *pcTail; //队尾
signed char *pcWriteTo;
signed char *pcReadFrom;
xList xTasksWaitingToSend; //等待发送的任务列表
xList xTasksWaitingToReceive; //等待接收的任务列表
} xQUEUE;
如何使用消息队列:
xQueueHandle MsgQueue; 声明一个队列句柄,队列句柄可以理解成一个队列的标记,不同的队列具有不同的标记。
MsgQueue = xQueueCreate( 5 , sizeof( int16_t) );创建队列,即在内容中开辟固定大小的区域。
xQueueSend( MsgQueue, ( void* )&SendNum,0 );向队列中填充内容,第二参数需要取出地址并进行类型转换,第三个参数设置等待时间,在队列满的情况下再往队列中填充内容的话便会阻塞任务,直到等待时间溢出;若此处填充的内容为0的话,则立即返回插入队列结果(成功或失败)。
xQueueReceive( MsgQueue, &ReceiveNum,100/portTICK_RATE_MS )从队列中取出内容,第二个参数需要取出地址,第三个参数为等待最大时间,若在等待的时间内队列中没有数据则返回阻塞任务。
附一个学习用的完整项目代码
本项目在cortex-m3 STM32奋斗开发板V5上成功运行。KEIL4
任务一向消息队列填充数字,任务二从消息队列提取数据并发送到串口1,同时有LED灯跟随数据传送亮灭。
下载地址:
STM32搭载RTOS实现任务+消息队列+串口通信完整项目代码