打印
[STM32F4]

有没有办法分两次在STM32下载程序,并运行呢

[复制链接]
3297|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wang12zhe|  楼主 | 2015-6-4 09:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
想实现这样的功能:

有三个设备,A  B  C

这三个设备都使用STM32F4芯片,三个设备的驱动程序相同,但是应用程序有点差异

想通过某种方式,这三个设备相同的驱动程序首先烧写到片芯片,产生无差别的标准品,

然后当需要产品 A  B  C  的时候,根据需要的类型 再次烧写有差别的应用程序,

在应用程序里,可以调用驱动程序完成相关的功能,

驱动程序 可以只是一些函数和变量,但是应用程序应该能正常调用他

有人这样做过吗?

我知道将驱动程序编译成库文件,可以实现    还有其他办法吗?
沙发
ticomi| | 2015-6-4 12:11 | 只看该作者
这样做理论上是可以的,但是实际上很困难!最好是将代码全部写入,通过预设标志位来确定需要运行的设备代码,标志位可以通过外部手段修改!

使用特权

评论回复
板凳
mmuuss586| | 2015-6-4 12:14 | 只看该作者
你还如3个程序写在一起,通过串口或其它方式设置,运行那个的代码;

使用特权

评论回复
地板
wowow| | 2015-6-4 12:50 | 只看该作者
这真没什么困难的,以前就回个一个类似的帖子。你查一下keil帮助里:
Linker User Guide -> Linker Command-line Options -> --symdefs=filename
9.118 --symdefs=filename
Creates a file containing the global symbol definitions from the output image.

Syntax
--symdefs=filename
where filename is the name of the text file to contain the global symbol definitions.
Default
By default, all global symbols are written to the symdefs file. If a symdefs file called filename already exists, the linker restricts its output to the symbols already listed in this file.
Note
If you do not want this behavior, be sure to delete any existing symdefs file before the link step.
Usage
If filename is specified without path information, the linker searches for it in the directory where the output image is being written. If it is not found, it is created in that directory.
You can use the symbol definitions file as input when linking another image.

以上是讲如何生成symbol文件,以下是讲如何使用symbol文件:
Related concepts
6.14 Access symbols in another image

以前贴子写过的就不写了,补充经验:
1.共用的代码最好是已经稳定,很少需要修改的,要不分开搞也没有意义了。
2.共用代码加一个版本信息,保存在固定地址(比如说最开头),应用程序里启动前读一下,判断一下版本的兼容性。

建议:最好帮助文档,特别是compiler和linker的文档浏览一遍,很多问题都有现成的解决方案。不用全部弄懂,只要知道有什么问题在哪可以查到就行。

使用特权

评论回复
5
hgjinwei| | 2015-6-4 12:52 | 只看该作者
我们前两代产品就是这么搞的,处于安全考虑,将一些解密程序独立编译及烧录。这些程序对应用提供统一接口就可以了。
不过要小心静态变量对内存的破坏,最好是要求这些程序只使用堆栈空间,不留静态空间。

使用特权

评论回复
6
wowow| | 2015-6-4 13:02 | 只看该作者
不好意思,上次是在正点原子的论坛回的帖:http://www.openedv.com/posts/list/44990.htm

假设IAP代码相对固定,可以将共用代码放到IAP项目里,scatter里将flash分成两个块,一部分是IAP独占,一部分是共用区。
链接时要加上--symdefs选项,生成一个symbol表,列出各个函数、变量的地址。帮助里有,一查有一串相关文档。
例如:--symdefs=.\share.sym
生成的symbol文件share.sym里删除无关的,保留共用的函数、字库之类的。然后加入到APP的项目里,
注意文件的属性要改成Object file。

APP也要在scatter文件里定义好区块,不能跟IAP和共用区重叠就行了。也就是说APP里没有将共同代码链接进去,只记录了代码/变量的地址,直接引用。

反过来共用代码放在APP里,生成symbol文件给IAP也是一样的。

使用特权

评论回复
7
wang12zhe|  楼主 | 2015-6-4 13:28 | 只看该作者
hgjinwei 发表于 2015-6-4 12:52
我们前两代产品就是这么搞的,处于安全考虑,将一些解密程序独立编译及烧录。这些程序对应用提供统一接口就 ...

能说的详细一点吗  或者哪里有可以参考的资料,第一次干  没思路

使用特权

评论回复
8
wang12zhe|  楼主 | 2015-6-5 14:26 | 只看该作者
wowow 发表于 2015-6-4 12:50
这真没什么困难的,以前就回个一个类似的帖子。你查一下keil帮助里:
Linker User Guide -> Linker Command ...

你好,第一次搞这个,有几个疑问,烦请指点,
1、看别人的帖子,有这样一句话: 链接时要加上--symdefs选项,生成一个symbol表,列出各个函数、变量的地址。帮助里有,一查有一串相关文档
在哪里增加--symdefs选项,能生成一个symbol表,


2、生成的这个symbol表如何添加到工程? 类似C文件一样的 add files to ?

3、我现在是想在裸机程序上 将MCU的外设初始化部分和外设应用部分使用分散加载实现,这样可以实现吗?

使用特权

评论回复
9
犹豫的大三| | 2015-6-5 15:58 | 只看该作者
hgjinwei 发表于 2015-6-4 12:52
我们前两代产品就是这么搞的,处于安全考虑,将一些解密程序独立编译及烧录。这些程序对应用提供统一接口就 ...

