搜索
bottom↓
回复: 54

MDK下程序分区管理,单独升级某分区后新增的全局变量不...

[复制链接]

出70入0汤圆

发表于 2016-3-30 23:53:49 | 显示全部楼层 |阅读模式
   我的程序分成三个分区,第1分区为操作系统和启动代码,第2个分区是逻辑功能模块,第3分区是网络管理模块,三个分区所占用的flash和ram均独立划分。1分区定型之后基本将不会再更新,2,3分区由不同的同事编写。
这么划分的目的主要是功能划分明确,后续某个分区需要新增功能或者修复bug,只需修改自己的代码,调试好之后远程更新自己所属的分区程序即可。
现在问题来了,我们测试发现,若后续变更的代码中新增了需要初始化的全局变量,升级后新增的变量不会初始化,甚至有可能影响到原来的旧变量初始化值。经查找资料发现,全局变量的初始化是在__main函数里面完成的,这部分代码是编译器
的内部裤函数自动生成的,应该不能修改。
   我现在的思路是:去掉__main函数,在各个分区中各自写一个用于初始化自己的全局变量的函数,但现在不知道如何将保存在flash中的全局变量初始化值copy到各个全局变量中,请有实现过类似功能的大神指点下,谢谢!

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2016-3-31 01:05:06 | 显示全部楼层
去掉IDE提供的.s文件,自己写一个

出100入85汤圆

发表于 2016-3-31 07:35:35 来自手机 | 显示全部楼层
怎么程序分区楼主到时可以普及下。

出0入0汤圆

发表于 2016-3-31 08:08:17 | 显示全部楼层
只要把不动的部分编译为LIB的库文件就好了,用户部分使用特定的函数作为入口,或MAIN在用户代码中,用特定的函数初始化系统,别的功能作为API使用

出0入0汤圆

发表于 2016-3-31 08:16:08 | 显示全部楼层
这样划区已经超出了我的认知范围。。。

出0入0汤圆

发表于 2016-3-31 08:29:02 | 显示全部楼层
三个区域分成三个不同的工程吗?如果是这样的话挺牛的,想不明白各自的中断怎么处理,也想不通操作系统的函数该怎么去调用,例如延时之类的。
反而是全局变量的调用好办,大家约定一个区域,到时候用指针指向一个绝对地址就行了。

出0入0汤圆

发表于 2016-3-31 09:00:50 | 显示全部楼层
思路可以实现,将另外俩区的限定为Noinit,在代码里自行初始化。
实用性不评论,与楼主观点不同。

出50入0汤圆

发表于 2016-3-31 09:10:37 | 显示全部楼层
本帖最后由 yuzr 于 2016-3-31 09:11 编辑

在RAM中开辟一块区域,3个分区都要用的全局变量放在里面。如果2,3分区要增加全局变量,那么放到这个分区。这样编译的时候,1分区代码应该不会受影响。
或者2楼的方法,研究IDE提供的.s文件并自己写一个。

对于读写flash的底层函数,放在1分区中,调试好后以后就不修改了。

出0入0汤圆

发表于 2016-3-31 09:11:38 | 显示全部楼层
确实很少见,请问楼主各个区域的程序存在相互调用的关系吗?

出0入0汤圆

发表于 2016-3-31 09:14:04 | 显示全部楼层
搜索 分散加载 看看

出0入0汤圆

发表于 2016-3-31 09:28:27 | 显示全部楼层
这种情况, 应该每个区做个全局变量初始化的接口函数就行, 每个区的RAM分离了, 在更新的时候, 先把对应去的RAM初始化为0, 然后,调用接口函数不就得了;

__main只能处理开机上电的活, 对应你这种情况不太适合吧

出70入0汤圆

 楼主| 发表于 2016-3-31 10:48:55 | 显示全部楼层
w282529350 发表于 2016-3-31 09:11
确实很少见,请问楼主各个区域的程序存在相互调用的关系吗?

2,3区会有数据交互,交互的变量地址是指定的不变的,不会调用对方的函数;1区是操作系统,公共调用的函数都在这个区。这是多线程的,这样分区是没问题的

出70入0汤圆

 楼主| 发表于 2016-3-31 10:49:17 | 显示全部楼层
oooios 发表于 2016-3-31 09:14
搜索 分散加载 看看

不是这回事

出70入0汤圆

 楼主| 发表于 2016-3-31 10:52:44 | 显示全部楼层
