首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

深入理解FreeRTOS的任务机制和消息队列+附完整项目代码

深入理解FreeRTOS的任务机制和消息队列+附完整项目代码

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 )从队列中取出内容,第二个参数需要取出地址,第三个参数为等待最大时间,若在等待的时间内队列中没有数据则返回阻塞任务。
返回列表