参考网址:
RTOS多任务访问同一个UART的操作方法
在RTOS多任务编程的时候,同一个硬件(比如UART、I2C等)被多个任务访问的情况比较多,如果不合理处理,就会导致“混乱”的局面。
处理“混乱”局面的方法比较多,下面基于FreeRTOS,以UART为例讲讲常见的互斥、队列这两种方法。
互斥访问方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| SemaphoreHandle_t xSemaphore = NULL; xSemaphore = xSemaphoreCreateMutex();
void TaskA(void *pvParameters) { for(;;) { if(xSemaphoreTake(xSemaphore, 10 ) == pdTRUE) { USART_SendNByte(); xSemaphoreGive(xSemaphore); } } }
|
信号量与互斥量区别:
信号量:多个任务同步使用某个资源;
一个任务完成某个动作后通过信号告诉别的任务,别的任务才可以执行某些动作;
互斥量:多任务互斥使用某个资源;
一个任务占用某个资源,那么别的任务就无法访问,直到该任务离开,其他任务才可以访问该资源;
队列操作方法
队列操作方法就是FIFO,先入先出的原理。比如:任务A要使用UART发送一串数据,将其加入队列; 接着任务B也要使用UART发送一串数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| QueueHandle_t xQueue; xQueue = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE);
xTaskCreate(UART_Send_Task, "UART_Send", STACK_SIZE, NULL, TASK_PRIORITY, NULL);
void TaskA(void *pvParameters) { for(;;) {
xQueueSend(xQueue, &TaskA_Buf, 10) } }
void TaskB(void *pvParameters) { for(;;) {
xQueueSend(xQueue, &TaskB_Buf, 10) } }
void UART_Send_Task(void *pvParameters) { for(;;) { if(xQueueReceive(xQueue, &Buf, 10) == pdTRUE) { USART_SendNByte(&Buf); } } }
|