MDK下的绝对地址宏__at到底怎么用呢

[复制链接]
 楼主| zdhlixiang2006 发表于 2013-7-7 08:20 | 显示全部楼层 |阅读模式
本帖最后由 zdhlixiang2006 于 2013-7-7 08:22 编辑

    前一段一个项目中用到了远程升级,本人也对IAP很感兴趣,于是开搞,主芯片是LPC2138,刚开始什么都不懂,2周后终于有点思路了。

        进入正题:我的下位机IAP程序分四部分,LPC2138 falsh 有500K,共27个扇区,分别是0-26,所以我的程序中是这么设计的:跳转程序(从默认地址开始存放,上电后首先执行),bootloader位于扇区1,用户程序区(扇区2-扇区12),程序备份恢复区(扇区13-扇区25),扇区26首地址存放一个跳转程序用到的标志。我用一整个扇区(4K)来存放一个标志(PrmRun)确实很浪费,主要是没有办法,因为NXP Flash的最小操作单位是扇区:Q

        程序分区存放我已实现,主要是利用了分散加载机制中断重映射,其他没什么特别的。总体思路是,跳转程序中去指定地址读取跳转标志,然后据此跳转(是用户程序区还是备份恢复区)。bootloader 利用IAP来升级用户程序区,如果更新成功就更新跳转标志PrmRun=1并跳转到用户程序区执行,如果多次失败就跳转到备份区,然后更新跳转标志PrmRun=0以告诉系统下次上电后仍然运行备份程序

        现在遇到一个问题,地址的绝对定位问题,因为26扇区首地址为0X0007C000,查看资料,MDK可以使用absacc.h中的__at宏,于是在bootloader中我这样定义了一个变量  INT32U PrmRun  __at(0X0007C000); 然后程序中当IAP升级成功时,就改变此标志为1, 我是这样搞的:
  PrmRun = 1;//默认为0 编译OK,但是当程序执行时就跟死机了一样,注释掉这句,OK,进入调试发现,这样操作会引起预取数据异常,为什么呢?如果这样操作本身有问题,那怎么来实现我的功能呢,即在26扇区首地址的数据可以随意更改,求解答,先谢了,读取很简单,利用指针定位即可
:hug:
 楼主| zdhlixiang2006 发表于 2013-7-7 08:32 | 显示全部楼层
补充一个很恐怖的现象,假如上面这句代码是这样的:INT32U PrmRun  __at(0X0007C000) = 1;大家知道编译后的RO有多大吗,有496K,就是说,大小就等于扇区0~扇区25之和,我试着下载,果然特别大,烧写了半分钟,我查看内存,在0X0007C000地址上确实按照小端模式存放了00 00 00 01这样四个四节,但是后面还紧跟了几个数据,很奇怪,不知道从哪里来的,字体是红色!!!
 楼主| zdhlixiang2006 发表于 2013-7-7 08:34 | 显示全部楼层
INT32U是 unsigned int的宏定义 忘了说了
aozima 发表于 2013-7-7 10:58 | 显示全部楼层
在0地址放一个字节,在512K处放一个字节,实际有用数据只有两个字节,但如果要把这两个数据合并成一个镜像的话,就有512K大。
中间的都是填充。

建议使用指针直接指向目标地址,这样就不会有这情况。
 楼主| zdhlixiang2006 发表于 2013-7-7 12:05 | 显示全部楼层
aozima 发表于 2013-7-7 10:58
在0地址放一个字节,在512K处放一个字节,实际有用数据只有两个字节,但如果要把这两个数据合并成一个镜像 ...

哦,flash用指针可以任意读取,但是不能直接写,只能通过调用IAP命令
江枫渔火 发表于 2013-7-7 13:19 | 显示全部楼层
我用AT91芯片是直接跳到内存中去烧写FLash.不分什么IAP区,用户程序区~
mohanwei 发表于 2013-7-7 13:21 | 显示全部楼层
到官网下载一个IAP的例程,读懂,再修改……
coody 发表于 2013-7-7 21:31 | 显示全部楼层
建议不要使用绝对定义地址的方式
huangxz 发表于 2013-7-7 21:58 | 显示全部楼层
好像在哪里看过这个帖子了,楼主是不是多版块发帖啊
 楼主| zdhlixiang2006 发表于 2013-7-7 22:44 | 显示全部楼层
coody 发表于 2013-7-7 21:31
建议不要使用绝对定义地址的方式

有什么好办法吗
airwill 发表于 2013-7-8 09:14 | 显示全部楼层
真能折腾.
首先 __at 不是宏, 是个编译指令吧
这个东西很好用, 但是要配合芯片你的程序的地址安排情况, 不要随心所欲地设置地址哦
qingqiu647 发表于 2013-7-8 10:19 | 显示全部楼层
在STM32上用IAP,实现过代码升级
qingqiu647 发表于 2013-7-8 10:20 | 显示全部楼层
在STM32上用IAP,实现过代码升级
 楼主| zdhlixiang2006 发表于 2013-7-8 11:57 | 显示全部楼层
江枫渔火 发表于 2013-7-7 13:19
我用AT91芯片是直接跳到内存中去烧写FLash.不分什么IAP区,用户程序区~

:L
 楼主| zdhlixiang2006 发表于 2013-7-8 11:58 | 显示全部楼层
airwill 发表于 2013-7-8 09:14
真能折腾.
首先 __at 不是宏, 是个编译指令吧
这个东西很好用, 但是要配合芯片你的程序的地址安排情况, 不 ...

求详细说明:handshake
airwill 发表于 2013-7-8 13:31 | 显示全部楼层
INT32U PrmRun  __at(0X0007C000);

你不能也直接定义一个指针, 而不用直接定义变量在那个地址.
具体参考库函数里那么多外设的定义方法
ayb_ice 发表于 2013-7-8 16:28 | 显示全部楼层
t_EEPROM const volatile eeprom __attribute__((at(SEL_EE_PAGE_OF_EFM32*SIZEOF_EFM32_EE_PAGE))) = {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:沐浴着XX的春风,义无反顾游荡在马勒戈壁

21

主题

523

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部