onepower 发表于 2016-3-31 09:28
这种情况, 应该每个区做个全局变量初始化的接口函数就行, 每个区的RAM分离了, 在更新的时候, 先把对应去的R ...

现在我不想对每个变量单独用语句来初始化,这样会很繁琐,而且后续新的开发人员接手如果不按这个规则编写就出问题了。我是想定义变量的时候跟正常的一样,如:int buff[]={1,2,3,4,5,6,7,8,9}, 程序跑起来这个buff数组就初始化为这些值。

出70入0汤圆

 楼主| 发表于 2016-3-31 10:54:27 | 显示全部楼层
dalarang 发表于 2016-3-31 08:29
三个区域分成三个不同的工程吗?如果是这样的话挺牛的,想不明白各自的中断怎么处理,也想不通操作系统的函 ...

同一个工程,通过生成LIB的方式给对方编译测试。

出70入0汤圆

 楼主| 发表于 2016-3-31 11:03:57 | 显示全部楼层
本帖最后由 gshuang1 于 2016-3-31 11:05 编辑
yuzr 发表于 2016-3-31 09:10
在RAM中开辟一块区域,3个分区都要用的全局变量放在里面。如果2,3分区要增加全局变量,那么放到这个分区。 ...


这样也不行的,全局变量初始化的值是保存在flash里面的,这些值是不连续的。现在关键是如何将flash的数据复制到对应的全局变量中。
例如:
变量定义:
struct  xxx  a={1,2};//结构体占用10字节
int    b=10;
char  buf[10]={4,5,6};
char  d=5;

编译后查看bin文件看到flash里面是:1 2 xx 4,5,6 xx xx 5,这些数据跟变量总大小都不一致,不能整块复制过去的,不知如何提取。

出70入0汤圆

 楼主| 发表于 2016-3-31 11:09:27 | 显示全部楼层
mcu5i51 发表于 2016-3-31 08:08
只要把不动的部分编译为LIB的库文件就好了,用户部分使用特定的函数作为入口,或MAIN在用户代码中,用特定 ...

这部分功能已经实现,现在有个问题是,2,3分区的代码变更时新增了需要初始化的全局变量,如果对电子板升级程序仅升级单个分区,1分区还是旧版本的烧录文件的话,新增的变量就不会初始化,如果新增变量插在旧变量前面也会影响到旧变量初始化值。

出50入0汤圆

发表于 2016-3-31 11:17:48 | 显示全部楼层
gshuang1 发表于 2016-3-31 11:03
这样也不行的,全局变量初始化的值是保存在flash里面的,这些值是不连续的。现在关键是如何将flash的数据 ...

我认为只能一个个全局变量加载。
上电先将ram清零,然后一个个加载全局变量的值。“数据跟变量总大小”不一致,在楼主的例子中,结构体占用10字节,将未使用的字节填成0。注意一下对齐问题。

出50入0汤圆

发表于 2016-3-31 11:19:17 | 显示全部楼层
gshuang1 发表于 2016-3-31 11:09
这部分功能已经实现,现在有个问题是,2,3分区的代码变更时新增了需要初始化的全局变量,如果对电子板升 ...

新增的变量为什么不加到旧变量的后面,规则是要定好的,大家都要遵守的。文档中写清楚就好。

出70入0汤圆

 楼主| 发表于 2016-3-31 11:29:03 来自手机 | 显示全部楼层
yuzr 发表于 2016-3-31 11:17
我认为只能一个个全局变量加载。
上电先将ram清零,然后一个个加载全局变量的值。“数据跟变量总大小”不 ...

很多人会这么用的,而且就算全部补齐也是跟flash对应不起来

出70入0汤圆

 楼主| 发表于 2016-3-31 11:31:52 来自手机 | 显示全部楼层
yuzr 发表于 2016-3-31 11:19
新增的变量为什么不加到旧变量的后面,规则是要定好的,大家都要遵守的。文档中写清楚就好。 ...

单个c文件是可以管理,但有很多文件的时候,你修改其中一个文件,在最后面增加了一个变量,编译出来后是插在中间的

出0入0汤圆

发表于 2016-3-31 11:32:36 | 显示全部楼层
我的项目跟楼主差不多,不过我是用iar做的,分为操作系统区和各功能模块,这样升级方便,修改分散加载文件的配置就可以了,全局变量全部初始化为0,然后使用的时候从存储器中载入,用了这么久没发现问题

出50入0汤圆

