成功修改STM32启动程序(自定义的分散加载模式)

2019-08-20 18:25发布

原子的开发板,用跑马灯程序的工程来改的,DOWNLOAD和DEBUG效果都能跑起来,当然这只是用个简单小程序试试,我也就抛砖引玉,了解MDK启动代码的前辈也来讨论讨论最好。

话说启动代码,没什么神秘的,往简单里说不外乎3个功能部分
1,做个AREA放置向量表,异常/中断跳转的地址表。
2,初始化SP的值,初始化内核的状态(比如工作在用户模式或超级模式,STM启动默认在高权限模式)
3,如果使用的是简单的分散加载,IMAGE(映像文件)也就由1个RO,1个RW,1个ZI组成,并且RO的load region和execution region相同,那么只需要COPY RW区到RAM,然后再RW区后面创建ZI区,只部分可以用汇编代码自己实现。当然库里的__main函数就包含这些功能,但是如果不用__main,那就要自己写这部分了。

何为简单的分散加载?


MDK的HELP文档里有很详细的说明。

首先编译器设置要改

要是勾了,编译器要报错,问你启动库函数找不到。

勾了就是使用默认的分散加载描述文本,.SCT文件是不让改的,所以想改就不要勾。

贴上启动代码,我用红字做解释,后面有附近下载的。

    IMPORT |Image$$ER_IROM1$$RO$$Base|
    IMPORT |Image$$ER_IROM1$$RO$$Limit|
    
    IMPORT |Image$$RW_IRAM1$$RW$$Base|
    IMPORT |Image$$RW_IRAM1$$RW$$Limit|
    
    IMPORT |Image$$RW_IRAM1$$ZI$$Base|
    IMPORT |Image$$RW_IRAM1$$ZI$$Limit|

上面这几个符号并不神秘,他们是编译器根据分散加载描述文本产生的全局标号,在.MAP文件里能找到他们对应的值,因此我们可以用IMPORT来引用他们,注意名字不能乱起,这个是根据你的.SCT文件产生的标号

LR_IROM1 0x08000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   * (+RO)
  }
  RW_IRAM1 0x20000000 0x00005000  {  ; RW data
   * (+RW +ZI)
  }
}

这就是我的.SCT文本 记得MDK原.SCT文本里含有 *(InRoot$$Sections)  一定要删掉 这个是根段,有很多启动库函数包在里面的



                THUMB ; Vector Table Mapped to Address 0 at Reset                 AREA    RESET, CODE, READONLY Vectors         DCD     0x20005000                ; Top of Stack      我就直接赋值给SP了
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler         ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     MemManage_Handler         ; MPU Fault Handler
                DCD     BusFault_Handler          ; Bus Fault Handler
                DCD     UsageFault_Handler        ; Usage Fault Handler
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     SVC_Handler               ; SVCall Handler
                DCD     DebugMon_Handler          ; Debug Monitor Handler
                DCD     0                         ; Reserved
                DCD     PendSV_Handler            ; PendSV Handler
                DCD     SysTick_Handler           ; SysTick Handler                 ; External Interrupts
                DCD     WWDG_IRQHandler           ; Window Watchdog
                DCD     PVD_IRQHandler            ; PVD through EXTI Line detect
                DCD     TAMPER_IRQHandler         ; Tamper
                DCD     RTC_IRQHandler            ; RTC
                DCD     FLASH_IRQHandler          ; Flash
                DCD     RCC_IRQHandler            ; RCC
                DCD     EXTI0_IRQHandler          ; EXTI Line 0
                DCD     EXTI1_IRQHandler          ; EXTI Line 1
                DCD     EXTI2_IRQHandler          ; EXTI Line 2
                DCD     EXTI3_IRQHandler          ; EXTI Line 3
                DCD     EXTI4_IRQHandler          ; EXTI Line 4
                DCD     DMAChannel1_IRQHandler    ; DMA Channel 1
                DCD     DMAChannel2_IRQHandler    ; DMA Channel 2
                DCD     DMAChannel3_IRQHandler    ; DMA Channel 3
                DCD     DMAChannel4_IRQHandler    ; DMA Channel 4
                DCD     DMAChannel5_IRQHandler    ; DMA Channel 5
                DCD     DMAChannel6_IRQHandler    ; DMA Channel 6
                DCD     DMAChannel7_IRQHandler    ; DMA Channel 7
                DCD     ADC_IRQHandler            ; ADC
                DCD     USB_HP_CAN_TX_IRQHandler  ; USB High Priority or CAN TX
                DCD     USB_LP_CAN_RX0_IRQHandler ; USB Low  Priority or CAN RX0
                DCD     CAN_RX1_IRQHandler        ; CAN RX1
                DCD     CAN_SCE_IRQHandler        ; CAN SCE
                DCD     EXTI9_5_IRQHandler        ; EXTI Line 9..5
                DCD     TIM1_BRK_IRQHandler       ; TIM1 Break
                DCD     TIM1_UP_IRQHandler        ; TIM1 Update
                DCD     TIM1_TRG_COM_IRQHandler   ; TIM1 Trigger and Commutation
                DCD     TIM1_CC_IRQHandler        ; TIM1 Capture Compare
                DCD     TIM2_IRQHandler           ; TIM2
                DCD     TIM3_IRQHandler           ; TIM3
                DCD     TIM4_IRQHandler           ; TIM4
                DCD     I2C1_EV_IRQHandler        ; I2C1 Event
                DCD     I2C1_ER_IRQHandler        ; I2C1 Error
                DCD     I2C2_EV_IRQHandler        ; I2C2 Event
                DCD     I2C2_ER_IRQHandler        ; I2C2 Error
                DCD     SPI1_IRQHandler           ; SPI1
                DCD     SPI2_IRQHandler           ; SPI2
                DCD     USART1_IRQHandler         ; USART1
                DCD     USART2_IRQHandler         ; USART2
                DCD     USART3_IRQHandler         ; USART3
                DCD     EXTI15_10_IRQHandler      ; EXTI Line 15..10
                DCD     RTCAlarm_IRQHandler       ; RTC Alarm through EXTI Line
                DCD     USBWakeUp_IRQHandler      ; USB Wakeup from suspend   ; Reset Handler Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  main
    
                LDR  r0,  =|Image$$ER_IROM1$$RO$$Limit|
                LDR  r1,  =|Image$$RW_IRAM1$$RW$$Base|
                LDR  r3,  =|Image$$RW_IRAM1$$ZI$$Base|
