今天在项目创建消息队列,消息队列中的数据类型的是结构体,调用接口使用的cubeide自带的创建消息队列的接口
typedef struct _Irda_Info
{
uint16_t datalength;
uint8_t direction;
uint8_t data[MB_SER_PDU_SIZE_MAX];
} Irda_Info;
osMessageQId irdaRecvQueue_Handle
osMessageQDef(irdaRecv_Queue, 4, sizeof(Irda_Info));
irdaRecvQueue_Handle = osMessageCreate(osMessageQ(irdaRecv_Queue), NULL);
结果发现在任务A中发送
xQueueSend(irdaRecvQueue_Handle , (char*)&Irda_SendInfo, 1000);
任务B中接收
xQueueReceive(irdaRecvQueue_Handle , (char*)&Irda_RecvInfo, 1000)
B中接收的数据与A不一致,只能收到4个字节是正确的,后来进入osMessageQDef函数中发现
#define osMessageQDef(name, queue_sz, type) \
const osMessageQDef_t os_messageQ_def_##name = \
{ (queue_sz), sizeof (type) }
进入osMessageCreate函数
osMessageQId osMessageCreate (const osMessageQDef_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
}
函数调用了FreeRTOS的消息队列创建API(xQueueCreate),填入的消息的长度为queue_def->item_sz,而上面的osMessageQDef定义了queue_def->item_sz只能等于sizeof (type),所以调用cubeide自己的消息队列创建的消息长度只能是固定的,无法根据自己需求来定义。
解决方法就是使用freertos自身的消息队列API
irdaRecvQueue_Handle = xQueueCreate(3, sizeof(Irda_Info));
if(NULL == irdaRecvQueue_Handle)
{
app_err("Create irdaRecvQueue_Handle fail!\n");
}
这应该也不算是一个坑,只能算是没有看懂ST的freertos的机制吧。
不过在追求效率的项目中,一般不会用消息队列来传递很长的消息,当需要传递很长的消息时,使用消息队列传递指针是效率最快的。