stm32cubeide的freertos-消息队列发送结构体或者长消息,接收不完整的问题

今天在项目创建消息队列,消息队列中的数据类型的是结构体,调用接口使用的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的机制吧。

不过在追求效率的项目中,一般不会用消息队列来传递很长的消息,当需要传递很长的消息时,使用消息队列传递指针是效率最快的。

你可能感兴趣的:(stm32cubeide的freertos-消息队列发送结构体或者长消息,接收不完整的问题)