单片机中断向量偏移前移到启动代码中

一、问题

单片机经常存在这么一种结构:BOOT+配置+APP。BOOT与配置一次性开发完,更改的概率较低,但APP一直处于维护过程中。

APP维护经常使用仿真器进行DEBUG,大部分情况下是编译在首地址0x8000000并且运行,这里编译需要更改两个地方:

1.IDE指定的FLASH首地址,或.sct文件:

LR_IROM1 0x08020000 0x00040000 {                 ; 定义一个加载时域,域基址:0x08020000,域大
                                                                             ; 小为 0x00040000,对应实际 Flash 的大小
ER_IROM1 0x08000000 0x00040000 {                 ; 定义一个运行时域,第一个运行时域必须和加载
                                                                              ; 时域起始地址相同,否则库不能加载到该时域的
                                                                              ; 错误,其域大小一般也和加载时域大小相同
*.o (RESET, +First)                                                 ; 将 RESET 段最先加载到本域的起始地址外,即
                                                                              ; RESET 的起始地址为 0,RESET 存储的是向量表
*(InRoot$$Section)                                                           
.ANY (+RO)                                                           ; 加载所有匹配目标文件的只读属性数据,包含:
                                                                               ; Code、RW-Code、RO-Data。
.ANY (+XO)                                                          
} 
RW_IRAM1 0x20000000 0x00040000 {            ; 定义一个运行时域,域基址:0x20000000,域大
                                                                         ; 小为 0x00040000,对应实际 RAM 大小
* (+RW +ZI)                                                      ; 加载所有区配目标文件的 RW-Data、ZI-Data
                                                                          ; 这里也可以用.ANY 替代*号
}
ARM_LIB_HEP  0x20040000 EMPTY 0x70000 {            ; 定义一个运行时域,域基址:0x20040000,域大小为0x70000,预留给启动代码里的堆用
}
ARM_LIB_STACK  0x200BFFC0 EMPTY -0x BFFC0 {      ; 定义一个运行时域,域基址:0x200BFFC0,域大小为0x BFFC0,预留给启动代码里的栈用
                                                                                      ;启动代码汇编使用__
;IMPORT |Image$$ARM_LIB_STACK$$ZI$$Linit|
                                                                                 ;__Vector DCD  |Image$$ARM_LIB_STACK$$ZI$$Linit| ;Top of Stack
}
BOOT_INFO  0x200BFFC0 EMPTY 0x10 {            ; 定义一个运行时域,域基址:0x200BFFC0,域大小为0 x10,预留引导信息用
			               ;C/C++使用:
               ;extern unsigned int Image$$BOOT_INFO$$ZI$$Base;//起始
               ;extern unsigned int Image$$BOOT_INFO$$ZI$$Limit; //结束
                                                                            ;#define BOOT_INFO_BASE_ADDR    ((unsigned int)(&Image$$BOOT_INFO$$ZI$$Base))//0x200BFFC0
                                                                           ;#define BOOT_INFO_END_ADDR    ((unsigned int)(&Image$$BOOT_INFO$$ZI$$Limit))//0x200BFFD0
}
MCU_SELF_TEST_RESULT  0x200BFFD0 EMPTY 0x10 {            ; 定义一个运行时域,域基址:0x200BFFD0,域大小为0 x10,预留自检信息用
}
}

2.程序运行起来指定的中断向量表由0x8020000改为0x8000000:

#define VECTORTABLE_OFFSET 0x20000
Set_Vector_Tabel(VECTORTABLE_OFFSET);//赋值给寄存器0xE000ED08
//FreeRTOS中没有亚优先级处理,必须在第一个任务前配置为Group4
Set_Nvic_Priority_Group_Config(NVIC_PriorityGroup_4);

因此,为了避免每次仿真器DEUBG都要修改第2个步骤的代码,想办法SCT的地址与代码关联起来。

二、问题解决:

定义中断向量地址:

IMPORT |Image$$ARM_LIB_STACK$$ZI$$Linit|
__Vector DCD  |Image$$ARM_LIB_STACK$$ZI$$Linit| ;Top of Stack

在启动代码的初始化与进入MAIN之间增加几句代码:

;重映射中断向量
LDR R0, =0xE000ED08
LDR R1, = __Vector
STR R1, [R0];从栈的首地址取出中断向量地址,写入寄存器0xE000ED08

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值