请教静态变量会破换内存怎么理解?我的IAR程序里用到了静态变量

使用特权

评论回复
10
hgjinwei| | 2015-6-6 08:18 | 只看该作者
wang12zhe 发表于 2015-6-4 13:28
能说的详细一点吗  或者哪里有可以参考的资料,第一次干  没思路

就是把源码编译到指定地址,并约定一个地址为程序入口地址。如PC的main函数,MCU里边就要看编译器怎么设置了,有些编译器可以支持main作为入口,但一般都要使用汇编引导。

打个比方,我有一个程序输出"Hello World"要独立编译,并设置在0x8000-0000地址运行,那就要将这个程序链接到0x8000-0000地址上。
而应用就这么调用: ((void(*)(void))0x80000000)();

使用特权

评论回复
11
hgjinwei| | 2015-6-6 08:23 | 只看该作者
犹豫的大三 发表于 2015-6-5 15:58
请教静态变量会破换内存怎么理解?我的IAR程序里用到了静态变量

所谓的“静态变量会破坏内存”是只两个不同时编译的程序在用一个系统(裸机,无MMU)运行,因为编译时不好相互约定静态变量的分配空间,在两个程序参差运行时,就有可能破坏彼此的静态空间。

比如A程序有个静态变量s_status被链接到0x20000000,而B程序也有个静态变量s_config被链接到0x20000000,你说,A改变了s_status,是否意味着B的s_config也被相应的修改了?

使用特权

评论回复
12
wowow| | 2015-6-6 09:17 | 只看该作者
hgjinwei 发表于 2015-6-6 08:23
所谓的“静态变量会破坏内存”是只两个不同时编译的程序在用一个系统(裸机,无MMU)运行,因为编译时不好 ...

放在公共区的一般只是函数和const变量(包括字符串、数据表、字库等)。假如某些模块实在有变量要用,用全局变量,不要用静态变量(包括全局静态变量和函数里的局部静态变量)。因为全局变量会在symbo文件里列出,而静态变量不会。这样应用程序就不知道这些静态变量的存在,冲突就是一定的了。这些全局变量的位置最好集中在一起,放在比较合适的位置。因为对应用程序来说,这些变量在内存里就像钉子钉在那不能动的,应用程序的内存分配必须绕着它们走。一般集中放在内存的开头或未尾。如果只用在内存大小固定的芯片里,放在末尾比较好。如果可能会用在不同内存大小的芯片里,放在开头比较好。

使用特权

评论回复
13
suiyy| | 2015-6-6 10:00 | 只看该作者
hgjinwei 发表于 2015-6-6 08:18
就是把源码编译到指定地址,并约定一个地址为程序入口地址。如PC的main函数,MCU里边就要看编译器怎么设 ...

调用地址错了,应该是((void(*)(void))0x80000001)();

使用特权

评论回复
14
suiyy| | 2015-6-6 10:07 | 只看该作者
本帖最后由 suiyy 于 2015-6-6 10:09 编辑

static修饰符需要分开考虑:
函数内的局部变量如果使用STATIC修饰 则和全局变量一致
如果全局变量加上STATIC修饰,则编译时地址不显,但也并不是说不同时候编译的文件会地址重叠
按照上面各位的意思 是不是说如果编译库中使用static修饰变量时 会在编译工程连接这个库时 地址会冲突?
这当然是不可能的。所以请不清楚的不要去误导新人

使用特权

评论回复
15
01dxwlm| | 2015-6-6 10:14 | 只看该作者
我去年就做过类似的程序,不过下载程序是通过串口,PC端程序是用VC做的

使用特权

评论回复
16
hgjinwei| | 2015-6-6 12:17 | 只看该作者
suiyy 发表于 2015-6-6 10:07
static修饰符需要分开考虑:
函数内的局部变量如果使用STATIC修饰 则和全局变量一致
如果全局变量加上STATI ...

你说的是一次链接,只生成一个目标,当然不会冲突。
但多个目标在同一芯片上运行,就不好说了。

比如boot程序跳入APP后,如果APP会返回,boot能保证其使用的内存空间不变?

使用特权

评论回复
17
wowow| | 2015-6-7 10:13 | 只看该作者
suiyy 发表于 2015-6-6 10:07
static修饰符需要分开考虑:
函数内的局部变量如果使用STATIC修饰 则和全局变量一致
如果全局变量加上STATI ...

这是讨论的是两个不同的的工程,请看清主题。

使用特权

评论回复
18
戈卫东| | 2015-6-7 10:17 | 只看该作者
相同的驱动写成一个模块多个应用共用很难么?

使用特权

评论回复
19
犹豫的大三| | 2015-6-8 11:20 | 只看该作者
hgjinwei 发表于 2015-6-6 08:23
所谓的“静态变量会破坏内存”是只两个不同时编译的程序在用一个系统(裸机,无MMU)运行,因为编译时不好 ...

我在编译时限定了两个程序的ROM和RAM的范围,比如IAR程序的ROM地址的范围是0x08000000~0x0800FFFF,RAM地址范围是0x20000000~0x20003FFF。应用程序的ROM地址范围是0x08010000~0x080FFFFF,RAM地址范围是0x20004000~0x20017FFF。这样你说的问题不是不会存在了吗?

使用特权

评论回复
20
kaoyanfor2010| | 2015-6-9 15:51 | 只看该作者
使用IAP方式可以实现,而且官网有例程

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

101

主题

205

帖子

1

粉丝