打印

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

[复制链接]
3888|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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大。
中间的都是填充。

建议使用指针直接指向目标地址,这样就不会有这情况。

使用特权

评论回复
5
zdhlixiang2006|  楼主 | 2013-7-7 12:05 | 只看该作者
aozima 发表于 2013-7-7 10:58
在0地址放一个字节,在512K处放一个字节,实际有用数据只有两个字节,但如果要把这两个数据合并成一个镜像 ...

哦,flash用指针可以任意读取,但是不能直接写,只能通过调用IAP命令

使用特权

评论回复
6
江枫渔火| | 2013-7-7 13:19 | 只看该作者
我用AT91芯片是直接跳到内存中去烧写FLash.不分什么IAP区,用户程序区~

使用特权

评论回复
7
mohanwei| | 2013-7-7 13:21 | 只看该作者
到官网下载一个IAP的例程,读懂,再修改……

使用特权

评论回复
8
coody| | 2013-7-7 21:31 | 只看该作者
建议不要使用绝对定义地址的方式

使用特权

评论回复
9
huangxz| | 2013-7-7 21:58 | 只看该作者
好像在哪里看过这个帖子了,楼主是不是多版块发帖啊

使用特权

评论回复
10
zdhlixiang2006|  楼主 | 2013-7-7 22:44 | 只看该作者
coody 发表于 2013-7-7 21:31
建议不要使用绝对定义地址的方式

有什么好办法吗

使用特权

评论回复
11
airwill| | 2013-7-8 09:14 | 只看该作者
真能折腾.
首先 __at 不是宏, 是个编译指令吧
这个东西很好用, 但是要配合芯片你的程序的地址安排情况, 不要随心所欲地设置地址哦

使用特权

评论回复
12
qingqiu647| | 2013-7-8 10:19 | 只看该作者
在STM32上用IAP,实现过代码升级

使用特权

评论回复
13
qingqiu647| | 2013-7-8 10:20 | 只看该作者
在STM32上用IAP,实现过代码升级

使用特权

评论回复
14
zdhlixiang2006|  楼主 | 2013-7-8 11:57 | 只看该作者
江枫渔火 发表于 2013-7-7 13:19
我用AT91芯片是直接跳到内存中去烧写FLash.不分什么IAP区,用户程序区~

:L

使用特权

评论回复
15
zdhlixiang2006|  楼主 | 2013-7-8 11:58 | 只看该作者
airwill 发表于 2013-7-8 09:14
真能折腾.
首先 __at 不是宏, 是个编译指令吧
这个东西很好用, 但是要配合芯片你的程序的地址安排情况, 不 ...

求详细说明:handshake

使用特权

评论回复
16
airwill| | 2013-7-8 13:31 | 只看该作者
INT32U PrmRun  __at(0X0007C000);

你不能也直接定义一个指针, 而不用直接定义变量在那个地址.
具体参考库函数里那么多外设的定义方法

使用特权

评论回复
17
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

粉丝