搜索
bottom↓
回复: 10

请教LM3S BOOTLOADER代码中“dcd ResetISR - 0x20000000”如何理解?

[复制链接]

出0入0汤圆

发表于 2011-3-2 12:11:42 | 显示全部楼层 |阅读模式
//*********************************************************
// Cortex-M3 处理器的简化向量表,也是必要的,
//*********************************************************
    export  __vector_table
__vector_table
    dcd     g_pulStack + (STACK_SIZE * 4)  // Offset 00: Initial stack pointer
    dcd     ResetISR - 0x20000000          // Offset 04: Reset handler
    dcd     NmiSR                          // Offset 08: NMI handler
    dcd     FaultISR                       // Offset 0C: Hard fault handler
......

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

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2011-3-2 12:28:34 | 显示全部楼层
转自网上,全文如下:

揭开BOOT LOAD升级过程的神秘面纱



    在没有接触BOOTLOAD之前,看着别人搞这“玩意儿”,觉得是一个很有技术含量的事,当细细的去“品”过后,也就是那么一回事,作技术就是要深专,只要“钻”进去了,在某一时刻就会恍然大悟。今天就将我对BOOTLOAD升级过程的理解和大家分享分享。

    BOOTLOAD并不是只有arm中才有的,其它的嵌入式系统甚至PC上都会有bootloader,主要的作用就是引导操作系统。在硬件起动后,硬件设备尚未初始化,直接加载体积较大的系统比较困难,有时甚至无法加载,如系统内核在网络上的情况,所以常常在系统运行前,提供一个体积较小但又具体初始化基本软硬件环境的程序来运行,由它来载入系统并设置系统运行参数,并最终运行系统,这就是bootloader。

    它可以分为两大类,一类BOOTLOAD是芯片在出厂时,生产商固化在ROM中的BOOTLOAD;二类BOOTLOAD是用户在设计过程中,根据实际工程的需要设计一小段代码,使新的应用程序从非JATG接口引导到ROM区或RAM区。其实这两类在功能上都差不多。本文讨论二类BOOTLOAD,讨论以Cotex-M3内核的LM3S系列处理器为对象。代码和编译器是基于IAR5.11版本。

    我们都知道任何程序都是从复位开始执行起走的,BOOTLOAD也不例外。当芯片复位后(软、硬件复位,掉电复位等),系统产生复位中断,执行复位中断服务程序,复位中断的优先级最高,所以不需要考虑有谁可以打断它(专心做它自己的事)。当然,程序员就可以在复位中断里面打芯片的主意了。BOOTLOAD升级应用程序的点子就是从这里出发的(一发不可收拾“坏透了”),它先把自己的BOOTLOAD复制到RAM区,再零填充.bss段(数据段,主要用于存放那些初始化为0的变量和没有初始的自动变量。位于SRAM区)。然后就让向量表的偏移从RAM的起始地址开始算起,LM3Sxxxx是从0x2000 0000开始偏移,到此,开始在RAM区里执行。

    在RAM区里执行时,会对升级信号进行检测,如检测到要升级信号,则开始配置要升级的接口(升级前的准备),准备好了就升级应用程序。如果没有检测到升级信号则执行原有的用户应用程序。我们来看看启动代码分析,就知道是怎么回事了。
//*********************************************************
// 包含配置头文件
//*********************************************************
#include "bl_config.h"
//*********************************************************
// 声明.bbs数据段,此段位于RAM区
//*********************************************************
    rseg    .bss:DATA(2)
//*********************************************************
// 分配存储堆栈
//*********************************************************
g_pulStack ds8 STACK_SIZE * 4
//*********************************************************
// 声明INTVEC段,此段位于ROM区,用于存放下面这一段向量表
//*********************************************************
    rseg    INTVEC:CONST(2)
//*********************************************************
// Cortex-M3 处理器的简化向量表,也是必要的,
//*********************************************************
    export  __vector_table
