搜索
bottom↓
回复: 16

AVR中断向量表

[复制链接]

出0入0汤圆

发表于 2009-4-19 11:48:26 | 显示全部楼层 |阅读模式
单片机为atmega8,目标是通过rs485给单片机升级
1、应用程序是用Codevision编写的
2、bootloader程序是用Imagecraft编写的
3、烧写文件的时候,是将两个程序合并后一起烧写进去的。
我的问题是:1、程序运行一段时间,Flash中的程序会被重写一部分(程序的开始部分),为什么呢。这样的操作过程是否有问题,需要注意点什么呢,是否和中断向量的迁移有关系呢。
            2、执行应用程序的时候,如果中断向量表在BOOTLOADER区的头部,那么会影响到应用程序的运行吗?要是影响的话,为什么呢?
请马潮老师给予解答,知道您很忙,不过我是真的希望老师能帮助一下我,这个问题我已经困惑了好长时间了。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2009-4-19 13:46:32 | 显示全部楼层
马老师忙,来说说我的一点看法吧。

1. Flash 程序被重写,可能是程序跑飞到Bootloader区,改写了Flash,另外一种可能是BootLoader程序有BUG,误操作修改了Flash。针对程序跑飞问题,一定要开启BOD或者加外部复位IC,针对程序Bug问题,需要仔细检查一下程序。

2. 至于中断向量表搬移问题,如果执行应用程序,并且应用程序不使用中断,那么中断向量表在哪个区都不是问题,但是应用程序不用中断的可能是不大的,建议在BootLoader程序跳入工作区前,就先做好堆栈指针的复位,以及中断向量表的搬移,这些事情不要留给应用程序。

出0入0汤圆

 楼主| 发表于 2009-4-19 19:36:11 | 显示全部楼层
多谢出来指教!!希望和你继续共同探讨!!
用C语言编写的怎样做到堆栈指针复位呢,跳出BOOTLOADER时,我是用的这条语句asm("jmp 0x0000"),这样可能有问题吗?
如果在执行应用程序的时候就把中断向量表移到BOOTLOADER区,执行应用程序的时候可能有问题吗?应用程序有中断

出0入0汤圆

发表于 2009-4-19 20:41:41 | 显示全部楼层
看来你的BootLoader又是抄谁的,又是 asm("jmp 0x0000") 这样的问题。你先查一下Mega8支不主持JMP指令,我接触的AVR,8K Flash以及以下的,都不支持JMP指令的,应该是RJMP。

    堆栈指针的复位,同样可以通过插入汇编实现,你既然知道asm("jmp 0x0000") ,就不会插入点别的么。用8位机,汇编、以及单片机的内部寄存器的结构还是要好好的了解一下。下面是Mega16的跳转汇编。用asm插入到C中吧。
;==========================================================================
; 函数名称:Sub_Enter_Work_Prog_Bank
; 函数功能:搬移中断向量表到0x0000,复位堆栈指针,然后进入工作程序区
; 入口参数:无
; 出口参数:无
; 用寄存器:R16
; 程序版本:1.0
; 编写日期:2007-12-28
; 修改次数:0
; 修改日期:
; 修改内容:
;==========================================================================
Sub_Enter_Work_Prog_Bank:                   ;//  
    CLI                                     ;//  
    LDI     R16, 0x04                       ;// 系统堆栈设置
    OUT     SPH, R16                        ;// SP = 0x04FF,SRAM 的最高地址
    LDI     R16, 0x0FF                      ;//  
    OUT     SPL, R16                        ;//  
    LDI     R16, 0x01                       ;// 程序完整,升级成功,进入工作模式前,搬移向量表到0x0000
    OUT     MCUCR, R16                      ;//  
    CLR     R16                             ;//  
    OUT     MCUCR, R16                      ;//  

    JMP     Work_Prog_Entry                 ;//     升级成功,进入工作区  (这里修改为RJMP 0x0000)

出0入0汤圆

发表于 2009-4-19 20:49:18 | 显示全部楼层
刚才查了一下,Mega8  与 Mega168系列的存储器结构有点不一样,上面的程序不能直接用,我只是想说明步骤。

1. 关中断
2. 复位堆栈指针
3. 搬移中断向量到工作区
4. 跳转入工作区

出0入0汤圆

 楼主| 发表于 2009-4-19 21:03:50 | 显示全部楼层
真是慧眼哪!惭愧!我抄的是马潮老师的ATMEGA128的BOOTLOADER程序,我也注意到了ATMEGA8,的跳转指令没有JMP,但是,用Imagecraft编译器编译Bootloader程序的时候没有出错。
另外,我还是想问问,如果从bootloader跳出的时候,用asm("rjmp 0x0000")跳到应用区头部的时候,难道没有复位堆栈指针吗?

出0入0汤圆

 楼主| 发表于 2009-4-19 21:06:28 | 显示全部楼层
谢谢关注,等待中...

出0入0汤圆

