FreeRTOS 操作系统学习
http://wiki.csie.ncku.edu.tw/embedded/FreeRTOS_Melot.pdf
3 队列管理
队列是FreeRTOS中所有任务通信或同步之外的基本机制。理解队列至关重要,因为在构建一个复杂的任务通信应用时,不可避免地将用到它。它是存储固定数据大小(“长度”)的一种方式。队列能够被多个不同的任务读写,但并不从属于某个特定的任务。队列通常是一个FIFO,这意味着元素按照被写入的顺序被读取。此行为取决于写入方法:可以使用两个写入函数在此队列的开始或结尾处进行写入。
3.1 队列的读取
当有任务尝试对队列进行读操作时,如果此时有其他任务或中断正在对此队列进行写操作, 必须要等写操作的任务完成,此时任务被阻塞(Blocked),当队列写操作完成后,任务状态自动转为“就绪(Ready)” 。如果同时有多个任务尝试对队列进行写操作,则按任务优先级依次进行。还有一种情况,当多个任务尝试对队列进行读操作,且所有任务的优先级都相同,那么队列按照读操作的请求的时间依次进行。任务还可以指定等待读取队列时的最大等待时间,大于这个时间,任务将放弃读取,自动切换回“就绪”状态。
portBASE_TYPE xQueueReceive( xQueueHandle xQueue, const void * pvBuffer, portTickType xTicksToWait ); |
xQueue 是要读取的队列的标识符
pvBuffer 是指向缓冲区的指针,读取值将被复制到该缓冲区。该内存必须已分配并且必须足够大以处理从队列中 读取的元素
xTicksToWait 定义最大的等待时间。0 当值无效时,任务不等待,但是如果设置INCLUDE_vTaskSuspend且xTicksToWait等于MAX_DELAY,则任务将无限期等待。
如果在 xTicksToWait 之前成功读取了一个值,则返回pdPASS。 否则,xQueueReceive()返回errQUEUE_EMPTY。
队列中的某个元素被读取后通常会被删除;但是,另一个读取函数可以实现读取后元素不被删除,函数如下
portBASE_TYPE xQueuePeek( xQueueHandle xQueue, const void * pvBuffer, portTickType xTicksToWait ); |
3.2 队列写操作
队列写操作与读类似。当一个任务尝试写队列时,必须等队列有空余缓存:等其他任务完成队列读取并释放队列空间后,才可进行写操作,否则任务将被阻塞。多个任务同时读,高优先级任务优先。当多个同优先级任务尝试下写队列,先到先写。 图6 很好地说明了队列的工作方式。
文本7 提供一个常用的写队列的函数原型。文本8 提供 xQueueSend 执行后如果用户希望读取最后写入的元素将要使用的函数先进先出(后进先出或LIFO)。
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 。
portBASE_TYPE xQueueSendToBack( xQueueHandle xQueue, const void * pvItemToQueue, portTickType xTicksToWait ); portBASE_TYPE xQueueSendToFront( xQueueHandle xQueue, const void * pvItemToQueue, portTickType xTicksToWait ); |
3.3 创建一个队列
队列长度及其中每个元素的大小是在队列创建时就规定好的。文本9 给出创建队列的常用函数
xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ); |
uxQueueLenght 队列元素的数量。
uxItemSize 规定了队列每个元素是多少个字节的大小。
如果队列因内存不足创建失败xQueueCreate返回NULL;如果不是,则应保留返回值以处理新创建的队列
表6 有一个队列和两个任务的可能情况