У меня есть простая голая программа для ARM-чипа STM32F103 (я использую набор инструментов GNU и отладчик openocd).
Когда я запускаю его из ОЗУ, он работает нормально.Когда я загружаю микросхему с помощью предустановленного загрузчика и сразу перепрыгиваю на Reset_Handler
, он тоже работает.Но когда я пытаюсь загрузиться с Flash, процессор переходит в режим HardFault.
Сразу после сброса процессора регистр pc
указывает на местоположение Reset_Handler
.Когда я делаю шаг, если попадает в Hardfault_Handler
.
Почему это происходит?Я подозреваю, что это плохой доступ к памяти, но все, кажется, выровнено.
Код сборки:
.syntax unified
.cpu cortex-m3
.arch armv7-m
.fpu softvfp
.thumb
.section .text
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.align 4
Reset_Handler:
mov r0, #0
mov r1, #0
mov r2, #0
b Reset_Handler
.section .vector,"a",%progbits
.type Vectors, %object
.size Vectors, .-Vectors
Vectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word MemManage_Handler
.word BusFault_Handler
.word UsageFault_Handler
.word 0
.word 0
.word 0
.word 0
.word SVC_Handler
.word DebugMon_Handler
.word 0
.word PendSV_Handler
.word SysTick_Handler
.word WWDG_IRQHandler
.word PVD_IRQHandler
.word TAMPER_IRQHandler
.word RTC_IRQHandler
.word FLASH_IRQHandler
.word RCC_IRQHandler
.word EXTI0_IRQHandler
.word EXTI1_IRQHandler
.word EXTI2_IRQHandler
.word EXTI3_IRQHandler
.word EXTI4_IRQHandler
.word DMA1_Channel1_IRQHandler
.word DMA1_Channel2_IRQHandler
.word DMA1_Channel3_IRQHandler
.word DMA1_Channel4_IRQHandler
.word DMA1_Channel5_IRQHandler
.word DMA1_Channel6_IRQHandler
.word DMA1_Channel7_IRQHandler
.word ADC1_2_IRQHandler
.word USB_HP_CAN1_TX_IRQHandler
.word USB_LP_CAN1_RX0_IRQHandler
.word CAN1_RX1_IRQHandler
.word CAN1_SCE_IRQHandler
.word EXTI9_5_IRQHandler
.word TIM1_BRK_IRQHandler
.word TIM1_UP_IRQHandler
.word TIM1_TRG_COM_IRQHandler
.word TIM1_CC_IRQHandler
.word TIM2_IRQHandler
.word TIM3_IRQHandler
.word 0
.word I2C1_EV_IRQHandler
.word I2C1_ER_IRQHandler
.word 0
.word 0
.word SPI1_IRQHandler
.word 0
.word USART1_IRQHandler
.word USART2_IRQHandler
.word 0
.word EXTI15_10_IRQHandler
.word RTC_Alarm_IRQHandler
.word USBWakeUp_IRQHandler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
b Reset_Handler
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak MemManage_Handler
.thumb_set MemManage_Handler,Default_Handler
.weak BusFault_Handler
.thumb_set BusFault_Handler,Default_Handler
.weak UsageFault_Handler
.thumb_set UsageFault_Handler,Default_Handler
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak DebugMon_Handler
.thumb_set DebugMon_Handler,Default_Handler
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak WWDG_IRQHandler
.thumb_set WWDG_IRQHandler,Default_Handler
.weak PVD_IRQHandler
.thumb_set PVD_IRQHandler,Default_Handler
.weak TAMPER_IRQHandler
.thumb_set TAMPER_IRQHandler,Default_Handler
.weak RTC_IRQHandler
.thumb_set RTC_IRQHandler,Default_Handler
.weak FLASH_IRQHandler
.thumb_set FLASH_IRQHandler,Default_Handler
.weak RCC_IRQHandler
.thumb_set RCC_IRQHandler,Default_Handler
.weak EXTI0_IRQHandler
.thumb_set EXTI0_IRQHandler,Default_Handler
.weak EXTI1_IRQHandler
.thumb_set EXTI1_IRQHandler,Default_Handler
.weak EXTI2_IRQHandler
.thumb_set EXTI2_IRQHandler,Default_Handler
.weak EXTI3_IRQHandler
.thumb_set EXTI3_IRQHandler,Default_Handler
.weak EXTI4_IRQHandler
.thumb_set EXTI4_IRQHandler,Default_Handler
.weak DMA1_Channel1_IRQHandler
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
.weak DMA1_Channel2_IRQHandler
.thumb_set DMA1_Channel2_IRQHandler,Default_Handler
.weak DMA1_Channel3_IRQHandler
.thumb_set DMA1_Channel3_IRQHandler,Default_Handler
.weak DMA1_Channel4_IRQHandler
.thumb_set DMA1_Channel4_IRQHandler,Default_Handler
.weak DMA1_Channel5_IRQHandler
.thumb_set DMA1_Channel5_IRQHandler,Default_Handler
.weak DMA1_Channel6_IRQHandler
.thumb_set DMA1_Channel6_IRQHandler,Default_Handler
.weak DMA1_Channel7_IRQHandler
.thumb_set DMA1_Channel7_IRQHandler,Default_Handler
.weak ADC1_2_IRQHandler
.thumb_set ADC1_2_IRQHandler,Default_Handler
.weak USB_HP_CAN1_TX_IRQHandler
.thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
.weak USB_LP_CAN1_RX0_IRQHandler
.thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
.weak CAN1_RX1_IRQHandler
.thumb_set CAN1_RX1_IRQHandler,Default_Handler
.weak CAN1_SCE_IRQHandler
.thumb_set CAN1_SCE_IRQHandler,Default_Handler
.weak EXTI9_5_IRQHandler
.thumb_set EXTI9_5_IRQHandler,Default_Handler
.weak TIM1_BRK_IRQHandler
.thumb_set TIM1_BRK_IRQHandler,Default_Handler
.weak TIM1_UP_IRQHandler
.thumb_set TIM1_UP_IRQHandler,Default_Handler
.weak TIM1_TRG_COM_IRQHandler
.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
.weak TIM1_CC_IRQHandler
.thumb_set TIM1_CC_IRQHandler,Default_Handler
.weak TIM2_IRQHandler
.thumb_set TIM2_IRQHandler,Default_Handler
.weak TIM3_IRQHandler
.thumb_set TIM3_IRQHandler,Default_Handler
.weak I2C1_EV_IRQHandler
.thumb_set I2C1_EV_IRQHandler,Default_Handler
.weak I2C1_ER_IRQHandler
.thumb_set I2C1_ER_IRQHandler,Default_Handler
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
.weak USART2_IRQHandler
.thumb_set USART2_IRQHandler,Default_Handler
.weak EXTI15_10_IRQHandler
.thumb_set EXTI15_10_IRQHandler,Default_Handler
.weak RTC_Alarm_IRQHandler
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
.weak USBWakeUp_IRQHandler
.thumb_set USBWakeUp_IRQHandler,Default_Handler
.end
Сценарий компоновщика ОЗУ:
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
MEMORY {
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 20k
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64k
}
_estack = 0x20004FFF;
SECTIONS {
.isr_vector : {
. = ALIGN(4);
KEEP(*(.vector))
. = ALIGN(8);
} > RAM
.text : {
. = ALIGN(4);
*(.text)
} > RAM
}
Сценарий компоновщика Flash:
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
MEMORY {
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 20k
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64k
}
_estack = 0x20004FFF;
SECTIONS {
.isr_vector : {
. = ALIGN(4);
KEEP(*(.vector))
. = ALIGN(8);
} > FLASH
.text : {
. = ALIGN(4);
*(.text)
} > FLASH
}
Разборка секции .text
:
08000110 <ADC1_2_IRQHandler>:
8000110: e7fe b.n 8000110 <ADC1_2_IRQHandler>
8000112: bf00 nop
8000114: f3af 8000 nop.w
8000118: f3af 8000 nop.w
800011c: f3af 8000 nop.w
08000120 <Reset_Handler>:
8000120: f04f 0000 mov.w r0, #0
8000124: f04f 0100 mov.w r1, #0
8000128: f04f 0200 mov.w r2, #0
800012c: e7f8 b.n 8000120 <Reset_Handler>
800012e: bf00 nop
Разборка секции .isr_vector
(частично):
08000000 <Vectors>:
8000000: 20004fff strdcs r4, [r0], -pc ; <UNPREDICTABLE>
8000004: 08000120 stmdaeq r0, {r5, r8}
8000008: 08000111 stmdaeq r0, {r0, r4, r8}
800000c: 08000111 stmdaeq r0, {r0, r4, r8}
8000010: 08000111 stmdaeq r0, {r0, r4, r8}
...
8000108: 08000111 stmdaeq r0, {r0, r4, r8}
800010c: 00000000 andeq r0, r0, r0