发表于 2016-3-31 11:34:25 | 显示全部楼层
gshuang1 发表于 2016-3-31 11:31
单个c文件是可以管理,但有很多文件的时候,你修改其中一个文件,在最后面增加了一个变量,编译出来后是 ...

将全局变量放在一个.c文件中,将RAM中放置全局变量的区域定义成一个大的数组,添加变量依次添加,注意变量长度的对齐问题。

出70入0汤圆

 楼主| 发表于 2016-3-31 11:37:16 来自手机 | 显示全部楼层
windrarara 发表于 2016-3-31 11:32
我的项目跟楼主差不多,不过我是用iar做的,分为操作系统区和各功能模块,这样升级方便,修改分散加载文件 ...

Iar编译出来的变量初始化值在flash里面是连续的吗,跟各个变量一一对应的吗?能否详细点呢?有悬赏

出0入0汤圆

发表于 2016-3-31 11:40:06 | 显示全部楼层
看起来你需要第4个工程,单独声明公共变量区,包括const变量和API指针,提取一组公共API供其它工程调用(全局变量什么的最好还是封装起来),针对这个工程的更改需要实时push到其他工程里面。
应该也不难搞,上SVN吧,所有人都在一个工作空间中编辑代码,但是负责不同工程的人具有不同权限,不是自己负责的工程只有编译和链接的权限没有编辑权限(只读),而公共工程是公开的,每个人都可以编辑。

这样大家build工作区的时候(你现在应该是工作区吧。。。),会把每个工程都编译一遍,保证其他工程的更改合并到最终的输出文件里面。否则的话,不上OS,仅仅依靠开发环境是没办法知道其他工程的信息并在编译链接的时候为他们安排空间的。

还有一种办法就是上OS,应用工程引入OS定义的各种资源文件声明,按照统一的标准做成APP,让OS去加载。RTT有这种机制的完整实现,可以参考一下。

出0入0汤圆

发表于 2016-3-31 11:53:52 | 显示全部楼层
gshuang1 发表于 2016-3-31 11:37
Iar编译出来的变量初始化值在flash里面是连续的吗,跟各个变量一一对应的吗?能否详细点呢?有悬赏 ...

我的全局变量不直接赋值,这样就会产生你1楼说的问题,而是专门写赋值函数,用之前赋值一下就可以了,初始化全部为0

出0入0汤圆