发表于 2009-4-19 21:20:49 | 显示全部楼层
编译能通过,表示AVR有这么条指令,但是不是所以AVR芯片都支持,个人觉得这个编译器也做得不是很好,这点本来应该报错,至少应该有警告的。

   另外,一跳转指令,如果能复位SP指针,那么世界就乱套了。建议多看看Datasheet,看得出来你对单片机的结构、机理还处于摸索阶段。

出0入0汤圆

 楼主| 发表于 2009-4-19 22:46:05 | 显示全部楼层
说的有道理!我还有待进一步研究一下单片机结构和机理啊!
我还是想问问:如果中断向量表在bootloader区,那么我执行应用程序的时候,应用程序运行的是否可靠呢,会不会出什么不可预知的错误呢?在那能找到这方面的资料呢?
哈哈。。。
我是不是有点问题多多啊!
还请赐教!我真是非常的想明白啊!谢谢!!!!!!!!!!!!!!!!!!!!!

出0入0汤圆

发表于 2009-4-19 23:26:41 | 显示全部楼层
嗯,17楼真是热心呀.学习!

有点问题请教一下.下面这些代码是我从C语言的反汇编文件中得到了
        in r28,__SP_L__
        in r29,__SP_H__
        sbiw r28,7
        in __tmp_reg__,__SREG__
        cli
        out __SP_H__,r29
        out __SREG__,__tmp_reg__
        out __SP_L__,r28

第一步,保存SP到R28:R29,
第二步,R28:R29减7
然后又把SP给还原回去了.
不明白.以前我总以为SP会初始化成一个固定值.

出0入0汤圆

发表于 2009-4-19 23:33:57 | 显示全部楼层
8楼,只要应用程序中不用中断,用 CLI 指令关掉总中断,中断向量表在哪个区是不重要的,一点影响也没有。

    9楼,这个应该是函数或者中断的返回部分的代码,你再看看这个程序的前段,是不是有指针加7的代码,这个部分的-7可能就是释放函数在栈上分配的空间。先搞清楚,函数的局部变量是在栈上分配的,使用完毕后,需要释放。加上static的局部变量例外,那时在堆上分配的。

出0入0汤圆

发表于 2009-4-19 23:39:38 | 显示全部楼层
唉……,sorry,说反了,AVR堆栈是向下生长的,-7应该是分配局部变量,向后看看是否有+7的指令释放栈空间。

出0入0汤圆

发表于 2009-4-19 23:50:06 | 显示全部楼层
本不想说什么,但还是忍不住。

首先,请lz不要假借我的名义。我在M128书中的BOOTLOAD的例程中根本没有使用中断,也就不存在中断向量迁移的问题。

AVR是提供了中断向量迁移的功能,但如果你不具备雄厚的基础和高超的能力,是根本用不好这个功能的。

BOOTLOAD,按其原本的功能就是更换用户区的代码,是单一的任务。在这段代码中建议不要使用中断,这样就不必考虑中断向量迁移这样复杂的问题。

出0入0汤圆

 楼主| 发表于 2009-4-20 09:27:36 | 显示全部楼层
不好意思,马潮老师,也许我说的不太明白,我是根据你的《Atmega128原理与开发应用指南(上)》中的atmega128的BOOTLOADER例子移植到ATMEGA8上的(只改变了相关的寄存器的配置),Bootloader程序中根本没有中断,但是,你在书中说道用Imagecraft编译bootloader程序的时候,编译器自动把中断向量表迁移到bootloader区的头部。所以,我才有了上面的问题:“如果中断向量表在Bootloader区,那么我执行应用程序的时候,应用程序是否运行可靠呢,会出问题吗?”
我真的是诚心诚意的想请教马潮老师!还请老师指导!谢谢!

出0入0汤圆

发表于 2009-4-20 18:45:23 | 显示全部楼层
atmega128的BOOTLOADER例子移植到ATMEGA8上,只改变了相关的寄存器的配置是不够的,M8的FLASH一页的大小与M128不同,有些指令也不同,都要做相应的修改。

在我的代码中,跳到0000开始执行前,已经把中断矢量迁移回0000处了。

出0入0汤圆

 楼主| 发表于 2009-4-20 20:09:18 | 显示全部楼层
FLASH页我注意到了,这点已经改动过了,程序也可以正常下载,我在跳到0x0000处开始执行的语句是asm("jmp 0x0000")这样写会有问题吗(Imagecraft编译时没有提示错误)?一定要用asm("rjmp 0x0000")吗?还请老师谅解,我这样问东问西的!

另外,我想请老师再指教一下:我的实现思路是,当执行应用程序的时候,如果接到升级命令就用指令asm("rjmp 0xc00")跳到Bootloader区。在执行应用程序,而不执行Bootloader程序的情况下,“如果中断向量表在Bootloader区,那么我执行应用程序的时候,应用程序是否运行可靠呢,会出问题吗?” 有这方面的详细资料吗?我想学习一下。

出0入0汤圆

发表于 2011-3-19 22:47:30 | 显示全部楼层
我使用BOODLOADER也遇到Flash中的程序的开始部分00-FF被重写,要么是写成了乱码,要么全写成了0xff,要么全写成了0x00.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 12:54

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表