搜索
bottom↓
回复: 39

[分享]采用结构体和共用体配合的方式存储参数

  [复制链接]

出0入4汤圆

发表于 2018-3-30 10:15:49 | 显示全部楼层 |阅读模式
本帖最后由 bolizhicheng204 于 2018-3-30 10:20 编辑

经常用flash、EEROM保存参数。最笨的办法就是自己计算每一个变量的位置,一个个写入,这个办法效率极其低下,每次修改都要改 一大堆 东西。后来采用结构体和共用体配合的方式,效率高很多。其实论坛里很多人都用这个办法,我做了一些修改,特此分享。欢迎指正!
大概思路:结构体里面放置各种参数变量,在写一个共用体,把刚才的结构体和一个数组放一起,这样数组和结构体公用内存,其数据就可以相互访问了。
此处以芯片内部flash读写为例,见图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2018-3-30 10:22:01 | 显示全部楼层
一直这样写,但是好像有种说法,软件中最好不要用联合,目前我做不到。

出0入4汤圆

 楼主| 发表于 2018-3-30 10:30:52 | 显示全部楼层
surken 发表于 2018-3-30 10:22
一直这样写,但是好像有种说法,软件中最好不要用联合,目前我做不到。

不会吧,我看DSP底层代码还有STM32底层代码有很多联合体啊

出0入0汤圆

发表于 2018-3-30 10:40:31 | 显示全部楼层
不用联合体是MISRA规范的要求

出5入10汤圆

发表于 2018-3-30 10:44:54 | 显示全部楼层
用强制指针转换也可以,最愁的就是结构体 联合共用体的命名~一层套一层

出5入10汤圆

发表于 2018-3-30 10:45:50 | 显示全部楼层
还有个问题就是要考虑对齐~

出0入0汤圆

发表于 2018-3-30 10:54:56 | 显示全部楼层
MISRA規範開起來NXP ST的庫都是N千個錯誤

出0入53汤圆

发表于 2018-3-30 11:04:15 | 显示全部楼层
本帖最后由 zhcj66 于 2018-3-30 11:13 编辑

一个个定义地址确实麻烦,好处是数据出错好查找,保存速度快,采用结构体和共用体配合的方式存储参数存储需要整个区域存储或者读取,运行效率会慢不少

出0入4汤圆

 楼主| 发表于 2018-3-30 11:17:28 | 显示全部楼层
bailao99 发表于 2018-3-30 10:40
不用联合体是MISRA规范的要求

为什么不让用,会有什么隐患吗

出0入36汤圆

发表于 2018-3-30 11:25:11 | 显示全部楼层
合体相关的细节:
  1)联合体的末尾有多少个填充单元
  2)联合体的各个成员如何对齐
  3)多字节的数据类型高低字节如何排放顺序
  4)如果包含位字段 (bit-field),各位如何排放
因为这四个原因在不同系统、不同编译器下有太多可能,所以MISRA直接就不准使用了。

出0入93汤圆

发表于 2018-3-30 11:32:35 | 显示全部楼层
你这个联合体真繁琐,我都这样用的:
  1. typedef union {
  2.         struct SysParaStruct;
  3.         unsigned char buff[];
  4. } SysParaUnion;
复制代码
当然,匿名联合的#pragma anon_unions是要开启的。

出0入4汤圆

 楼主| 发表于 2018-3-30 11:32:47 | 显示全部楼层
norman33 发表于 2018-3-30 11:25
合体相关的细节:
  1)联合体的末尾有多少个填充单元
  2)联合体的各个成员如何对齐

有道理,用指针强制转换的方式替代共用体怎么样?

出0入0汤圆

发表于 2018-3-30 11:34:36 | 显示全部楼层
本帖最后由 zhonghua_li 于 2018-3-30 11:35 编辑

这种方式有个缺点:
会吧很多不相关的东西弄到一块去,
比如,我有个变量是模块A的变量Av中的, 有个变量Bv是模块B中的, 把这些变量弄到一个结构体里面去,感觉有点混乱。
以前我做了一个自动分配方案。
直接这么用就可以了  registe_eep(Bv);  save_to_eep(&Bv); load_from_eep(&Bv)

出0入93汤圆

发表于 2018-3-30 11:35:46 | 显示全部楼层
bolizhicheng204 发表于 2018-3-30 11:32
有道理,用指针强制转换的方式替代共用体怎么样?

你觉得联合体需要考虑的事情指针就不需要考虑了?用指针坑还更多些。

出10入0汤圆

发表于 2018-3-30 11:38:48 | 显示全部楼层
联合就是直接把C降到汇编的思维去了。
所以,少用,不用更好。

出0入0汤圆

发表于 2018-3-30 12:01:31 | 显示全部楼层
涵潇舒雅 发表于 2018-3-30 10:45
还有个问题就是要考虑对齐~

写和读都用一样的共用体 就不用考虑对齐了

出0入8汤圆

发表于 2018-3-30 12:17:12 | 显示全部楼层

出0入36汤圆

发表于 2018-3-30 12:40:38 | 显示全部楼层
bolizhicheng204 发表于 2018-3-30 11:32
有道理,用指针强制转换的方式替代共用体怎么样?