__vector_table
    dcd     g_pulStack + (STACK_SIZE * 4)  // Offset 00: Initial stack pointer
    dcd     ResetISR - 0x20000000          // Offset 04: Reset handler
    dcd     NmiSR                          // Offset 08: NMI handler
    dcd     FaultISR                       // Offset 0C: Hard fault handler
    dcd     IntDefaultHandler              // Offset 10: MPU fault handler
    dcd     IntDefaultHandler              // Offset 14: Bus fault handler
    dcd     IntDefaultHandler              // Offset 18: Usage fault handler
    dcd     0                              // Offset 1C: Reserved
    dcd     0                              // Offset 20: Reserved
    dcd     0                              // Offset 24: Reserved
    dcd     0                              // Offset 28: Reserved
    dcd     UpdateHandler - 0x20000000     // Offset 2C: SVCall handler
    dcd     IntDefaultHandler              // Offset 30: Debug monitor handler
    dcd     0                              // Offset 34: Reserved
    dcd     IntDefaultHandler              // Offset 38: PendSV handler
#if defined(ENET_ENABLE_UPDATE)
    import  SysTickIntHandler
    dcd     SysTickIntHandler              // Offset 3C: SysTick handler
#else
    dcd     IntDefaultHandler              // Offset 3C: SysTick handler
#endif
#if defined(UART_ENABLE_UPDATE) && defined(UART_AUTOBAUD)
    import  GPIOIntHandler
    dcd     GPIOIntHandler                 // Offset 40: GPIO port A handler
#endif
//*********************************************************
// 声明代码段CODE,用于存放代码段
//*********************************************************
    rseg    CODE:CODE(2)
    thumb
//*********************************************************
// 初始化时,把flasn里面的boot loader拷贝到SRAM区,
// 零填充.bss段并从SRAM区向量表开始执行
//*********************************************************
ProcessorInit
    //
    // 把flash 的 boot loader拷贝到SRAM区
    //
    movs    r0, #0x00000000
    ldr     r1, =0x20000000         // SRAM区的起始地址
    ldr     r2, =SFB(.bss)
copy_loop
        ldr     r3, [r0], #4
        str     r3, [r1], #4
        cmp     r1, r2
        blt     copy_loop          // 复制boot loader代码
    //
    // 零填充.bss段
    //
    movs    r0, #0x00000000
    ldr     r2, =SFE(.bss)
zero_loop
        str     r0, [r1], #4
        cmp     r1, r2
        blt     zero_loop

    //
    // 设置中断向量表相对于SRAM区的起始地址的偏移量
    //
    ldr     r0, =0xe000ed08    // 中断向量的起始地址
    ldr     r1, =0x20000000
    str     r1, [r0]
  
    orr     lr, lr, #0x20000000 // 设置向量表偏移寄存器为SRAM底部

    bx      lr                 // 跳转到SRAM区执行

//*********************************************************
// 复位中断处理程序
//*********************************************************
    export  ResetISR        // 复位中断函数声明
ResetISR

    bl      ProcessorInit   // 调用ProcessorInit汇编代码

    //
    // 看是否有升级信号
    //
    import  CheckForceUpdate
    bl      CheckForceUpdate    // 调用升级检测程序
    cbz     r0, CallApplication // 如果检测到没有升级信号.就调用原有的应用程序。
                                // 如果有则继续向下执行

    //
    // 处理器相关配置
    //
#ifdef ENET_ENABLE_UPDATE       // 以太网升级接口配置
    import  ConfigureEnet
    bl      ConfigureEnet
#elif defined(CAN_ENABLE_UPDATE) // CAN接口升级配置
    import  ConfigureCAN
    bl      ConfigureCAN
#else
    import  ConfigureDevice     // 其它接口升级配置如I2C/UART/SSI
    bl      ConfigureDevice
#endif

    //
    //  调用升级程序
    //
