打印
[应用相关]

【IAP】讨论下RAM放IAP loader的问题

[复制链接]
7059|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
McuPlayer|  楼主 | 2008-7-30 19:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我现在也遇到了类似的问题,就是C语言是自动分配变量的,所以不知道各块RAM的使用情况。另外ST的USB Lib也会用到些局部变量,这RAM要是一覆盖,那变量map全完蛋了。00有什么好的idea解决此问题。

---------------------------------------------------
我只好退而求其次,在Flash的尾巴上分了一块给IAP loader,PC来指令,FW就跳到Loader上去,然后就是Loader和PC用USB通讯了,然后loader负责PC送来的AP的FW写到Flash的前端。

AP的FW放到前端,有两个好处,一是调试方便,二是烧录方便,JTAG/ISP不用设起始地址。

图片是我的Firmware打包Utility,负责把IAP和AP的hex文件先转成Binnary再combine成一个二进制文件。考虑客户的需求,当然其中有版本校验版权之类的信息打包进去。
沙发
McuPlayer|  楼主 | 2008-7-30 19:22 | 只看该作者

应香版要求,另开贴,希望大家一起把这个问题解决好

使用特权

评论回复
板凳
computer00| | 2008-7-30 20:03 | 只看该作者

各块RAM、ROM的使用你可以自己指定的呀~~~这个不是关键问题

你可以直接在链接文件中指定,改工程的堆栈在什么位置,变量在什么位置,程序在什么位置等等。

最麻烦的是代码的绝对地址跳转问题,我上次为了在44B0上搞个IAP,费了不少神,后来没办法了,
直接修改HEX文件下载进去的,晕……

因为要拷贝到RAM中去执行,所以运行地址必须要设置为RAM的地址,这样的话使用JTAG又无法将代码
下载到FLASH中去...如果设置在FLASH地址,虽然使用JTAG可以下载到FLASH中去,但是又不能复制到
RAM中去运行,因为有些指令是绝对跳转或者取绝对地址中的值,我晕……我当时是在KEIL中搞的,
所以很麻烦,据说在ADS中使用分散加载比较容易...IAR怎样搞法我就不清楚了...

好在STM32F10x这个不用将代码复制到RAM中去就可以了…………

可以看看我以前讨论的:
https://bbs.21ic.com/club/bbs/list.asp?boardid=35&t=2496814&tp=%u4E0D%u8FC7%u6211%u5DF2%u7ECF%u653E%u5F03%u8BA9%u7F16%u8BD1%u5668%u5168%u90E8%u4EA7%u751F%u76F8%u5BF9%u8DF3%u8F6C%u8FD9%u4E2A%u505A%u6CD5%u4E86

使用特权

评论回复
地板
香水城| | 2008-7-30 20:58 | 只看该作者

楼主这里谈了两个问题,一个是RAM区的定位,另一个是IAP的

不好意思让McuPlayer另开帖,因为前一个帖的楼主不了解什么是IAP,那个帖子谈了很多什么是IAP的问题。


正像圈圈所言,在STM32上写IAP不必把程序拷贝到RAM中运行,STM32可以实现在Flash中执行擦写Flash的操作程序。因此,楼主的问题变成了两个孤立的问题。


问题一、关于在RAM中开辟一个区域并拷贝一段程序到RAM中运行,如何分配这个RAM区:

可以考虑开一个大的数组,由编译器自动地分配一块存储区,拷贝程序时只需使用数组的名字即可,跳转的时候把数组的地址cast到函数指针直接调用。


问题二、IAP程序放在哪里?

我的意见是放在用户Flash区的开始,即低地址区,首先是因为中断向量表在地址0x0000 0000,IAP程序的Reset向量和中断向量都需要使用向量表;其次,IAP程序放在Flash的低地址区,真正的功能程序就会放在IAP之后,而且永远不会意外地覆盖IAP程序。

如果把IAP程序放在Flash的高地址端,不但没有上述两个好处,还有一个问题是如果你要把Flash的容量升级或降档,都要重新安排分配IAP程序的地址。

使用特权

评论回复
5
香水城| | 2008-7-30 21:02 | 只看该作者

我写了一个博客,可能有助于这个问题的讨论

使用特权

评论回复
6
computer00| | 2008-7-30 21:11 | 只看该作者

IAP和用户程序是两个时间上独立的程序,所以楼主不用担心RA

使用特权

评论回复
7
McuPlayer|  楼主 | 2008-7-30 23:04 | 只看该作者

我用的是Keil的MDK

IAP和用户程序是两个时间上独立的程序?----IAP和AP会share USB等部分的!
这时候,寄存器的状态和中间变量都很重要。
我目前是迂回解决的---USB重新枚举,但是Delay掉无谓的3秒时间。

真正的IAP应该是MCU没有重启,USB更谈不上重新枚举的问题,甚至OS的Timer Tick还有WDT都在正常Run着。
所以我说,我现在的IAP是个大打折扣的IAP,一占用了Flash、二是USB重新枚举。

我现在用的是Keil,我的AP用的变量以及buffer还是很大的,即使手工分配,也没有大片的空余。这时候一个比较好的Solution是,人为为各个变量与buffer指定地址,然后把跟IAP无关的RAM集中到一起,作为IAP的程序存放地址。可惜Keil MDK for ARM尚无法完美解决此问题。


下面是我的程序流程List,我这个先下载Loader,是考虑以后解决RAM放置Loader后,用户仍可自行IAP升级。

OpenDevice
iapWriteLoader
iapJmp2Loader
CloseDevice
Sleep(3000);
OpenDevice
iapWriteApplication
iapJmp2Application
CloseDevice

