打印

51写bootloader时如何修改中断向量

[复制链接]
9205|31
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jerkoh|  楼主 | 2009-2-27 10:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1,目前的方案:将62K的flash 分2个区 0000h-0cfffh做应用程序区
从0d000h做bootloader区
   这样做有2个问题是:
   1,主程序在上电执行时必须要先jmp 0d000h转到我的bootloader区。
   2,当bootloader在下载时如果出现意外,导致下载开始就失败,而擦除了
jmp 0d000h 那就全部完玩,再也进不了bootloader。

2,现在我想,将bootloader放到程序空间的前面比如4K (1000h)
   这样也有2个问题 我解决不了。

         这些可否在bootloader里面都给先定义了。如下:
         org 0000h
         jmp start
         org 0003h
         jmp int0
         org 000bh
         jmp time0
         org 0013h
         jmp int1
         org 001bh
         jmp time1
         org 0023h
         jmp uart
 
int0: jmp 1003h         ;因为我在bootloader里面是不用在任何中断的
time0:jmp 100bh         ;串口也是查询收发的
int1: jmp 1013h         ;所以不会出现跳转到1000h以后的这些映射地址
time1:jmp 101bh
uart: jmp 1023h
         
         这样做的话,当bootloader下载应用程序时,应用程序就很不灵活,
首先,得把定义应用程序的中断向量给阉割,只下载它主函数开始部分写入FLASH
而且 它的中断向量地址都得定义好映射后的地址
        感觉这方法很麻烦。

        主要问题是应用程序如何来定义上面的中断入口地址,而且还要映射在1000h后面。
        大家多提意见

相关帖子

沙发
jerkoh|  楼主 | 2009-2-27 19:01 | 只看该作者

re

顶起来

使用特权

评论回复
板凳
ayb_ice| | 2009-2-27 20:42 | 只看该作者

有些51可以重映射

可以开机按某个键进入BOOT程序

使用特权

评论回复
地板
buaazy| | 2009-2-27 21:43 | 只看该作者

回复

放在前面确实中断向量问题不好解决,我认为可以放在最后,你存在的两个问题我想可以这么解决:
1.跳转的问题很简单,可以做个什么跳线什么的,在应用程序中判断一下就可以了。
2.如果在烧写程序失败,可以在程序中正常流程不会跑到的地方加些跳转到bootload的语句,当然这个也不是不能彻底解决

使用特权

评论回复
5
jerkoh|  楼主 | 2009-2-27 22:11 | 只看该作者

re

做的是一个TCP/IP转串口 iap(当然实际还是串口升级,只是PC软件是TCP通信操作)
所以硬件的人为操作是不允许的


使用特权

评论回复
6
ayb_ice| | 2009-2-27 22:25 | 只看该作者

可以在开机前

连续一段时间接收特定的指定命令进入IAP

使用特权

评论回复
7
jerkoh|  楼主 | 2009-2-27 22:50 | 只看该作者

re

ayb_ice
如果从0000H开始的512字节扇区被意外擦了
也就是没有了这样一个命令的接收改如何处理
请指点下,谢谢

使用特权

评论回复
8
ayb_ice| | 2009-2-27 23:06 | 只看该作者

如果没有硬件重映射

好象不能完全解决这样的问题

使用特权

评论回复
9
jerkoh|  楼主 | 2009-2-27 23:18 | 只看该作者

re

谢谢LS的
硬件重映射没有的。
应为这款51只是开饭了62K的data FLASH
可以任意读写修改 AP改AP
它的正真BOOTLOADE就是STC的串口下载区

MCU是 STC   iap12c5a62s2

使用特权

评论回复
10
quakegod| | 2009-2-28 05:04 | 只看该作者

偶也曾经考虑过这个问题

偶觉得有个办法可行

就是把bootLoader放在0000开始的扇区,并截获所有中断和跳转,
然后每次开机启动都会先运行BootLoader,BootLoader先校验程序区是否正确,
如果正确,则转到程序区运行,
在程序区里重新开辟一个中断向量表,Bootloader里面截获的中断统统跳转到新的向量表,缺点就是中断反应稍微延时了一点点
当然你写的程序需要特殊一点,
你可以把新的中断向量表定义到01000h开始,然后主程序接着在后面
把0000-1000h这段地址空出来,把原来的中断向量表也写上,跳到新的中断向量表,只是多了一个跳转,这样程序在仿真的时候是能通过的,也能写到别的芯片上运行,
只是在IAP的时候,0000-1000h那段地址不烧录就好了。
其实这样,你的BootLoader也可以使用中断了,只是多了一些判断后,可能中断延时会更多一点点。
程序就好像下面的
---BootLoader程序----
ORG 00h
    ljmp start1
