单片机技术网|技术阅读
登录|注册

您现在的位置是:单片机技术网 > 技术阅读 > RTOS多任务访问同一个硬件资源的方法

RTOS多任务访问同一个硬件资源的方法


问题:基于RTOS多任务编程,同一个硬件(比如UART、I2C等)被多个任务访问的情况比较多,如果不合理处理,就会导致“混乱”的局面,解决问题方法比较多,下面基于FreeRTOS,以UART为例讲讲常见的互斥、队列这两种方法。


1

互斥访问方法互斥量:一个可以处于两态之一的变量:解锁和加锁。
原理:创建一个互斥量,任务A在需要占用资源(使用UART发送数据),加锁把资源(UART)占用。此时任务B及其他任务就无法占用该资源。当任务A使用完资源(UART发送完数据),解锁释放资源,其他任务才可以抢占该资源。创建互斥量
任务A占用资源使用资源(发送数据)任务A释放资源
优先级高的任务B占用资源使用资源任务B释放资源
依次,优先级任务占用资源··


伪代码:

//创建互斥量资源SemaphoreHandle_t xSemaphore = NULL;xSemaphore = xSemaphoreCreateMutex();
void TaskA(void *pvParameters){ for(;;) { //占用资源 if(xSemaphoreTake(xSemaphore, 10 ) == pdTRUE) { //使用资源(发送数据) USART_SendNByte(); //释放资源 xSemaphoreGive(xSemaphore); } }}
信号量与互斥量区别信号量:多个任务同步使用某个资源;一个任务完成某个动作后,通过信号告诉别的任务,别的任务才可以执行某些动作。
互斥量:多任务互斥使用某个资源一个任务占用某个资源,那么别的任务就无法访问,直到该任务离开,其他任务才可以访问该资源;不能再中断服务中使用。


2

队列操作方法队列操作方法就是FIFO,先入先出的原理。如任务A要使用UART发送一串数据,将其加入队列; 接着任务B也要使用UART发送一串数据。
那么,任务A将这串数据加入队列,接着任务B将要发送的一串数据也加入队列。在另外一个UART发送的任务C中,从队列中按照FIFO方式读取队列里面的数据,依次发送出去即可。创建一个队列(发送数据队列)创建一个任务(UART发送数据任务)
任务A加入队列任务B加入队列   ·   ·   ·
另外一个任务C,依次读取队列数据,使用UART发送出去。


伪代码:

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(;;) { //循环读取队列BUF if(xQueueReceive(xQueue, &Buf, 10) == pdTRUE) { USART_SendNByte(&Buf); } }}


以上两种方法比较常用,而且简单。获取更多编码技巧,请关注微信公众号