讨论一下CubeMX生成的cmsisi_os接口里面MessageQueue的实现,感觉上代码有bug。 MessageQueue共有三个API,osMessageCreate、osMessagePut和osMessageGet, 有疑问的在put和get上,先看put, osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) @param info message information. 这个意思是MessageQueue只能传一个整数吗?如果只能传一个整数,那么创建时APIosMessageQDef_t的item_sz就必须<=4字节,这个不合理。 还是传地址?如果是地址,最好用long info啊,好吧,目前还可以正常工作。 再看实际调用FreeRTOS的地方, 中断里面调用: if (xQueueSendFromISR(queue_id, &info, &taskWoken) != pdTRUE) { return osErrorOS; } 普通线程里面: if (xQueueSend(queue_id, &info, ticks) != pdTRUE) { return osErrorOS; } 居然是传了info的指针,info是形参,取info的地址,也就是说堆栈里的一个地址,在xQueueSend里面有内存拷贝: prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); pvItemToQueue就是&info,prvCopyDataToQueue拷贝的大小为item_sz。 同理,在osMessageGet里调用的是 xQueueReceiveFromISR(queue_id, &event.value.v, &taskWoken) 和 xQueueReceive(queue_id, &event.value.v, ticks),同样是传的堆栈里的指针,只要item_sz超过4字节,拷贝就会超出本身event所占的内存地址,程序几乎必挂。 难道说用MessageQueue只能传递一个32位的整数吗?但如果只传32位整数,那何必指定item_sz呢,api接口里面也没对这个参数检查,很容易造成内存操作异常啊,有没有哪位研究过,请指教下。 |
void StartDefaultTask(void const * argument)
{
/* USER CODE BEGIN 5 */
char* pMsg;
uint8_t prntThs[8];
uint8_t charNum;
osEvent evt;
/* Infinite loop */
for(;;)
{
evt = osMessageGet(myQueue01Handle, osWaitForever);
if(evt.status == osEventMessage){
pMsg = evt.value.p;
charNum = 4;
//pMsg = prntBuf; //如果取消此注释,打印输出正常。所以我觉得是osMessage没有正常工作
HAL_UART_Transmit_IT(&huart2,(uint8_t*) pMsg, charNum);
/* Before starting a new communication transfer, you need to check the current
state of the peripheral; if it is busy you need to wait for the end of current
transfer before starting a new one.
*/
while (HAL_UART_GetState(&huart2) != HAL_UART_STATE_READY){ }
}
else{
HAL_UART_Transmit_IT(&huart2, (uint8_t*)"Receive Msg Err..\r\n", 19);
/* Before starting a new communication transfer, you need to check the current
state of the peripheral; if it is busy you need to wait for the end of current
transfer before starting a new one.
*/
while (HAL_UART_GetState(&huart2) != HAL_UART_STATE_READY){ }
}
}
/* USER CODE END 5 */
}
/* StartTask02 function */
void StartTask02(void const * argument)
{
/* USER CODE BEGIN StartTask02 */
/* Infinite loop */
for(;;)
{
strcpy(prntBuf,"");
strcpy(prntBuf,"Message from task02.\r\n");
osMessagePut(myQueue01Handle,(uint32_t)prntBuf,osWaitForever);
osDelay(500);
}
/* USER CODE END StartTask02 */
}
========以下是讨论主题============
上述的OS指的是cmsis-rtos RTX, MDK V5环境。
有高手指点一二吗?
我原先定义的Queue为,结果虽有打印输出,但是乱码:
/* definition and creation of myQueue01 */
osMessageQDef(myQueue01, 32, uint16_t);
myQueue01Handle = osMessageCreate(osMessageQ(myQueue01), NULL);
修改为下面后,一切看似那么美好:
/* definition and creation of myQueue01 */
osMessageQDef(myQueue01, 32, uint32_t);
myQueue01Handle = osMessageCreate(osMessageQ(myQueue01), NULL);
心得体会就是,不要轻意怀疑权威
评分
查看全部评分
这句是重点。