Init_RW  
               CMP  r1,  r3
               LDRCC r2,  [r0],#4
               STRCC r2,  [r1],#4
               BCC  Init_RW
  
               LDR  r1,  =|Image$$RW_IRAM1$$ZI$$Limit|
              MOV  r2,  #0
Init_ZI  
               CMP  r3,  r1
              STRCC r2,  [r3],#4
               BCC  Init_ZI

上面的粗体就是自己写的 COPY RW区和创建ZI区的汇编代码,其实是我从ADS1.2下的S3C44B0X启动程序改过来的,大体不变,
那几个标号 
 =|Image$$ER_IROM1$$RO$$Limit|
 =|Image$$RW_IRAM1$$RW$$Base|
=|Image$$RW_IRAM1$$ZI$$Base|
 =|Image$$RW_IRAM1$$ZI$$Limit|

是什么意思,怎么用?这个我就不多解释了吧,.MAP文件里有他们的真相,HELP文档里也有他们的详细解释。
    
    
                LDR     R0, =main
                BX      R0
                ENDP
; Dummy Exception Handlers (infinite loops which can be modified)                NMI_Handler     PROC
                EXPORT  NMI_Handler               [WEAK]
                B       .
                ENDP
HardFault_Handler
                PROC
                EXPORT  HardFault_Handler         [WEAK]
                B       .
                ENDP
MemManage_Handler
                PROC
                EXPORT  MemManage_Handler         [WEAK]
                B       .
                ENDP
BusFault_Handler
                PROC
                EXPORT  BusFault_Handler          [WEAK]
                B       .
                ENDP
UsageFault_Handler
                PROC
                EXPORT  UsageFault_Handler        [WEAK]
                B       .
                ENDP
SVC_Handler     PROC
                EXPORT  SVC_Handler               [WEAK]
                B       .
                ENDP
DebugMon_Handler
                PROC
                EXPORT  DebugMon_Handler          [WEAK]
                B       .
                ENDP
PendSV_Handler  PROC
                EXPORT  PendSV_Handler            [WEAK]
                B       .
                ENDP
SysTick_Handler PROC
                EXPORT  SysTick_Handler           [WEAK]
                B       .
                ENDP Default_Handler PROC                 EXPORT  WWDG_IRQHandler           [WEAK]
                EXPORT  PVD_IRQHandler            [WEAK]
                EXPORT  TAMPER_IRQHandler         [WEAK]
                EXPORT  RTC_IRQHandler            [WEAK]
                EXPORT  FLASH_IRQHandler          [WEAK]
                EXPORT  RCC_IRQHandler            [WEAK]
                EXPORT  EXTI0_IRQHandler          [WEAK]
                EXPORT  EXTI1_IRQHandler          [WEAK]
                EXPORT  EXTI2_IRQHandler          [WEAK]
                EXPORT  EXTI3_IRQHandler          [WEAK]
                EXPORT  EXTI4_IRQHandler          [WEAK]
                EXPORT  DMAChannel1_IRQHandler    [WEAK]
                EXPORT  DMAChannel2_IRQHandler    [WEAK]
                EXPORT  DMAChannel3_IRQHandler    [WEAK]
                EXPORT  DMAChannel4_IRQHandler    [WEAK]
                EXPORT  DMAChannel5_IRQHandler    [WEAK]
                EXPORT  DMAChannel6_IRQHandler    [WEAK]
                EXPORT  DMAChannel7_IRQHandler    [WEAK]
                EXPORT  ADC_IRQHandler            [WEAK]
                EXPORT  USB_HP_CAN_TX_IRQHandler  [WEAK]
                EXPORT  USB_LP_CAN_RX0_IRQHandler [WEAK]
                EXPORT  CAN_RX1_IRQHandler        [WEAK]
                EXPORT  CAN_SCE_IRQHandler        [WEAK]
                EXPORT  EXTI9_5_IRQHandler        [WEAK]
                EXPORT  TIM1_BRK_IRQHandler       [WEAK]
                EXPORT  TIM1_UP_IRQHandler        [WEAK]
                EXPORT  TIM1_TRG_COM_IRQHandler   [WEAK]
                EXPORT  TIM1_CC_IRQHandler        [WEAK]
                EXPORT  TIM2_IRQHandler           [WEAK]
                EXPORT  TIM3_IRQHandler           [WEAK]
                EXPORT  TIM4_IRQHandler           [WEAK]
                EXPORT  I2C1_EV_IRQHandler        [WEAK]
                EXPORT  I2C1_ER_IRQHandler        [WEAK]
                EXPORT  I2C2_EV_IRQHandler        [WEAK]
                EXPORT  I2C2_ER_IRQHandler        [WEAK]
                EXPORT  SPI1_IRQHandler           [WEAK]
                EXPORT  SPI2_IRQHandler           [WEAK]
                EXPORT  USART1_IRQHandler         [WEAK]
                EXPORT  USART2_IRQHandler         [WEAK]
                EXPORT  USART3_IRQHandler         [WEAK]
                EXPORT  EXTI15_10_IRQHandler      [WEAK]
                EXPORT  RTCAlarm_IRQHandler       [WEAK]
                EXPORT  USBWakeUp_IRQHandler      [WEAK] WWDG_IRQHandler
PVD_IRQHandler
TAMPER_IRQHandler
RTC_IRQHandler
FLASH_IRQHandler
RCC_IRQHandler
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
DMAChannel1_IRQHandler
DMAChannel2_IRQHandler
DMAChannel3_IRQHandler
DMAChannel4_IRQHandler
DMAChannel5_IRQHandler
DMAChannel6_IRQHandler
DMAChannel7_IRQHandler
ADC_IRQHandler
USB_HP_CAN_TX_IRQHandler
USB_LP_CAN_RX0_IRQHandler
CAN_RX1_IRQHandler
CAN_SCE_IRQHandler
EXTI9_5_IRQHandler
TIM1_BRK_IRQHandler
TIM1_UP_IRQHandler
TIM1_TRG_COM_IRQHandler
TIM1_CC_IRQHandler
TIM2_IRQHandler
TIM3_IRQHandler
TIM4_IRQHandler
I2C1_EV_IRQHandler
I2C1_ER_IRQHandler
I2C2_EV_IRQHandler
I2C2_ER_IRQHandler
SPI1_IRQHandler
SPI2_IRQHandler
USART1_IRQHandler
USART2_IRQHandler
USART3_IRQHandler
EXTI15_10_IRQHandler
RTCAlarm_IRQHandler
USBWakeUp_IRQHandler                 B       .                 ENDP
                ALIGN  
                END

后面都没什么改动了,删掉了MDK的库函数,总之原版的向量表我是不敢动的


用原子的跑马灯试验试了下,OK,没问题,只是有个小纠结,看看.MAP文件里

MDK啊 你妹的还要坑我96字节啊。






友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
11条回答
justin_1ee
2019-08-21 12:38
回复【5楼】正点原子:
---------------------------------
原子哥,编译时Error: L6220E: Execution region RW_IRAM1 size (163092 bytes) exceeds limit (97280 bytes). Region contains 19 bytes of padding and 0 bytes of veneers (total 19 bytes of linker generated content).


RAM超了,如果代码不能再优化了,也不加RAM了,有什么办法解决吗,,楼主的这个办法可以解决这个问题吗?

一周热门 更多>