基于FreeRTOS的队列管理的应用
来源:互联网 发布:整形医院网站源码 编辑:程序博客网 时间:2024/06/05 20:19
- 我们前一篇技术文章大概说明了,如何基于FreeRTOS嵌入式实时操作系统,进行基本的应用软件开发。在这里,我们将说说在应用中,如果使用FreeRTOS的队列。这是因为在应用程序中,不同任务间的消息传送,会大量用到队列这种方式。
-
- 先解释一下队列:是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作。队列的操作方式和堆栈类似,唯一的区别在于队列只允许新数据在后端进行添加。
-
- 在FreeRTOS中,对队列有专门的管理机制及函数,在queue.h定义。使用队列进行消息传送,可以避免数据冲突与丢失等现象。如:有一个任务,需要根据另外三个任务的数据来执行它的操作或运行流程,且在这四个任务运行时,是不定时的,没有任何规律可言,那么按照传统的公共变量的方式,就有可能产生数据丢失或数据访问冲突。如果在这里使用FreeRTOS的队列来传递数据信息,则相当容易地把这种问题给解决了。在FreeRTOS中使用队列,最简单的应用,需要创建队列、发送队列消息、等待接收队列消息、删除队列等操作。使用队列,不仅可以传送单字节消息,也可以传送数据结构。在这里,队列管理相关的函数定义不就再进行说明了,需要时,可以参考queue.h。下面直接举例,说明如何使用FreeRTOS队列。
-
- 例如:有一组LED灯,在同一个物理操作端口上面,另外三个不同的任务,需要操作这组LED灯来指示系统状态。这时,引入一个单独的任务来操作这组LED灯,那三个不同的任务则向这一个LED灯操作任务发送消息来控制LED灯。则应用程序框架如下所示:
-
- 1、 定义消息数据结构及变量
-
- typedef struct
-
- {
-
- u8 msg_src;
-
- u8 msg_val;
-
- } Led_msg;
-
-
-
- #define Task1_msg 0x1 // 定义任务1所传递的消息
-
- #define Task2_msg 0x2 // 定义任务2所传递的消息
-
- #define Task3_msg 0x3 // 定义任务3所传递的消息
-
- xQueueHandle hLED_MSG;
-
- 2、 在main程序中,创建一个消息用于消息的传递
-
- hLED_MSG = xQueueCreate( 10 , sizeof(Led_msg) );
-
-
-
- 3、 在LED灯操作的任务中等待消息并处理
-
- void Task_LED( void *pvParameters )
-
- {
-
- Led_msg Receive_msg;
-
- While(1)
-
- {
-
- While(xQueueReceive(hLED_MSG, & Receive_msg, portMAX_DELAY ) != pdPASS );
-
- Switch(Receive_msg.msg_src)
-
- {
-
- case: Task1_msg
-
-
- ;;;;;
-
-
- Break;
-
-
- case: Task2_msg
-
-
- ;;;;;
-
-
- Break;
-
-
- case: Task3_msg
-
-
- ;;;;;
-
-
- Break;
-
-
- default:
-
-
- Break;
-
-
- }
-
-
- }
-
- }
-
-
-
- 4、消息的发送
-
- void Task1 ( void *pvParameters )
-
- {
-
- Led_msg Send_msg;
-
- While(1)
-
- {
-
- ;;;;;
-
-
- Send_msg. msg_src = Task1_msg;
-
-
- Send_msg. msg_val = 0x5;
-
-
- xQueueSend(hLED_MSG , & Send_msg, portMAX_DELAY );
-
-
- }
-
- }
-
-
-
- void Task2 ( void *pvParameters )
-
- {
-
- Led_msg Send_msg;
-
- While(1)
-
- {
-
- ;;;;;
-
-
- Send_msg. msg_src = Task2_msg;
-
-
- Send_msg. msg_val = 0x77;
-
-
- xQueueSend(hLED_MSG , & Send_msg, portMAX_DELAY );
-
-
- }
-
- }
-
-
-
- void Task3 ( void *pvParameters )
-
- {
-
- Led_msg Send_msg;
-
- While(1)
-
- {
-
- ;;;;;
-
-
- Send_msg. msg_src = Task3_msg;
-
-
- Send_msg. msg_val = 0x9;
-
-
- xQueueSend(hLED_MSG , & Send_msg, portMAX_DELAY );
-
-
- }
-
- }
-
-
-
- 到此,队列的基本应用例子程序已完成。如果在应用程序中的某种条件下,不再需要这个队列,则可以调用xQueueDelete(hLED_MSG)将该队列删除。基本了解了FreeRTOS任务的创建及应用,以及队列的应用,则可以完成一些简单应用程序的编写。