硬汉嵌入式论坛

 找回密码
 立即注册
查看: 5801|回复: 8
收起左侧

[FreeRTOS] RTOS中共享内存的问题。

[复制链接]

7

主题

14

回帖

35

积分

新手上路

积分
35
发表于 2018-5-10 11:00:14 | 显示全部楼层 |阅读模式
   最近在将一个协议栈移植到FreeRTOS系统上。之前的协议栈是基于前后台系统开发的,在串口接收中断将接收到的数据写入一个环形缓存区,再根据协议从这个缓存区中读出一帧数据,将数据转义和解析,将最后解析出的消息写入一个接收消息环形缓存区;发送数据时,将数据打包成一条消息并写入消息发送缓存区,从消息发送缓存区读出一条消息后,封包,转义,写入串口发送队列,通过轮询或者中断形式将数据发送出去。这里面的环形缓存区全部都是用全局数组做的,在前后台系统中使用没有什么问题。那么移植到RTOS环境下时,有诸多疑问如下:
1.串口接收缓存区和发送缓存区使用全局数组问题应该不大,因为不管什么时候只会有一个任务对这块内存进行读写。一个任务或者ISR读,一个任务或者ISR写。这样理解是否正确?

2.如果将上述前后台编程思想写出的协议栈移植到RTOS下,为了移植方便,是不是紧紧需要消息发送buf的操作做临界区护就行?因为在RTOS下会有多个任务需要往消息发送缓存中填写数据。这块消息发送缓存实质上就变成了若干任务的共享内存。当访问该内存时虽然可以进行临界区保护(原子操作),但是貌似还是会出问题!比如A任务在访问这块共享内存的时候,B任务也需要访问,但是此时操作被保护了,那就只能等到A任务访问结束后才能访问。这是不是就意味着A在写入数据的整个过程中都不能被打断(整个写入数据的函数都需要被临界保护),一但写入的数据过多,过于频繁是不是就会严重影响系统的实时性?这样是不是意味着使用RTOS的情况下,共享内存的形式不是很适用?

3.按RTOS的思维的话是不是应该发送消息缓存设计成消息队列?需要写入数据的任务通过消息队列将数据发送给发送任务?

总的来说,全局数组和全局变量之类的数据结构会对RTOS带来什么样的影响?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2018-5-10 12:00:07 | 显示全部楼层
1、没问题。
2和3、你可以改成用FreeRTOS的消息队列做,非常合适。

全局变量是多任务安全最大的毒瘤,如果是一些关键参数被意外修改,会直接导致系统崩溃。
回复

使用道具 举报

7

主题

14

回帖

35

积分

新手上路

积分
35
 楼主| 发表于 2018-5-10 13:44:52 | 显示全部楼层
eric2013 发表于 2018-5-10 12:00
1、没问题。
2和3、你可以改成用FreeRTOS的消息队列做,非常合适。

    谢谢硬汉老哥的回复。确实,在考虑使用RTOS的时候,应该是不用全局变量和全局数组,因为用全局变量能解决的事情,RTOS内核提供的任务通讯手段都能做,而且人家提供这些工具本来就是要解决这个问题的。如果还使用全局的变量和数组反而会影响系统稳定性和安全性。
    所以我觉得,这个协议栈在RTOS下还是需要按着RTOS的思路重新规划,在任务减通讯的时候使用消息队列。
    这应该是属于编程思维上的变化吧,之前前后台系统,最多就前台和后台,处理并发的时候简单明了,但是RTOS中除了ISR,任务之间也是软并发的。
    不知道这么理解对吗?再次感谢。
回复

使用道具 举报

7

主题

14

回帖

35

积分

新手上路

积分
35
 楼主| 发表于 2018-5-10 13:53:04 | 显示全部楼层
eric2013 发表于 2018-5-10 12:00
1、没问题。
2和3、你可以改成用FreeRTOS的消息队列做,非常合适。

    另外再加问一个问题:像这样的通讯协议栈,在使用RTOS时是规划成一个任务好呢?还是多个任务呢?一个任务的话,在发送的时候检查下消息队列中有数据与否,有就处理没有就进行后续操作。但是如果将协议栈的全部内容规划为一个任务,这个任务是不是会显得很庞大和臃肿呢?如果划分为多个任务,有需要增加很多任务之间的通讯。这方面您的建议是什么呢?
    多个任务都会往FIFO中写,一个任务从FIFO中读,这种情景下一般处理流程是什么样的?谢谢
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2018-5-10 17:12:54 | 显示全部楼层
sanvlee 发表于 2018-5-10 13:44
谢谢硬汉老哥的回复。确实,在考虑使用RTOS的时候,应该是不用全局变量和全局数组,因为用全局变量能 ...

对,不过有时候使用这些消息机制不方便的时候,可以用全局变量,全局变量有时候的确省事。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2018-5-10 17:18:09 | 显示全部楼层
sanvlee 发表于 2018-5-10 13:53
另外再加问一个问题:像这样的通讯协议栈,在使用RTOS时是规划成一个任务好呢?还是多个任务呢?一个 ...

按功能划分方便些。你可以安排一个任务,通过事件标志,不同的功能,不同的标志,根据标志在这个任务里面处理相应功能即可,这样的话,你的全局变量缓冲可以继续使用,也就不需要用消息队列了。我自己比较喜欢这种方式处理。
回复

使用道具 举报

7

主题

14

回帖

35

积分

新手上路

积分
35
 楼主| 发表于 2018-5-10 17:42:28 | 显示全部楼层
eric2013 发表于 2018-5-10 17:18
按功能划分方便些。你可以安排一个任务,通过事件标志,不同的功能,不同的标志,根据标志在这个任务里面 ...

事件标志不能解决这个问题吧。比如A任务是AD采集任务,B任务是温度采集任务,C任务是IC读卡任务,现在需要将这三组数据传送到另外一个MCU上去。那A、B、C任务都需要将采集到的数据写入消息发送缓存进行发送。如果还用前后台程序中那样的全局数组作为消息发送缓存的话,事件标志也只能通知到通讯任务(协议栈任务)D,A、B或者是C任务有数据要传输,但是具体传输的什么内容还是不知道的吧,另外,A、B、C三个任务都需要网消息发送缓存中写入消息实体,这样还是会造成多线程问题吧?是这样理解吗?谢谢。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2018-5-11 00:48:12 | 显示全部楼层
sanvlee 发表于 2018-5-10 17:42
事件标志不能解决这个问题吧。比如A任务是AD采集任务,B任务是温度采集任务,C任务是IC读卡任务,现在需 ...

实际操作全部在这个任务里面进行,其它任务只是发要操作命令(事件标志)过来。
回复

使用道具 举报

7

主题

14

回帖

35

积分

新手上路

积分
35
 楼主| 发表于 2018-5-11 10:25:18 | 显示全部楼层
eric2013 发表于 2018-5-11 00:48
实际操作全部在这个任务里面进行,其它任务只是发要操作命令(事件标志)过来。

有点明白了!谢谢汉哥!汉哥每次都有问必答,钦佩,钦佩!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-13 04:28 , Processed in 0.289279 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表