硬汉嵌入式论坛

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

[FreeRTOS] FreeRTOS 是否可以使用全局变量

[复制链接]

38

主题

75

回帖

189

积分

初级会员

积分
189
发表于 2024-7-8 11:49:34 | 显示全部楼层 |阅读模式
最近在学习FreeRTOS, 由于没有实战经验,一些细节问题不知道该如何处理才是最优的方法。

比如有两个任务,A和B,任务A通过传感器读取当前温度,任务B中设定一个最大温度,不断与任务A中得到的当前温度进行对比,如果当前温度大于最大温度,则在任务B中启动报警。

假设任务A中读取到的当前温度是gettemp, 任务B中设定的最大温度变量是maxtemp,.

在任务B中,代码大概这样:
ifgettemp>=maxtemp)  //判断当前温度是否大于最大温度
{
      start_alarm();  //启动报警
}

以上的代码,我是在任务B中直接使用了gettemp这个变量拿来对比,而没有通过队列从任务A中传输到任务B。因为gettemp变量在任务B中只是用来对比,不会改变他的值,所以我直接使用它。
但不确定这样做是不是最优的方法?
以上只是一个例子,在规模大点的程序中,如果每一个变量的值都要靠队列传过来,那就会定义非常非常多的队列,我不想定义太多的队列,感觉队列太多导致程序非常臃肿!

我的疑问是,Freertos中到底还能不能像裸机一样使用全局变量?还是所有的数据传输必须使用队列?
我个人感觉有些地方用全局变量方便些,但是没没有一个教程提到过全局变量该不该用?希望有实战经验的大神赐教!
回复

使用道具 举报

6

主题

306

回帖

324

积分

高级会员

积分
324
发表于 2024-7-8 13:07:47 | 显示全部楼层
可以使用全局变量,但上边的判断不是原子操作,有被中断的风险,要求不高可以这样操作。
回复

使用道具 举报

356

主题

2180

回帖

3253

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3253
发表于 2024-7-8 15:00:47 | 显示全部楼层
本帖最后由 caicaptain2 于 2024-7-8 15:02 编辑

可以用全局变量,也是常规操作。需要注意,全局变量最好只在一个任务中写,可以多个任务读。 而且要考虑任务的优先级,且每个任务必须有os_delay(),避免高优先级的任务一直占用。

更换个思路,单片机的任意一个外设就是一个全局变量。所以上面说的事项要注意,仅在一个任务中修改外设。
回复

使用道具 举报

4

主题

412

回帖

424

积分

高级会员

积分
424
发表于 2024-7-8 15:43:06 | 显示全部楼层
全局变量只有一个任务修改数据,其他任务只读的话没问题的,前提保证读写的原子性, 即不超过cpu字长.

ps 前面我写的,后面的让ai阅读理解简单整理一下不想查资料了。仅供参考。
如果在程序中,有一个全局变量,只有一个任务(或线程)对这个变量进行修改(写操作),而其他的任务都只是读取这个变量的值,并不进行修改,那么这种情况下通常是没有问题的。但是,关键的前提是必须保证对这个全局变量进行读写操作的原子性,这意呀着每次读取或写入操作都是不可分割的,不会被其他任务中断。

读写操作的数据量不超过CPU的字长。CPU的字长是指CPU一次性能处理数据的最大位数,例如32位或64位。当操作的数据量不超过CPU的字长时,大多数现代CPU能够保证对这些数据的读写操作是原子的,即一步完成,不会被打断。

总结来说,如果只有一个任务修改全局变量,其他任务都是读取操作,同时满足操作的原子性和不超过CPU字长的条件,那么这种情况下操作全局变量通常是安全的。
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2024-7-15 13:25:31 | 显示全部楼层
当然可以用全局变量,前提条件有两个:(1)该全局变量必须用volatile类型限定符声明,以确保它对所有任务(线程)实时可见。(2)确保对该变量的所有访问(读和写)均为原子操作,既不会在读过程中被写打断,也不会在写过程中被读打断。通常,如果的变量的字长不大于处理器数据总线的宽度,读写操作是原子的。例如,8位机操作8位数据,32位机操作32位数据,这些通常都是原子操作。对32位ARM Cortex-M处理器来说,如果该全局变量是32位的,可以确保其是原子操作;如果变量是64位的,这种情况有些复杂,需要看编译器是否生成64位操作指令。保险起见,对多任务系统,强烈建议使用的全局变量不要大于CPU字长。对具有中断(异常)的系统,以上规则同样适用。
回复

使用道具 举报

1

主题

19

回帖

22

积分

新手上路

积分
22
发表于 2024-11-11 17:16:44 | 显示全部楼层
fxyc87 发表于 2024-7-8 13:07
可以使用全局变量,但上边的判断不是原子操作,有被中断的风险,要求不高可以这样操作。

怎么样是一个原子操作呢?赋值是原子的吗?
回复

使用道具 举报

1

主题

131

回帖

139

积分

初级会员

积分
139
发表于 2024-11-13 16:49:27 | 显示全部楼层
1322678967 发表于 2024-7-15 13:25
当然可以用全局变量,前提条件有两个:(1)该全局变量必须用volatile类型限定符声明,以确保它对所有任务 ...

32位系统操作8位变量,是原子操作吗?应该不是吧?
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2024-11-17 20:32:13 | 显示全部楼层
nnqtdf 发表于 2024-11-13 16:49
32位系统操作8位变量,是原子操作吗?应该不是吧?

对ARM Cortex-M 内核是原子操作,其他内核不确定,要看其内核总线描述
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-12 03:39 , Processed in 0.040510 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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