FreeRTOS 操作系统学习(四) 队列管理

                                                      FreeRTOS 操作系统学习

http://wiki.csie.ncku.edu.tw/embedded/FreeRTOS_Melot.pdf

3  队列管理

      队列是FreeRTOS中所有任务通信或同步之外的基本机制。理解队列至关重要,因为在构建一个复杂的任务通信应用时,不可避免地将用到它。它是存储固定数据大小(“长度”)的一种方式。队列能够被多个不同的任务读写,但并不从属于某个特定的任务。队列通常是一个FIFO,这意味着元素按照被写入的顺序被读取。此行为取决于写入方法:可以使用两个写入函数在此队列的开始或结尾处进行写入。

3.1 队列的读取 

       当有任务尝试对队列进行读操作时,如果此时有其他任务或中断正在对此队列进行写操作, 必须要等写操作的任务完成,此时任务被阻塞(Blocked),当队列写操作完成后,任务状态自动转为“就绪(Ready)”    。如果同时有多个任务尝试对队列进行写操作,则按任务优先级依次进行。还有一种情况,当多个任务尝试对队列进行读操作,且所有任务的优先级都相同,那么队列按照读操作的请求的时间依次进行。任务还可以指定等待读取队列时的最大等待时间,大于这个时间,任务将放弃读取,自动切换回“就绪”状态。

     

文本5: 读取队列的常规方法:先读取元素,然后将其删除

portBASE_TYPE xQueueReceive(                                

                                                                     xQueueHandle xQueue,                                 

                                                                     const void *      pvBuffer,                                

                                                                     portTickType    xTicksToWait

                                                        ); 

      xQueue         是要读取的队列的标识符

      pvBuffer         是指向缓冲区的指针,读取值将被复制到该缓冲区。该内存必须已分配并且必须足够大以处理从队列中                                          读取的元素

      xTicksToWait   定义最大的等待时间。0 当值无效时,任务不等待,但是如果设置INCLUDE_vTaskSuspend且xTicksToWait等于MAX_DELAY,则任务将无限期等待。

       如果在 xTicksToWait  之前成功读取了一个值,则返回pdPASS。 否则,xQueueReceive()返回errQUEUE_EMPTY。

       队列中的某个元素被读取后通常会被删除;但是,另一个读取函数可以实现读取后元素不被删除,函数如下

文本 6: 队列读取后元素不会被删除

portBASE_TYPE xQueuePeek(       xQueueHandle xQueue,                                 

                                                          const void  *     pvBuffer,                                 

                                                          portTickType     xTicksToWait   

                                                     ); 

3.2  队列写操作

      队列写操作与读类似。当一个任务尝试写队列时,必须等队列有空余缓存:等其他任务完成队列读取并释放队列空间后,才可进行写操作,否则任务将被阻塞。多个任务同时读,高优先级任务优先。当多个同优先级任务尝试下写队列,先到先写。 图6 很好地说明了队列的工作方式。

      文本7 提供一个常用的写队列的函数原型。文本8 提供 xQueueSend 执行后如果用户希望读取最后写入的元素将要使用的函数先进先出(后进先出或LIFO)。

Text 7: FIFO模式写队列函数

portBASE_TYPE xQueueSend(  xQueueHandle xQueue, 

                                                    const void  *  pvItemToQueue, 

                                                    portTickType xTicksToWait

                                                   ); 

             xQueue                   需要些的队列. 该值通过队列的创建函数返回

             pvItemToQueue      是指向要(按值)复制到队列中的元素的指针

             xTicksToWait           允许等待的最大时间。 0 表示当队列满后不等待直接放弃写操作。如果在FreeRTOSConfig.h                                                          将  INCLUDE_vTaskSuspend 值定义为1  (本节8.1),并且xTicksToWait等MAX_DELAY,                                                         任务将会一直阻塞并保持等待。

          写成功后 XqueueSend 函数将返回 pdPASS,若写操作超时,则返回 errQUEUE_FULL 。

文本 8: xQueueSendToBack: 与 xQueSend相似; xQueueSendToFront 用 LIFO 模式写队列.

portBASE_TYPE xQueueSendToBack(  xQueueHandle xQueue,                                   

                                                                const void * pvItemToQueue,                                    

                                                                portTickType xTicksToWait                                  

                                                              ); 

portBASE_TYPE xQueueSendToFront(   xQueueHandle xQueue,                                    

                                                                  const void * pvItemToQueue,                                   

                                                                  portTickType xTicksToWait                                 

                                                               ); 

3.3  创建一个队列

     队列长度及其中每个元素的大小是在队列创建时就规定好的。文本9 给出创建队列的常用函数

文本 9: 队列创建函数

xQueueHandle xQueueCreate(   unsigned portBASE_TYPE uxQueueLength,                                                                                                                                    unsigned portBASE_TYPE uxItemSize

                                                  ); 

            uxQueueLenght    队列元素的数量。

            uxItemSize  规定了队列每个元素是多少个字节的大小。

     如果队列因内存不足创建失败xQueueCreate返回NULL;如果不是,则应保留返回值以处理新创建的队列   

                                                      

                                                                         表6  有一个队列和两个任务的可能情况

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章