#ifdef ENET_ENABLE_UPDATE        // 调用以太网升级程序
    import  UpdateBOOTP
    b       UpdateBOOTP
#elif defined(CAN_ENABLE_UPDATE) // 调用CAN升级程序
    import  UpdaterCAN
    b       UpdaterCAN
#else
    import  Updater              // 其它接口升级程序。开始升级处理了
    b       Updater
#endif

    //
    // 准备调用应用程序
    //
CallApplication                  // 如果没有升级信号就执行这里调应用程序
    ldr     r0, =APP_START_ADDRESS // 应用程序的起始地址加载到R0

    ldr     r1, =0xe000ed08     // 应用程序响量表的地址LM3S系列芯片中断向量是从0Xe000ed08开始的
    str     r0, [r1]

    // 从应用程序响量表中读出堆栈指针
    // 堆栈是向量表的一开始位址.LM3S芯片是堆栈的栈顶地址,有些芯片可能是栈底地址,
    // 如果是栈底的话,PC指针就等于SP+堆栈大小+4
    ldr     r1, [r0]
    mov     sp, r1

    //
    // 从应用程序响量表中读出PC指针
    //
    ldr     r0, [r0, #4]
    bx      r0    // 开始执行应用程序

//*********************************************************
// 升级中断处理程序,这段代码和上面这段代码类似,不加分析。
//*********************************************************
UpdateHandler
    //
    // Initialize the processor.
    //
    bl      ProcessorInit

    //
    // Load the stack pointer from the vector table.
    //
    movs    r0, #0x00000000
    ldr     r0, [r0]
    mov     sp, r0

    //
    // Branch to the update handler.
    //
#ifdef ENET_ENABLE_UPDATE
    b       UpdateBOOTP
#elif defined(CAN_ENABLE_UPDATE)
    import  AppUpdaterCAN
    b       AppUpdaterCAN
#else
    b       Updater
#endif

//*********************************************************
// 不可屏蔽中断处理程序
//*********************************************************
NmiSR
    b       .     // 死循环
//*********************************************************
// 硬件错误中断处理程序
//*********************************************************
FaultISR
    b       .     // 死循环
//*********************************************************
// 未定义中断处理程序
//*********************************************************
IntDefaultHandler
    b       .     // 死循环
//*********************************************************
// 延时函数
//*********************************************************
    export  Delay
Delay
    subs    r0, #1
    bne     Delay
    bx      lr
//*********************************************************
// 启动文件结束
//*********************************************************
    end

出0入0汤圆

发表于 2011-3-2 12:38:14 | 显示全部楼层
好东西 顶个

出0入0汤圆

 楼主| 发表于 2011-3-2 14:16:27 | 显示全部楼层
回复【楼主位】eworker
-----------------------------------------------------------------------

dcd     ResetISR - 0x20000000?

出0入0汤圆

 楼主| 发表于 2011-3-2 17:13:36 | 显示全部楼层
为何要减去0x20000000?

出0入0汤圆

 楼主| 发表于 2011-3-2 18:41:00 | 显示全部楼层
回复【4楼】eworker
为何要减去0x20000000?
-----------------------------------------------------------------------

下班了,顶一下!

出0入0汤圆

发表于 2011-3-3 13:03:13 | 显示全部楼层
不是写着,向量表的便宜地址吗?

出0入0汤圆

 楼主| 发表于 2011-3-3 14:29:34 | 显示全部楼层
回复【6楼】touch_avr
不是写着,向量表的便宜地址吗?
-----------------------------------------------------------------------

为何要将中断向量表放到RAM中去?

出0入0汤圆

发表于 2011-8-17 15:40:47 | 显示全部楼层
mark

出0入0汤圆

发表于 2014-2-10 14:20:08 | 显示全部楼层
多加学习!

出0入0汤圆

发表于 2014-2-10 15:03:34 | 显示全部楼层
在看LM4F232,,比这个要复杂些。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-26 16:36

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

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