FreeRTOS中使用CubMX队列创建队列函数osMessageQDef的坑

废话不多说,创建一个队列,在cubeMX下自动生成代码如下

osMessageQDef(ESP8266SendQueue, 256, 8);

ESPSendQueueHandle =osMessageCreate(osMessageQ(ESP8266SendQueue), NULL);

该队列意义在于生成256item,每个item大小8个字节

 

使用队列最主要是作为数据传输的载体,现在可以很简单的测试一下使用队列传输的功能;

首先定义一个8个元素的数组

uint8_t AA[8] = {1,2,3,4,5,6,7,8};

然后随便在一个任务中将该数组拷入队列

xQueueSend(ESPSendQueueHandle, AA,100);

然后在另外一个任务中使用一个数组作为载体将队列中的数据拷出来

uint8_t BB[8];

拷贝出来

xQueueReceive(ESPSendQueueHandle,& BB,500);

然后通过串口助手发送(未配置可以直接使用debug看此时的BB里面数据)

CDC_Transmit_FS(BB ,sizeof(BB)); 

FreeRTOS中使用CubMX队列创建队列函数osMessageQDef的坑_第1张图片

此时只显示0 1 2 3,那么我们可以再把AA的数组改一改,改成2作为AA[0]

结果显示:

FreeRTOS中使用CubMX队列创建队列函数osMessageQDef的坑_第2张图片

此时只显示 2 0 1 3

那么问题来了,为什么队列复制数组只能存放4个元素呢?

追入osMessageQDef来看

 

FreeRTOS中使用CubMX队列创建队列函数osMessageQDef的坑_第3张图片

osMessageQId osMessageCreate (constosMessageQDef_t *queue_def, osThreadId thread_id)

{

 (void) thread_id;

 

#if( configSUPPORT_STATIC_ALLOCATION == 1 )&& ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )

 

  if((queue_def->buffer != NULL) && (queue_def->controlblock !=NULL)) {

   return xQueueCreateStatic(queue_def->queue_sz, queue_def->item_sz,queue_def->buffer, queue_def->controlblock);

  }

 else {

   return xQueueCreate(queue_def->queue_sz, queue_def->item_sz);

  }

#elif ( configSUPPORT_STATIC_ALLOCATION ==1 )

 return xQueueCreateStatic(queue_def->queue_sz, queue_def->item_sz,queue_def->buffer, queue_def->controlblock);

#else 

 return xQueueCreate(queue_def->queue_sz, queue_def->item_sz);

#endif

}

重点看这句

xQueueCreate(queue_def->queue_sz,queue_def->item_sz);

创建队列,使用的是freertos的原生函数,但是参数呢, queue_def->queue_sz, queue_def->item_sz,没错,是写死的,追进去看一看

 

 

此结构体如下

/// Definition structure for message queue.

/// \note CAN BE CHANGED: \bos_messageQ_def is implementation specific in every CMSIS-RTOS.

typedef struct os_messageQ_def  {

 uint32_t               queue_sz;    ///< number ofelements in the queue

 uint32_t                item_sz;    ///< size of an item

#if( configSUPPORT_STATIC_ALLOCATION == 1 )

 uint8_t                *buffer;      ///< buffer forstatic allocation; NULL for dynamic allocation

 osStaticMessageQDef_t  *controlblock;     ///< controlblock to hold queue's data for static allocation; NULL for dynamic allocation

#endif

 //void                      *pool;    ///< memory array formessages

} osMessageQDef_t;

这两个结构是写死的,均为uint32_t类型

那么我们再来看看定义函数

#define osMessageQDef(name, queue_sz,type)   \

const osMessageQDef_tos_messageQ_def_##name = \

{ (queue_sz), sizeof (type) }

不管我们在cube中写入多少,最终创建队列形参其实是sizeof(type),也就是固定的4字节,所以这就是原因。

解决方法,不使用cubeMX的封装函数创建,直接使用Freertos的函数进行队列创建

DataBusQueueHandle = xQueueCreate(256,8);

这个时候再次试验,对应uint8_t AA[8] = {1,2,3,4,5,6,7,8};

此时从队列中读取数据为

1 2 3 4 5 6 7 8

完美解决


你可能感兴趣的:(STM32,M3)