发表于 2016-3-31 11:56:10 | 显示全部楼层
error_dan 发表于 2016-3-31 11:40
看起来你需要第4个工程,单独声明公共变量区,包括const变量和API指针,提取一组公共API供其它工程调用(全 ...

楼主应该是升级的时候只升级相关的模块区域而不是全部升级,所以即使build了全部的工程,写进去的还是要升级的那个模块的部分,操作系统那边的全局变量还是没动的,所以会产生主楼说的问题

出0入0汤圆

发表于 2016-3-31 11:59:03 | 显示全部楼层
gshuang1 发表于 2016-3-31 11:37
Iar编译出来的变量初始化值在flash里面是连续的吗,跟各个变量一一对应的吗?能否详细点呢?有悬赏 ...

强烈建议你把整个项目全部build一遍,然后升级的时候升级所有flash区域而不是单个模块,这样应该就不会有问题了,我以前也遇到过这种问题,就是这样解决的

出70入0汤圆

 楼主| 发表于 2016-3-31 12:17:07 来自手机 | 显示全部楼层
windrarara 发表于 2016-3-31 11:59
强烈建议你把整个项目全部build一遍,然后升级的时候升级所有flash区域而不是单个模块,这样应该就不会有 ...

这样肯定是没问题的。但是这个产品的程序会分三个文件独立归档,版本管理也是独立的,后续走变更流程不能要求别人对他们代码进行版本升级。还有一个麻烦就是需要变更的时候都要向其他负责人索要最新的lib,他们升级也要向你要最新的lib

出70入0汤圆

 楼主| 发表于 2016-3-31 12:20:30 来自手机 | 显示全部楼层
error_dan 发表于 2016-3-31 11:40
看起来你需要第4个工程,单独声明公共变量区,包括const变量和API指针,提取一组公共API供其它工程调用(全 ...

我用的就是rtt操作系统,如何实现

出0入0汤圆

发表于 2016-3-31 12:22:34 | 显示全部楼层
gshuang1 发表于 2016-3-31 12:17
这样肯定是没问题的。但是这个产品的程序会分三个文件独立归档,版本管理也是独立的,后续走变更流程不能 ...

不知道你们公司的管理是怎么样的,你如果是负责人,可以让其他人把写好的代码给你,你build了之后拿去升级就可以了,类似这种的项目以后写清楚不能随便开全局变量,尽量用参数传递,其实这也是写代码的基本要求

出70入0汤圆

 楼主| 发表于 2016-3-31 12:23:10 来自手机 | 显示全部楼层
styleno1 发表于 2016-3-31 09:00
思路可以实现,将另外俩区的限定为Noinit,在代码里自行初始化。
实用性不评论,与楼主观点不同。 ...

我要的是能初始化,这个是不初始化

出70入0汤圆

 楼主| 发表于 2016-3-31 12:27:57 来自手机 | 显示全部楼层
windrarara 发表于 2016-3-31 12:22
不知道你们公司的管理是怎么样的,你如果是负责人,可以让其他人把写好的代码给你,你build了之后拿去升 ...

这跟产品有关,逻辑区会做不同的作业,而网络管理区和操作系统区只有一个作业,所以不完全独立出来的话,以后操作系统区会生成多个作业,但实际上这部分源码是没变的,不好管理

出70入0汤圆

 楼主| 发表于 2016-3-31 12:34:01 来自手机 | 显示全部楼层
windrarara 发表于 2016-3-31 12:22
不知道你们公司的管理是怎么样的,你如果是负责人,可以让其他人把写好的代码给你,你build了之后拿去升 ...

任何一个代码都不可能没有静态变量的,你能不用?传递进去的变量不是全局变量吗?全局变量跟静态变量不是同一个概念吗,只是作用区域的区别而已。

出0入0汤圆

发表于 2016-3-31 12:55:52 | 显示全部楼层
还是第一次听说单片机这么分区用的。我倒是做过boot+app结构,这个很常见,boot和app是分开的两个工程,flash也是各自的分区,因为不会同时运行RAM可以共用。
你这三个分区可是要同时运行的,是三个独立工程吗?

出70入0汤圆

 楼主| 发表于 2016-3-31 13:12:23 来自手机 | 显示全部楼层
科技猎人 发表于 2016-3-31 12:55
还是第一次听说单片机这么分区用的。我倒是做过boot+app结构,这个很常见,boot和app是分开的两个工程,fla ...

是的,这样运行是没问题的

出70入0汤圆

 楼主| 发表于 2016-3-31 13:14:20 来自手机 | 显示全部楼层
科技猎人 发表于 2016-3-31 12:55
还是第一次听说单片机这么分区用的。我倒是做过boot+app结构,这个很常见,boot和app是分开的两个工程,fla ...

共用一个工程,不能工程是不能同时跑的

出0入0汤圆

发表于 2016-3-31 13:16:54 | 显示全部楼层
整个程序是在多线程基础上运行的?那不还是基于操作系统的?所谓的分区只不过是操作系统的不同线程而已?这肯定不是平常的boot+app结构,只是多线程编程,至于内存什么的让编译去去分配地址不可以吗?平常的boot+app是两个程序中断跳转,两者不能直接交互信息,而且cup只能属于某一方,不能同时运行。

出0入0汤圆

发表于 2016-3-31 13:45:51 来自手机 | 显示全部楼层
所有的全局变量都指定唯一地址,unsiged char xdata b _at_ 0xF000;不过这样会很累,中间改一个后面都要改

出70入0汤圆

 楼主| 发表于 2016-3-31 13:58:22 来自手机 | 显示全部楼层
startwar0418 发表于 2016-3-31 13:45
所有的全局变量都指定唯一地址,unsiged char xdata b _at_ 0xF000;不过这样会很累,中间改一个后面都要改 ...

不是这回事

出70入0汤圆

 楼主| 发表于 2016-3-31 13:59:32 来自手机 | 显示全部楼层
单飞 发表于 2016-3-31 13:16
整个程序是在多线程基础上运行的?那不还是基于操作系统的?所谓的分区只不过是操作系统的不同线程而已?这 ...

不行的,.......

出0入0汤圆

发表于 2016-3-31 14:01:41 | 显示全部楼层
这个不是很好搞,目前为止还没见过有人自己处理静态变量初始化的。
静态变量包括全局变量和局部静态变量,它在编译完成后其地址就固定了,区别于由栈动态分配的局部变量。
静态变量初始化是在_main函数中完成的,未初始化及初始化为0的静态变量会放到ZI Data段,初始化不为0的静态变量放到RW Data段,
对于ZI Data段全部置0 即可,而RW Data段在ROM区还有一个映像区,不同编译器会有不同处理,最简单就是映像区和RW Data段一模一样直接拷贝就行,
而RW Data比较大时为了减小flash空间就会对其压缩,_main函数把映像解压缩后才能初始化RW Data段,而压缩算法又可能有多种。
只有把编译器实现_main函数的很多细节搞清楚才可能自己写一个替代的程序。

出70入0汤圆

 楼主| 发表于 2016-3-31 14:41:33 来自手机 | 显示全部楼层
科技猎人 发表于 2016-3-31 14:01
这个不是很好搞,目前为止还没见过有人自己处理静态变量初始化的。
静态变量包括全局变量和局部静态变量, ...

总算遇到一个明白人了。有部分编译器是不压缩的,就是mdk做了压缩,现在又不方便换编译器了。

出0入0汤圆

发表于 2016-3-31 15:16:27 | 显示全部楼层
以前也搞过类似的, BOOT管理一个FLASH区, USB协议栈一个FLASH区, 用户程序一个FLASH区, 一般情况下, 仅升级用户程序, 也碰到类似问题, 我的解决办法是预先分配全局变量, 后续升级的新增变量, 就用那些预先分配还没用到的全局变量.

出70入0汤圆

 楼主| 发表于 2016-3-31 16:19:06 来自手机 | 显示全部楼层
cheungman 发表于 2016-3-31 15:16
以前也搞过类似的, BOOT管理一个FLASH区, USB协议栈一个FLASH区, 用户程序一个FLASH区, 一般情况下, 仅升级 ...

请问预分配的全局变量没有调用到的话不会被忽略吗?你是怎么实现的

出0入0汤圆

发表于 2016-3-31 16:57:39 | 显示全部楼层
你是指编译器优化掉吗? 你可以用memset处理一下 我之前的项目好像没开优化.

我说一下以前的项目背景, 因为用到boot升级, 通信方式用usb, boot+app架构加上usb协议栈 ROM不够了, 所以架构改成boot+usb+app, 刚才看了以前的工程, 当时预先分配的是数组, 升级需要用到新的变量就直接用, 因为新的升级也只是逻辑处理, 用不了多少新的变量. 不过感觉这种土办法不太适合你的项目需求.

出0入0汤圆

发表于 2016-3-31 17:18:05 | 显示全部楼层
目前只用过两个区,还没搞过三个

出0入31汤圆

发表于 2016-3-31 19:00:19 来自手机 | 显示全部楼层
这个记录一下,后面研究研究

出0入0汤圆

发表于 2016-3-31 22:07:15 | 显示全部楼层
这3个分区的代码是通过scatter来管理的??

出70入0汤圆

 楼主| 发表于 2016-3-31 22:34:39 | 显示全部楼层
cheungman 发表于 2016-3-31 16:57
你是指编译器优化掉吗? 你可以用memset处理一下 我之前的项目好像没开优化.

我说一下以前的项目背景, 因为 ...

这种方法应该也不行,在__main函数里面调用了2个函数__decompress和__decompress1,网上说是解压rom里面的初始化数据的。编译器的压缩算法可能会根据初始值特点进行压缩的,某个区更新后rom中的某些初始值发生变化,可能会导致解压后数据不正确。

出70入0汤圆

 楼主| 发表于 2016-3-31 22:35:28 | 显示全部楼层
JJKwong 发表于 2016-3-31 22:07
这3个分区的代码是通过scatter来管理的??

是的。。。。。。。。。。。

出70入0汤圆

 楼主| 发表于 2016-4-1 09:56:03 来自手机 | 显示全部楼层
目前压缩问题已经解决,现在还有个新问题,请问如何把ro-data数据指定在某地址范围内?

出0入8汤圆

发表于 2018-7-18 13:59:12 | 显示全部楼层
gshuang1 发表于 2016-4-1 09:56
目前压缩问题已经解决,现在还有个新问题,请问如何把ro-data数据指定在某地址范围内? ...

楼主,能否介绍下 rom 怎么分3个区域的。

出70入0汤圆

 楼主| 发表于 2018-7-18 20:32:45 | 显示全部楼层
kebaojun305 发表于 2018-7-18 13:59
楼主,能否介绍下 rom 怎么分3个区域的。

SCT文件里面设置地址范围,定义一个section名,在c文件的最前面设置到这个section,不仅仅可以设置ROM,还可以指定RAM的占用范围。

出0入0汤圆

发表于 2018-7-18 21:26:45 | 显示全部楼层
关注下这个问题。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-27 03:47

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

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