在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发送的任务中,从队列中按照fifo方式读取队列里面的数据,依次发送出去即可。
创建一个队列(发送数据队列) 创建一个任务(uart发送数据任务) 任务a加入队列 任务b加入队列 · · · 另外一边的任务,依次读取队列数据,使用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); } }}
以上两种方法比较常用,也比较简单,希望对大家有帮助。
提示:代码仅供学习理解原理,在项目中需要结合实际情况增、删、修改代码。
原文标题:rtos多任务访问同一个uart的方法
文章出处:【微信公众号:strongerhuang】欢迎添加关注!文章转载请注明出处。
晶振没坏但不起振 PCB板上的晶体不起振为啥?
降压变换器,降压变换器输入输出电压关系公式
什么是光纤无源器件技术
不好意思,list.contain 去重该换换了!
STM32串口通信详解
如何让RTOS多任务访问同一个UART?
双曲面“王者”!小米Note2真机实拍 组图
荣耀V8配VR 手机厂卡位虚拟现实是跟风还是布局?
DFX设计中的几个问题及其解决方案
电流保护的工作原理
索尼Xperia1 III详细规格配置曝光
一文看懂贴片绕线屏蔽电感感值不稳定的解决方法
小米RedmiNote7评测 很多方面远远超过了千元机的配置相当的优秀
ADC0809引脚图与接口电路的详细资料说明
理想汽车首次在国内造车新势力中率先盈利
相位噪声的两种定义与测试方法简述
黄梅天,衣服晾不干怎么办?
如何在Ubuntu16.04上安装并使用 ensorFlow
土壤水分温度测定仪保障了农业的正常生产
双C口充电头协议芯片——英集芯IP2738,支持PD3.1快充