org 03h
    ljmp 1003h
org 0bh
    ljmp 100bh
org 013h
    ljmp  1013h
org 01bh
    ljmp 101bh
org 023h
    ljmp 1023h
start1:
开始校验程序区,判断是否有IAP指令等。。


OK1: 跳转到正常的程序区
    ljmp 1000h
ERR:
     出错处理等。


-------  应用程序  ---------
org 00h
    ljmp 1000h
org 03h
    ljmp 1003h
org 0bh
    ljmp 100bh
org 13h
    ljmp 1013h
org 1bh
    ljmp 101bh
org 23h
    ljmp 1023h



org 1000h
    ljmp start2
org 1003h
    ljmp int0
org 100bh
    ljmp int1
org 1013h
    ljmp intt0
org 101bh
    ljmp intt1
org 1023h
    ljmp com1
start2:

int0:
.......
int1:
.......
intt0:
......
intt1:
.....
com1:
.....

---------  应用程序结束 -----------
org ????h
   db  校验值
然后烧录的时候,应用程序的 0000-1000h数据并不进行烧录
这样就没有再定位的问题了。
不知道上面的解释楼主能否明白。










使用特权

评论回复
11
jerkoh|  楼主 | 2009-2-28 10:41 | 只看该作者

re

谢谢楼上的,这个方法应该很可行,
唯一的缺点就是需要将HEX文件切割一下
另外 用户程序其实也必须定位(这里的定位就是根据BOOTLOADER提供的新向量地址跳回真实地址)

使用特权

评论回复
12
quakegod| | 2009-2-28 12:24 | 只看该作者

楼上并没有完全明白我的意思

实际上HEX不需要切割,只是在IAP程序中做一下忽略处理即可
另外用户程序也不需要重新定位,因为烧录前后程序本身并没有发生任何变化

使用特权

评论回复
13
walnutcy| | 2009-2-28 16:05 | 只看该作者

中断向量软件跳转到RAM固定位置

ARM7以前也是这么做的,

使用特权

评论回复
14
quakegod| | 2009-2-28 16:13 | 只看该作者

回楼上

这里讨论的是51,不是ARM,
51是哈佛结构的,不能运行RAM里的程序,
而且中断向量表是写在ROM里的,不能修改的。

使用特权

评论回复
15
hotpower| | 2009-2-28 16:20 | 只看该作者
16
ayb_ice| | 2009-2-28 17:34 | 只看该作者

14L

并非所有的51像你说的那样...

使用特权

评论回复
17
quakegod| | 2009-2-28 20:30 | 只看该作者

回16楼

你说的偶明白,偶当然也可以用外扩RAM的形式把ROM寻址和RAM寻址映射起来,但是这个不是这里讨论的问题,
这里讨论的IAP,程序在运行时,中断向量那部分确实就是ROM.

使用特权

评论回复
18
ayb_ice| | 2009-2-28 21:14 | 只看该作者

我也考虑过类似的问题

不过在实际中没有这样的需求,也没有认真搞过,但是一般可能比较困难,否则那些支持这样功能的51也不用做重大改进了,建议你去参考一下华邦的51,比如W78E516B这个芯片支持这样的功能,但它的结构是不一样的.

使用特权

评论回复
19
dxpol432| | 2009-3-1 01:22 | 只看该作者

这样试一下

51固定的中断无法改变,可以在每个中断服务程序中加一个判断(sub-intX),如果加载了用户程序,就跳到用户程序中的中断执行。方法是:在(sub-intX)程序部分使用两种指令一个是 push 另一个是 reti,详细情况可参考51系列在执行 RETI 时的内部过程,简单的说就是 PUSH指令制造了假的返回地址。

使用特权

评论回复
20
jerkoh|  楼主 | 2009-3-1 16:06 | 只看该作者

re

看了各位的建议
总的来时 还是需要用户代码来配合bootloader代码
比如用户代码需要中断向量跳转 必须根据bootloader先前开设的1000h
也就是关联还是存在,要做到bootloader和用户代码只关联一个串口接收命令后跳转看来是不成立的
谢谢楼上的几位!

使用特权

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

本版积分规则

116

主题

1401

帖子

2

粉丝