媒介:编写不易,请勿搬运,仅供学习参考!!!
目录
FreeRtos中Queue的利用
Queue创建
Queue现实调用
动态创建和静态区别
Queue担当数据
Queue现实调用
Queue发送数据
Queue现实调用
Queue队列集利用
FreeRtos中Queue的利用
在FreeRtos操作系统中,Queue是一种用在Task之间传输数据的方法,这种方法传输数据的同时,可以满足互斥,同步,阻塞,唤醒,是一种最为常用的传输数据手段,主要特性有FIFO,同时Queue会自动管理数据的插入和删除,当读出来一个数据的时间,这个数据会自动从Queue里面删除,同时利用队列来传输数据,是最稳妥的手段。
Queue创建
- QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize );
复制代码函数参数 | 相干作用 | uxQueueLength | 用来确定队列里面存放多少个数据元素 | uxItemSize | 队列里面数据的大小,单位是字节 | 函数返回值 | 句柄:代表创建成功 ,NULL:创建失败 | 这里是动态创建Queue函数跟需要的参数,以及参数的意思,下面是静态创建Queue的函数原型,跟参数意思。
- QueueHandle_t xQueueCreateStatic( UBaseType_t uxQueueLength,UBaseType_t uxItemSize,uint8_t *pucQueueStorageBuffer,Static Queue_t *pxQueueBuffer);
复制代码函数参数 | 相干作用 | uxQueueLength | 用来确定队列里面存放多少个数据元素 | uxItemSize | 队列里面数据的大小,单位是字节 | uint8_t *pucQueueStorageBuffer | 自界说的Queue存储空间 | StaticQueue_t *pxQueueBuffer | 队列控制块,负责管理内部信息 | 函数返回值 | 句柄:代表创建成功 ,NULL:创建失败 | 留意,uint8_t *pucQueueStorageBuffer参数的大小应该是,uxQueueLength*uxItemSize的大小,不能比这个少,否则就放不下。这里静态创建跟动态相比多了两个参数,因为所有的静态创建都需要,主动确定分配空间的大小,动态创建就不消,同时pxQueueBuffer填写这个位置的参数,需要声明为StaticQueue_t范例才华填写。
Queue现实调用
- struct rotary_data {
- int32_t cnt;
- int32_t speed;
- };
- struct input_data {
- uint32_t dev;
- uint32_t val;
- };
- static uint8_t g_ucQueueRotaryBuf[10*sizeof(struct rotary_data)];
- static StaticQueue_t g_xQueueRotaryStaticStruct;
- g_xQueuePlatform = xQueueCreate(10, sizeof(struct input_data));
- g_xQueueRotary = xQueueCreateStatic(10, sizeof(struct rotary_data), g_ucQueueRotaryBuf, &g_xQueueRotaryStaticStruct);
-
复制代码 这里利用布局体来传输数据,以是计算布局体数据的大小,作为参数填写到,Queue创建声明的参数。
动态创建和静态区别
这两种创建方式的主要区别在于,内存分配方式和时机,动态创建也需要内存,前者内存由FreeRtos中的内存管理器分配Heap的内存给他,静态创建内存管理器不会分配,需要自己界说利用空间大小,同时删除静态创建任务,任务利用的内存空间是不会返回的。
总结下来最大的区别在于,动态分配不需要确定利用空间大小,删除释放利用空间,静态分配利用前要确定内存空间大小,删除创建不会释放利用的内存空间。
Queue担当数据
- BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait);
- BaseType_t xQueueReceiveFromISR(QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxTaskWoken);
复制代码 上面是函数原型,两个函数区别在于后缀有FromISR的函数能在中断中用,上文有提交,利用xQueueReceive()函数读队列数据读出来之后,数据会自动被Queue给移除。
函数参数 | 参数解释 | xQueue | 读谁人队列填写它的句柄 | pvBuffer | 从队列里面读取的数据,放到这个参数里面。 | xTicksToWait | 0:没有数据立即返回
portMAX_DELAY:没有数据阻塞到有数据
| 返回值 | pdPASS:从队列读出数据入
errQUEUE_EMPTY:读取失败,因为队列空了。
| 这个函数的返回值因为不是句柄,一般不需要取,需要留意的是,存放读取数据的变量跟 0或者portMAX_DELAY值的敲定。
Queue现实调用
- struct rotary_data {
- int32_t cnt;
- int32_t speed;
- };
- struct input_data {
- uint32_t dev;
- uint32_t val;
- };
- static uint8_t g_ucQueueRotaryBuf[10*sizeof(struct rotary_data)];
- static StaticQueue_t g_xQueueRotaryStaticStruct;
- g_xQueuePlatform = xQueueCreate(10, sizeof(struct input_data));
- g_xQueueRotary = xQueueCreateStatic(10, sizeof(struct rotary_data), g_ucQueueRotaryBuf, &g_xQueueRotaryStaticStruct);
- struct input_data idata;
- xQueueReceive( g_xQueuePlatform,&idata,portMAX_DELAY);
复制代码 这里读g_xQueuePlatform的数据,放入了idata里面,假如读不到数据,陷入阻塞状态,什么时间有了数据,就会唤醒,然后读取数据。
Queue写数据
- BaseType_t xQueueSendToBack(QueueHandle_t xQueue,const void *pvItemToQueue,TickType_t xTicksToWait);
- BaseType_t xQueueSendToBackFromISR(QueueHandle_t xQueue,const void *pvItemToQueue,BaseType_t *pxHigherPriorityTaskWoken );
复制代码 上面是写数据的函数同样的ISR这个函数,能用在中断里面,因为Queue的FIFO的原因,后写进去的数据,会在首先辈去的后面,下面是函数参数说明。
函数参数 | 参数解释 | xQueue | 填写谁的句柄数据就会写到哪一个队列
| pvItemToQueue | 需要写进去队列的数据,这个数据需要取地址 | xTicksToWait | 0:无法写进去数据会立即返回
portMAX_DELAY:没有写进去数据会进入阻塞状态
| 返回值 | errQUEUE_FULL:写入失败,因为队列满了。
pdPASS:数据成功写入了队列
| 这里写Queue需要留意的是,写入Queue的数据需要取地址。
Queue现实调用
- if( xTimerQueue != NULL )
- {
- /* Send a command to the timer service task to start the xTimer timer. */
- xMessage.xMessageID = xCommandID;
- xMessage.u.xTimerParameters.xMessageValue = xOptionalValue;
- xMessage.u.xTimerParameters.pxTimer = ( Timer_t * ) xTimer;
- if( xCommandID < tmrFIRST_FROM_ISR_COMMAND )
- {
- if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING )
- {
- xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait );
- }
- else
- {
- xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY );
- }
- }
- else
- {
- xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );
- }
- traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn );
- }
复制代码 这里的话xTicksToWait并没有取值0或者portMAX_DELAY,这个值你可以指定一个具体的等待时间,表示任务最多等待多少个调度滴答(tick)单位。
假如填写具体的等待时间,不是0或者portMAX_DELAY也是可以的。
我是大狗,欢迎指正,欢迎三连,希望对你,有所资助!!!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |