- ;******************************************************************************
 
- ;
 
- ; The NMI handler.
 
- ;
 
- ;******************************************************************************
 
- NmiSR
 
- if :def:_ENABLE_MOSCFAIL_HANDLER
 
- ;
 
- ; Grab the fault frame from the stack (the stack will be cleared by the
 
- ; processor initialization that follows).
 
- ;
 
- ldm sp, {r4-r11}
 
- mov r12, lr
 
 
- ;
 
- ; Initialize the processor.
 
- ;
 
- bl ProcessorInit
 
 
- ;
 
- ; Branch to the SRAM copy of the NMI handler.
 
- ;
 
- ldr pc, =NmiSR_In_SRAM
 
- else
 
- ;
 
- ; Loop forever since there is nothing that we can do about a NMI.
 
- ;
 
- b .
 
- endif
 
 
- ;******************************************************************************
 
- ;
 
- ; The hard fault handler.
 
- ;
 
- ;******************************************************************************
 
- FaultISR
 
- ;
 
- ; Loop forever since there is nothing that we can do about a hard fault.
 
- ;
 
- b .
 
 
- ;******************************************************************************
 
- ;
 
- ; The update handler, which gets called when the application would like to
 
- ; start an update.
 
- ; 升级服务函数,当应用程序想要开始升级时,调用这个函数.
 
- ;
 
- ;******************************************************************************
 
- UpdateHandler
 
- ;
 
- ; Initialize the processor. 初始化处理器
 
- ;
 
- bl ProcessorInit ;调用子程序
 
 
- ;
 
- ; Branch to the SRAM copy of the update handler.
 
- ;
 
- ldr pc, =UpdateHandler_In_SRAM
 
 
- ;******************************************************************************
 
- ;
 
- ; This portion of the file goes into the text section.
 
- ;
 
- ;******************************************************************************
 
- align 4
 
- area ||.text||, code, readonly, align=2
 
 
- Reset_Handler_In_SRAM
 
- ;
 
- ; Call the user-supplied low level hardware initialization function
 
- ; if provided.
 
- ; 如果用户提供了底层硬件初始化函数,则调用这个函数
 
- ;
 
- if :def:_BL_HW_INIT_FN_HOOK
 
- import $_BL_HW_INIT_FN_HOOK
 
- bl $_BL_HW_INIT_FN_HOOK
 
- endif
 
 
- ;
 
- ; See if an update should be performed.
 
- ; 检查是否有升级请求
 
- ;
 
- import CheckForceUpdate
 
- bl CheckForceUpdate
 
- cbz r0, CallApplication ;结果为零则转移(只能跳到下一行)
 
 
- ;
 
- ; Configure the microcontroller.
 
- ;
 
- EnterBootLoader
 
- if :def:_ENET_ENABLE_UPDATE
 
- import ConfigureEnet
 
- bl ConfigureEnet
 
- elif :def:_CAN_ENABLE_UPDATE
 
- import ConfigureCAN
 
- bl ConfigureCAN
 
- elif :def:_USB_ENABLE_UPDATE
 
- import ConfigureUSB
 
- bl ConfigureUSB
 
- else
 
- import ConfigureDevice
 
- bl ConfigureDevice
 
- endif
 
 
- ;
 
- ; Call the user-supplied initialization function if provided.
 
- ; 如果用户提供了初始化函数,则调用.
 
- ;
 
- if :def:_BL_INIT_FN_HOOK
 
- import $_BL_INIT_FN_HOOK
 
- bl $_BL_INIT_FN_HOOK
 
- endif
 
 
- ;
 
- ; Branch to the update handler.
 
- ; 进入升级处理程序
 
- ;
 
- if :def:_ENET_ENABLE_UPDATE
 
- import UpdateBOOTP
 
- b UpdateBOOTP
 
- elif :def:_CAN_ENABLE_UPDATE
 
- import UpdaterCAN
 
- b UpdaterCAN
 
- elif :def:_USB_ENABLE_UPDATE
 
- import UpdaterUSB
 
- b UpdaterUSB
 
- else
 
- import Updater
 
- b Updater
 
- endif
 
 
- ;
 
- ; This is a second symbol to allow starting the application from the boot
 
- ; loader the linker may not like the perceived jump.
 
- ;
 
- export StartApplication
 
- StartApplication
 
- ;
 
- ; Call the application via the reset handler in its vector table. Load the
 
- ; address of the application vector table.
 
- ;
 
- CallApplication
 
- ;
 
- ; Copy the application's vector table to the target address if necessary.
 
- ; Note that incorrect boot loader configuration could cause this to
 
- ; corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start
 
- ; of SRAM) is safe since this will use the same memory that the boot loader
 
- ; already uses for its vector table. Great care will have to be taken if
 
- ; other addresses are to be used.
 
- ; 如果必要的话,复制应用程序的向量表到目标地址.
 
- ; 请注意,不正确的boot loader配置会破坏整个程序!设置VTABLE_START_ADDRESS为
 
- ; 0x2000 0000(从SRAM启动)也是可以的,因为这将和boot loader使用同样的内存
 
- ;
 
- if (_APP_START_ADDRESS != _VTABLE_START_ADDRESS) ;看应用程序的起始地址是否和应用程序的向量表存储地址相同
 
- movw r0, #(_VTABLE_START_ADDRESS & 0xffff)
 
- if (_VTABLE_START_ADDRESS > 0xffff)
 
- movt r0, #(_VTABLE_START_ADDRESS >> 16)
 
- endif
 
- movw r1, #(_APP_START_ADDRESS & 0xffff)
 
- if (_APP_START_ADDRESS > 0xffff)
 
- movt r1, #(_APP_START_ADDRESS >> 16)
 
- endif
 
 
- ;
 
- ; Calculate the end address of the vector table assuming that it has the
 
- ; maximum possible number of vectors. We don't know how many the app has
 
- ; populated so this is the safest approach though it may copy some non
 
- ; vector data if the app table is smaller than the maximum.
 
- ; 计算向量表的结束地址,假设向量表有最大数目. 我们不知道应用程序使用了多少
 
- ; 向量表,但这样是最安全的
 
- ;
 
- movw r2, #(70 * 4)
 
- adds r2, r2, r0
 
- VectorCopyLoop
 
- ldr r3, [r1], #4
 
- str r3, [r0], #4
 
- cmp r0, r2
 
- blt VectorCopyLoop
 
- endif
 
 
- ;
 
- ; Set the vector table address to the beginning of the application.
 
- ; 将向量表重定位到应用程序开始处
 
- ;
 
- movw r0, #(_VTABLE_START_ADDRESS & 0xffff)
 
- if (_VTABLE_START_ADDRESS > 0xffff)
 
- movt r0, #(_VTABLE_START_ADDRESS >> 16)
 
- endif
 
- movw r1, #(NVIC_VTABLE & 0xffff) ;向量表偏移寄存器
 
- movt r1, #(NVIC_VTABLE >> 16)
 
- str r0, [r1]
 
 
- ;
 
- ; Load the stack pointer from the application's vector table.
 
- ; 从应用程序向量表装载用户堆栈.
 
- ;
 
- if (_APP_START_ADDRESS != _VTABLE_START_ADDRESS)
 
- movw r0, #(_APP_START_ADDRESS & 0xffff)
 
- if (_APP_START_ADDRESS > 0xffff)
 
- movt r0, #(_APP_START_ADDRESS >> 16)
 
- endif
 
- endif
 
- ldr sp, [r0]
 
 
- ;
 
- ; Load the initial PC from the application's vector table and branch to
 
- ; the application's entry point.
 
- ;
 
- ldr r0, [r0, #4]
 
- bx r0
 
 
- ;******************************************************************************
 
- ;
 
- ; The update handler, which gets called when the application would like to
 
- ; start an update.
 
- ; 升级处理函数,当用户程序想要开始升级时,调用此函数
 
- ;
 
- ;******************************************************************************
 
- UpdateHandler_In_SRAM
 
- ;
 
- ; Load the stack pointer from the vector table.
 
- ; 从boot loader向量表中装载堆栈指针
 
- ;
 
- if :def:_FLASH_PATCH_COMPATIBLE
 
- movs r0, #0x1000
 
- else
 
- movs r0, #0x0000
 
- endif
 
- ldr sp, [r0]
 
 
- ;
 
- ; Call the user-supplied low level hardware initialization function
 
- ; if provided.
 
- ; 调用用户提供的底层硬件初始化函数
 
- ;
 
- if :def:_BL_HW_INIT_FN_HOOK
 
- bl $_BL_HW_INIT_FN_HOOK
 
- endif
 
 
- ;
 
- ; Call the user-supplied re-initialization function if provided.
 
- ; 调用用户提供的初始化函数
 
- ;
 
- if :def:_BL_REINIT_FN_HOOK
 
- import $_BL_REINIT_FN_HOOK
 
- bl $_BL_REINIT_FN_HOOK
 
- endif
 
 
- ;
 
- ; Branch to the update handler.
 
- ; 进入升级例程
 
- ;
 
- if :def:_ENET_ENABLE_UPDATE
 
- b UpdateBOOTP ;在bl_enet.c中
 
- elif :def:_CAN_ENABLE_UPDATE
 
- import AppUpdaterCAN
 
- b AppUpdaterCAN
 
- elif :def:_USB_ENABLE_UPDATE
 
- import AppUpdaterUSB
 
- b AppUpdaterUSB
 
- else
 
- b Updater
 
- endif
 
 
- ;******************************************************************************
 
- ;
 
- ; The NMI handler.
 
- ; NMI异常服务例程,处理主振荡器失败
 
- ;
 
- ;******************************************************************************
 
- if :def:_ENABLE_MOSCFAIL_HANDLER
 
- NmiSR_In_SRAM
 
- ;
 
- ; Restore the stack frame.
 
- ;
 
- mov lr, r12
 
- stm sp, {r4-r11}
 
 
- ;
 
- ; Save the link register.
 
- ;
 
- mov r9, lr
 
 
- ;
 
- ; Call the user-supplied low level hardware initialization function
 
- ; if provided.
 
- ;
 
- if :def:_BL_HW_INIT_FN_HOOK
 
- bl _BL_HW_INIT_FN_HOOK
 
- endif
 
 
- ;
 
- ; See if an update should be performed.
 
- ;
 
- bl CheckForceUpdate
 
- cbz r0, EnterApplication
 
 
- ;
 
- ; Clear the MOSCFAIL bit in RESC.
 
- ;
 
- movw r0, #(SYSCTL_RESC & 0xffff)
 
- movt r0, #(SYSCTL_RESC >> 16)
 
- ldr r1, [r0]
 
- bic r1, r1, #SYSCTL_RESC_MOSCFAIL
 
- str r1, [r0]
 
 
- ;
 
- ; Fix up the PC on the stack so that the boot pin check is bypassed
 
- ; (since it has already been performed).
 
- ;
 
- ldr r0, =EnterBootLoader
 
- bic r0, #0x00000001
 
- str r0, [sp, #0x18]
 
 
- ;
 
- ; Return from the NMI handler. This will then start execution of the
 
- ; boot loader.
 
- ;
 
- bx r9
 
 
- ;
 
- ; Restore the link register.
 
- ;
 
- EnterApplication
 
- mov lr, r9
 
 
- ;
 
- ; Copy the application's vector table to the target address if necessary.
 
- ; Note that incorrect boot loader configuration could cause this to
 
- ; corrupt the code! Setting VTABLE_START_ADDRESS to 0x20000000 (the start
 
- ; of SRAM) is safe since this will use the same memory that the boot loader
 
- ; already uses for its vector table. Great care will have to be taken if
 
- ; other addresses are to be used.
 
- ;
 
- if (_APP_START_ADDRESS != _VTABLE_START_ADDRESS)
 
- movw r0, #(_VTABLE_START_ADDRESS & 0xffff)
 
- if (_VTABLE_START_ADDRESS > 0xffff)
 
- movt r0, #(_VTABLE_START_ADDRESS >> 16)
 
- endif
 
- movw r1, #(_APP_START_ADDRESS & 0xffff)
 
- if (_APP_START_ADDRESS > 0xffff)
 
- movt r1, #(_APP_START_ADDRESS >> 16)
 
- endif
 
 
- ;
 
- ; Calculate the end address of the vector table assuming that it has the
 
- ; maximum possible number of vectors. We don't know how many the app has
 
- ; populated so this is the safest approach though it may copy some non
 
- ; vector data if the app table is smaller than the maximum.
 
- ;
 
- movw r2, #(70 * 4)
 
- adds r2, r2, r0
 
- VectorCopyLoop2
 
- ldr r3, [r1], #4
 
- str r3, [r0], #4
 
- cmp r0, r2
 
- blt VectorCopyLoop2
 
- endif
 
 
- ;
 
- ; Set the application's vector table start address. Typically this is the
 
- ; application start address but in some cases an application may relocate
 
- ; this so we can't assume that these two addresses are equal.
 
- ;
 
- movw r0, #(_VTABLE_START_ADDRESS & 0xffff)
 
- if (_VTABLE_START_ADDRESS > 0xffff)
 
- movt r0, #(_VTABLE_START_ADDRESS >> 16)
 
- endif
 
- movw r1, #(NVIC_VTABLE & 0xffff)
 
- movt r1, #(NVIC_VTABLE >> 16)
 
- str r0, [r1]
 
 
- ;
 
- ; Remove the NMI stack frame from the boot loader's stack.
 
- ;
 
- ldmia sp, {r4-r11}
 
 
- ;
 
- ; Get the application's stack pointer.
 
- ;
 
- if (_APP_START_ADDRESS != _VTABLE_START_ADDRESS)
 
- movw r0, #(_APP_START_ADDRESS & 0xffff)
 
- if (_APP_START_ADDRESS > 0xffff)
 
- movt r0, #(_APP_START_ADDRESS >> 16)
 
- endif
 
- endif
 
- ldr sp, [r0, #0x00]
 
 
- ;
 
- ; Fix up the NMI stack frame's return address to be the reset handler of
 
- ; the application.
 
- ;
 
- ldr r10, [r0, #0x04]
 
- bic r10, #0x00000001
 
 
- ;
 
- ; Store the NMI stack frame onto the application's stack.
 
- ;
 
- stmdb sp!, {r4-r11}
 
 
- ;
 
- ; Branch to the application's NMI handler.
 
- ;
 
- ldr r0, [r0, #0x08]
 
- bx r0
 
- endif
 
 
- ;******************************************************************************
 
- ;
 
- ; The default interrupt handler.
 
- ;
 
- ;******************************************************************************
 
- IntDefaultHandler
 
- ;
 
- ; Loop forever since there is nothing that we can do about an unexpected
 
- ; interrupt.
 
- ;
 
- b .
 
 
- ;******************************************************************************
 
- ;
 
- ; Provides a small delay. The loop below takes 3 cycles/loop.
 
- ; 提供一个小的延时函数. 循环一次需要3个时钟周期.
 
- ;
 
- ;******************************************************************************
 
- export Delay
 
- Delay
 
- subs r0, #1
 
- bne Delay
 
- bx lr
 
 
- ;******************************************************************************
 
- ;
 
- ; This is the end of the file.
 
- ;
 
- ;******************************************************************************
 
- align 4
 
- end