打印

有关KEIL下IAP使用带来的疑惑,来和大家交流交流

[复制链接]
2605|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zdhlixiang2006|  楼主 | 2013-7-5 22:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
       半年前开始自学ARM7,自己画图做了个板子,主芯片是LPC2138,参考资料一个是周工的《深入浅出ARM7上册》,另外一本是邵贝贝的UCOS-II,不谦虚的说,现在该片子的使用已经相当熟练,综合起来做一些有一定深度的应用型项目也是可以的,想想一路走来真的是相当不容易:'(。有一天在上网无意中看到了一篇关于使用IAP进行远程升级的**,让我非常有兴趣,但是很多东西刚开始都根本看不懂,比如什么是分散加载文件,什么是中断重映射,什么是bootloader?一个星期以来,也是边看书边思考边实验,感觉弄懂了不少,但是仍然碰到了一些棘手的问题,卡住了,没办法了,来二姨家请教请教大家, 我用的是KEIL4,启动代码是库中自带的LPC2000系列。

   现象一:KEIL工程下 选项设置中有 IROM和 IRAM,以2138为例,IROM起始地址是0,大小为0x80000,IRAM起始地址是0x40000000,大小是0x8000,这个是默认选项,假如我调整flash起始地址为第1扇区,即0x1000,那么这个时候会有几种情况:
    1,假如我的程序中没有使用中断,那么相比默认设置,程序也可以运行
   
    2,假如程序使用了中断,但是中断的写法使用了__irq的形式,即利用了KEIL提供的中断处理机制,程序也可以运行

   3,假如程序使用了中断,但是中断处理机制是自己写的,程序就不能运行了(地址设为0是可以的)


    其实第二种情况让我很疑惑,因为按照周工书上说的,当用户程序的起始地址不是从0x0开始时并且用户使用了中断,由于ARM内核在发生中断后会首先去读取0x0地址的中断向量,然后据此跳转,为了使中断能够正常响应,就要使用中断重映射,具体做法是在修改用户程序的启动代码,拷贝64B向量到RAM的底端,然后修改REMAP值为2,可是我什么都没做,竟然都可以,难道是因为__irq这种方式内部很特别?有哪位网友知道可以告诉我一下,谢谢!

    第三种情况更让我郁闷,因为该程序的启动代码和中断处理代码都是公司一个牛人搞的,我也一直都在用,当修改了IROM起始地址后,该程序就无法运行了,我按照上面周工提供的办法处理了一下,仍然不行,将IROM该为0程序就可以正常跑起来,谁能告诉我这个可能还和什么有关系呢?



相关帖子

沙发
zdhlixiang2006|  楼主 | 2013-7-5 22:07 | 只看该作者
补充说明:第三种情况下的的程序使用了操作系统UCOS-II,我用J-LINK进入仿真,发现程序死在了一个叫OS_InterCritical()的汇编代码中,该段代码非常简单,就是修改CPSR的I位,然后判断是否修改成功,如果修改不成功会返回到原标号出继续修改,结果就死在了那里

使用特权

评论回复
板凳
huangxz| | 2013-7-6 09:35 | 只看该作者
回答你的第二个问题,在arm7进入中断以后,会直接跳转到中断的向量地址,对于nxp的arm7在中断的向量地址里面一般会
LDR     PC, [PC, #-0x0120]     ; Vector from VicVectAddr
如果你在application里面重新设置VIC的话,那么对于application来说那条指令仍然是正确的,因为在中断进入是取寄存器的值,而寄存器的这个值是VIC来产生的。所以仍然能正确中断,那是不足为奇的。

使用特权

评论回复
地板
zdhlixiang2006|  楼主 | 2013-7-6 12:15 | 只看该作者
huangxz 发表于 2013-7-6 09:35
回答你的第二个问题,在arm7进入中断以后,会直接跳转到中断的向量地址,对于nxp的arm7在中断的向量地址里面一 ...

谢谢的热情回复,说实话我看了好几遍,但是没看懂您说的什么意思,可不可以解释的更清楚、更直白一些呢

使用特权

评论回复
5
huangxz| | 2013-7-6 14:11 | 只看该作者
zdhlixiang2006 发表于 2013-7-6 12:15
谢谢的热情回复,说实话我看了好几遍,但是没看懂您说的什么意思,可不可以解释的更清楚、更直白一些呢 ...

重点在VIC里面,只要知道VIC是如何工作的,就会明白了:lol

使用特权

评论回复
6
zdhlixiang2006|  楼主 | 2013-7-7 08:07 | 只看该作者
huangxz 发表于 2013-7-6 14:11
重点在VIC里面,只要知道VIC是如何工作的,就会明白了

我的下位机IAP程序分四部分,LPC2138 falsh 有500K,共27个扇区,分别是0-26,所以我的程序中是这么设计的:跳转程序(从默认地址开始存放,上电后首先执行),bootloader位于扇区1,用户程序区(扇区2-扇区12),程序备份恢复区(扇区13-扇区25),扇区26首地址存放一个跳转程序用到的标志。我用一整个扇区(4K)来存放一个标志确实很浪费,主要是没有办法,因为NXP Flash的最小操作单位是扇区!!!,程序分区存放我已实现,主要是利用了分散加载机制和中断重映射机制,其他没什么特别的。程序总体思路是,跳转程序中利用指针去读取跳转标志,然后据此跳转。bootloader用来用来升级用户程序区,如果更新成功就跳转到用户程序区执行,如果多次失败就跳转到备份区,然后更新跳转标志以告诉系统下次上电后运行哪个。现在遇到一个问题,地址的绝对定位问题,因为26扇区首地址为0X0007C000,查看资料,可以使用absacc.h中的__at宏,于是在bootloader中我这样定义了一个变量  INT32U PrmRun标志寄存器  __at(0X0007C000);然后程序中当IAP成功时,就改变此标志, 我是这样搞的:PrmRun标志寄存器 = 1;//默认为0 编译OK,但是当程序执行时就跟死机了一样,注释掉这句,OK,进入调试发现,这样操作会引起预取数据异常,为什么呢?如果这样操作本身又问题,那怎么来实现我的功能呢,即在26扇区首地址的数据可以随时更改,求解答,先谢了

使用特权

评论回复
7
huangxz| | 2013-7-7 17:07 | 只看该作者
zdhlixiang2006 发表于 2013-7-7 08:07
我的下位机IAP程序分四部分,LPC2138 falsh 有500K,共27个扇区,分别是0-26,所以我的程序中是这么设计 ...

楼主跟我说的不是一个问题,那我来回答楼主当前这个问题

lpc21xx里面有个寄存器叫 general purpose registers,用他可以来实现复位的时候寄存器内容不会改变,替代你的那个PrmRun寄存器,另外,你在程序运行的时候往flash是不能直接用那个PrmRun = 1;来实现,因为本来就不能直接写,出现异常也是情理中的。

使用特权

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

本版积分规则

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

21

主题

523

帖子

2

粉丝