1. 背景
为了屏蔽不同OS之间的差别,ARM公司开发了一套OS接口--CMSIS_OS。
在使用STM32 cube生成的free rtos工程中,遇到一些问题。
问题1:osMessageGet 和 osMessagePut 发送和接收队列(结构体,数组等)。
问题2:osMailGet 和 osMailPut发送和接收队列(结构体,数组等)。
2. 问题分析( osMessagePut 和osMessageGet 为例)
osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { portBASE_TYPE taskWoken = pdFALSE; TickType_t ticks; ticks = millisec / portTICK_PERIOD_MS; if (ticks == 0) { ticks = 1; } if (inHandlerMode()) { if (xQueueSendFromISR(queue_id, &info, &taskWoken) != pdTRUE) { return osErrorOS; } portEND_SWITCHING_ISR(taskWoken); } else { if (xQueueSend(queue_id, &info, ticks) != pdTRUE) { return osErrorOS; } } return osOK; }
发送函数本质是调用xQueueSendFromISR 和xQueueSend。这个函数调用
BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition )
继续调用
( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
最终调用
( void ) memcpy( ( void * ) pxQueue->u.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize );
所以本质就是memcpy,把用户需要发送的数据拷贝到队列的内部内存保存。
osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec)接口上,传入的只能是一个数据或指针,所以传入数组或结构体时候,就必须以指针方式传入。
对于osMessageGet ,通用关键的也是memcpy,不过包装后,有一点非常特殊。
和free rtos接口的调用时经过xQueueReceiveFromISR(queue_id, &event.value.v, &taskWoken