RTOS队列代码分析

队列:
1.关中断
2.环形缓冲区
3.链表
链表里面有两个链表,分别为list for receive和list for send ,由名字可知:
1、前者用来在任务接收不到队列数据的时候先把自己挂在那里。
2、后者则是任务向队列发送数据的时候,队列数据满了,把自己挂在那里。

 /* 创建队列: 长度为5,数据大小为4字节(存放一个整数) */
    xQueue = xQueueCreate( 5, sizeof( int32_t ) );

在这里插入图片描述

 pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); /*lint !e9087 !e9079 see comment above. */
 这是是队列,他是由头部+buffer的大小组成

buffer是

xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize );

receive


/* 读队列
 * xQueue: 读哪个队列
 * &lReceivedValue: 读到的数据复制到这个地址
 * xTicksToWait: 如果队列为空, 阻塞一会
 */
xStatus = xQueueReceive( xQueue, &lReceivedValue, xTicksToWait );

进去看到这个

taskENTER_CRITICAL();

再进去

portDISABLE_INTERRUPTS();

所以在读队列的时候,我会进入临界区,也就是关中断。
在我读队列后,如果有data,就copy数据;如果没有data,我我就不想等了,返回err,或者算了,我等等吧,先睡一下,把自己挂在

 List_t xTasksWaitingToReceive;  

这个列表里面。。。。
上面有点问题,还没休眠,把自己从ready list[] 转移到delayed list才算真正的休眠。大概是从就绪态转为挂起态。
ps:FreeRTOS中任务的状态可分为:未创建态、就绪态、运行态、挂起态、延时态五种状态

好,当我终于接收到数据(被唤醒或者没睡直接接收到了),我会copy数据和唤醒一个东西。
那个东西就是因为队列满了而写不了东西进队列的任务桑。

  List_t xTasksWaitingToSend;

write

跟receive 差不多。关中断啊,返回err啊,休眠啊。就绪转挂起啊

在这里插入图片描述

具体代码在queue.c的1400行左右。

|
|
|
|
|

/* 读队列
 * xQueue: 读哪个队列
 * &lReceivedValue: 读到的数据复制到这个地址
 * xTicksToWait: 如果队列为空, 阻塞一会
 */
xStatus = xQueueReceive( xQueue, &lReceivedValue, xTicksToWait );

超时唤醒啊,超的这个xTicksToWait ,时间。
不能一直睡吧~~

猜你喜欢

转载自blog.csdn.net/lianghuajunone/article/details/124004613