MISRA同样禁止不同类型的指针采用强制转换

出5入42汤圆

发表于 2018-3-30 13:22:27 | 显示全部楼层
C菜,不会这么用。一直都是平铺的数组,一个个变量定义好地址。我知道我很low。

出0入0汤圆

发表于 2018-3-30 13:37:43 | 显示全部楼层
我也是这样用的,可以少敲几句代码

出0入399汤圆

发表于 2018-3-30 14:05:51 | 显示全部楼层
看了TI的代码也是这样的:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出5入10汤圆

发表于 2018-3-30 15:00:38 | 显示全部楼层
weichao4808335 发表于 2018-3-30 12:01
写和读都用一样的共用体 就不用考虑对齐了

对的,要是强制指针转换,就得关注,之前被坑过~哈哈哈

出0入0汤圆

发表于 2018-3-30 16:55:04 | 显示全部楼层
涵潇舒雅 发表于 2018-3-30 15:00
对的,要是强制指针转换,就得关注,之前被坑过~哈哈哈

进一次就不会进第二次了

出0入0汤圆

发表于 2018-3-30 17:10:31 | 显示全部楼层
个人都是“结构体+指针强转”,感觉这样操作似乎稍微麻烦点了。

出0入55汤圆

发表于 2019-6-28 08:00:50 来自手机 | 显示全部楼层
我是定义一个结构体,存时将这个结构体按字节存储,读也是,没这么复杂。缺点就是每次读写都会全部操作

出0入0汤圆

发表于 2019-6-28 08:43:40 | 显示全部楼层
不错,这个操作还是挺方便的

出0入0汤圆

发表于 2019-6-28 14:34:18 | 显示全部楼层
将结构体的指针强制转换成unsigned int *,存的时候直接使用word存,取的时候直接word取,在STM32上这么处理,结构体都会自动对齐的

出0入0汤圆

发表于 2019-6-28 15:58:27 来自手机 | 显示全部楼层
norman33 发表于 2018-3-30 11:25
合体相关的细节:
  1)联合体的末尾有多少个填充单元
  2)联合体的各个成员如何对齐

结构体也有一样的问题。将结构体/联合体直接传到另外一个第三方独立编译的程序,都有可能遇到这些问题,包括用不同版本编译器编译出来的静态库/动态库,其他机器等等。

出0入0汤圆

发表于 2019-6-28 17:12:00 | 显示全部楼层
谢谢,联合体,结构体存储的经验

出0入0汤圆

发表于 2019-6-29 23:01:30 来自手机 | 显示全部楼层
学习了。

出0入0汤圆

发表于 2019-6-30 01:54:02 来自手机 | 显示全部楼层
取结构体地址直接强制类型转换不是更简单些?

出0入0汤圆

发表于 2019-7-1 22:56:29 | 显示全部楼层
可以看看CH376的库,我也是从那知道有这种写法

出0入59汤圆

发表于 2019-7-2 09:07:14 | 显示全部楼层
这个方法我们一直在用,特别是配合文件系统,把整个配置文件的参数,都定义为一个结构体,重文件直接读到结构体中;写入时把结构体直接写入到文件系统; 保存参数不大时非常好用;

出0入0汤圆

发表于 2019-7-2 10:42:22 | 显示全部楼层
额,这个方法相对比较复杂。
offsetof函数就是用来专门获取结构体变量的偏移地址,很好用。

出0入0汤圆

发表于 2019-7-2 11:07:38 | 显示全部楼层
有隐患,还好现在是Flash,一旦产品大量上市,有可能都不知道是怎么死的

出0入0汤圆

发表于 2020-5-13 17:31:30 | 显示全部楼层
takashiki 发表于 2018-3-30 11:32
你这个联合体真繁琐,我都这样用的:当然,匿名联合的#pragma anon_unions是要开启的。 ...

使用STM8的代码移植到STM32中用到联合体,没有开启匿名联合的#pragma anon_unions。结果一直报错。谢谢。

出0入0汤圆

发表于 2020-6-16 11:57:00 | 显示全部楼层
学习了!

出10入120汤圆

发表于 2020-6-16 15:26:49 来自手机 | 显示全部楼层
没看懂,这样除了省一点点时间以外,对比直接定义并使用结构的优点在什么地方?

出0入0汤圆

发表于 2020-6-16 15:36:31 | 显示全部楼层
makesoft 发表于 2020-6-16 15:26
没看懂,这样除了省一点点时间以外,对比直接定义并使用结构的优点在什么地方? ...

使用参数的时候用结构体中的参数
写入FLASH和从FLASH读取出来的时候用buffer,这样保持固定的数据格式
我在FLASH操作也是用这种方式,MCU内部使用问题不大,要传输的话根本不敢用,不同的系统编译选项对应关系不是固定的

出10入120汤圆

发表于 2020-6-16 15:53:33 来自手机 | 显示全部楼层
lw32 发表于 2020-6-16 15:36
使用参数的时候用结构体中的参数
写入FLASH和从FLASH读取出来的时候用buffer,这样保持固定的数据格式
我 ...

整体读写,和用指针指向结构体的首成员访问其实没有区别,反而定义了一堆东西牺牲了可读性和维护性  囧rz
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 19:37

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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