使用特权

评论回复
8
McuPlayer|  楼主 | 2008-7-30 23:08 | 只看该作者

还有个办法-----buffer不分配,直接指定地址

buffer不分配,直接指定地址
编译器的选项中,关闭buffer使用的空间
这样编译器就会认为此空间不可用,但是我们的几个大buffer仍然使用此空间,因为我们心里有底------但这是以破坏程序的可读性为代价的。

等我这里的Flash不够用,我恐怕要试这一招了。

使用特权

评论回复
9
pheavecn| | 2008-7-31 09:18 | 只看该作者

修改xcl文件,重定义段分配。

使用特权

评论回复
10
computer00| | 2008-7-31 10:20 | 只看该作者

这样的话那只能将你的IAP程序跟应用程序一起编译了...

使用特权

评论回复
11
香水城| | 2008-7-31 10:32 | 只看该作者

感觉楼主有点钻牛角尖

首先先明确我们讨论的对象有2个程序,一个是IAP程序,另一个是用户功能程序IAP程序仅仅用于对用户功能程序升级,它不会执行任何的其它功能性操作,包括OS、看门狗等。用户功能程序是真正实现MCU应用功能的程序,可以包括OS、各种外设的控制等。

MCU启动之后会先进入IAP程序,如果IAP程序检测到需要更新用户功能程序,则在更新了用户功能程序后,MCU进入用户功能程序并不再返回IAP程序;如果IAP程序检测到不需要更新用户功能程序,则MCU直接进入用户功能程序并不再返回IAP程序。后面这样的流程就是你的产品的正常工作流程。

这里的关键是,IAP程序是一个有限制性的程序,(假定IAP使用USB通道)它仅仅是操作USB和执行Flash的擦写,假定你的用户功能程序使用USB的HID协议,你完全可以把IAP程序的USB部分也实现为HID,这样当你从IAP程序转到用户功能程序时,USB设备的状态是已知的,除此之外没有其它的切换信息,因此根本不会有你说的那么多问题。

退一步说,你也可以约定一个固定的RAM区,用于从IAP程序用户功能程序传递少量状态信息,最好使用结构体把所有变量包起来,这样他们之间的位置不会乱。

使用特权

评论回复
12
computer00| | 2008-7-31 11:00 | 只看该作者

哈哈...楼主要的IAP功能并不是升级整个固件然后从新运行,

而仅仅是修改FLASH中的某些参数、某些数据而已。因而,楼主的IAP部分就成为了实际应用程序的一部分……
它已经不再是我们前面所讨论的固件升级用的IAP了...

使用特权

评论回复
13
香水城| | 2008-7-31 11:06 | 只看该作者

如果是实际应用程序的一部分,这就更容易了

把IAP部分作为一个功能模块实现即可。

至于RAM的分配,可以采用划分两个区,一个区是需要更新的程序部分相关变量,另一个区放其它数据,只需简单地对这两个区定位即可。

使用特权

评论回复
14
McuPlayer|  楼主 | 2008-7-31 15:31 | 只看该作者

Loader和AP是独立编译的,因为地址定位都不同

IAP对客户而言,他不管你升级了什么,他要的是功能的升级。
而对于我们设计者而言,自然包括代码的升级和参数的升级。
当然,如果像Hot大叔玩代码数组那样,把整个AP都看做参数也未尝不可。

使用特权

评论回复
15
computer00| | 2008-7-31 16:19 | 只看该作者

一般来说,升级时需要停止应用程序的,

就像PC机中的软件一样,升级需要先退出程序,然后再升级,然后重新运行。杀毒软件升级病毒库不一样,它只是修改部分文件。

在MCU系统中,没有操作系统和文件系统管理的话,通常升级就是停止用户程序,然后重新执行IAP程序。
执行完IAP之后,重新启动,执行用户程序。所以IAP和用户程序是时间上互斥的两段程序。


很少见像楼主这样,在程序运行中更新的...

使用特权

评论回复
16
香水城| | 2008-7-31 16:34 | 只看该作者

问题的关键是在IAP操作时是否要求正常的功能操作继续有效

不知道楼主的需求是哪一种?

按照圈圈的猜测,楼主是要求“在IAP操作时,正常的功能操作继续有效”,如果是这样,我在13楼的RAM分区法是否可行?

多数的需求是“在IAP操作时,停止正常的功能操作,IAP结束后从新启动正常的功能操作”。

使用特权

评论回复
17
McuPlayer|  楼主 | 2008-7-31 18:57 | 只看该作者

其实我在IAP中大部分功能是关掉的

但是有个跟硬件相关的检测,始终在进行。
保护检测不能随便停止,否则十几V灌进STM32也不是玩的。

使用特权

评论回复
18
hotpower| | 2008-7-31 19:33 | 只看该作者

感觉楼主总是问题多多~~~

使用特权

评论回复
19
boy123| | 2008-7-31 20:55 | 只看该作者

说白了就是人为分两个区写程序.BOOT放在低区好操作.

使用特权

评论回复
20
McuPlayer|  楼主 | 2008-8-1 11:11 | 只看该作者

是啊,问题多多

分身无术啊,现在是Software/Firmware/Hardware全是我在做,连客户的工程指导书和工厂的BOM都要做。
不过还好,Layout找人做了,自己可以抽点时间到二姨家灌水了。

另外,ISP软件比较来看,力源的ISP软件联机成功几率最高。
真想自己动手搞一个,尤其是昨天给客户几个PE工程师培训时,一个个ISP都不争气。

使用特权

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

本版积分规则

338

主题

7307

帖子

26

粉丝