在ram中调试stm32程序,好处有3个: 其一:下载烧写速度快, 其二:再也不用担心会把flash给擦写到坏掉,如果碰到一个比较大一点嵌入式项目,烧写调试上千次是有可能的。但是不清楚芯片内部的flash是norflash还是slc类型的nandflash,总之,闪存芯片的擦写次数是有寿命限制的。 其三:可以更深入的理解芯片存储模型和启动机制。 同时,在ram中调试stm32程序,方式也有3个: 第一:在mdk开发环境中进入调试模式,通过载入一个初始化文件,内容如下: /*---------------------------------------------------------------------------- Setup() configure PC & SP for RAM Debug *----------------------------------------------------------------------------*/ FUNC void Setup (void) { SP = _RDWORD(0x20000000); // Setup Stack Pointer PC = _RDWORD(0x20000004); // Setup Program Counter _WDWORD(0xE000ED08, 0x20000000); // Setup Vector Table Offset Register } LOAD %L INCREMENTAL // load the application Setup(); // Setup for Running g, main 第二:通过芯片内置的bootloader程序和相关烧写工具(mcuisp),烧写完成后bootloader程序自动跳转dao相关内存地址开始执行新程序。但是bootloader烧写算法本身会消耗一定数量deram,需要根据不同芯片做出处理,主要是code烧写和中断向量表必须加上固定大小的偏移。 第三:自己编写一个引导程序烧写到flash中,每次重启芯片后固定从0x8000000地址处开始执行,然后再跳转到ram中的程序代码处执行。 主要有两个步骤,设置堆栈顶指针sp,然后再跳转到ResetHandler处执行。 因为cortexM3芯片的中断向量表示放在执行程序的最前面的,如下所示: __Vectors DCD __initial_sp ; Top of Stack 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 interrupt ( wwdg1_it) DCD PVD_AVD_IRQHandler ; PVD/AVD through EXTI Line detection DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line DCD FLASH_IRQHandler ; FLASH DCD RCC_IRQHandler ; RCC DCD EXTI0_IRQHandler ; EXTI Line0 DCD EXTI1_IRQHandler ; EXTI Line1 DCD EXTI2_IRQHandler ; EXTI Line2 DCD EXTI3_IRQHandler ; EXTI Line3 DCD EXTI4_IRQHandler ; EXTI Line4 DCD DMA1_Stream0_IRQHandler ; DMA1 Stream 0 DCD DMA1_Stream1_IRQHandler ; DMA1 Stream 1 DCD DMA1_Stream2_IRQHandler ; DMA1 Stream 2 DCD DMA1_Stream3_IRQHandler ; DMA1 Stream 3 DCD DMA1_Stream4_IRQHandler ; DMA1 Stream 4 DCD DMA1_Stream5_IRQHandler ; DMA1 Stream 5 DCD DMA1_Stream6_IRQHandler ; DMA1 Stream 6 DCD ADC_IRQHandler ; ADC1, ADC2 DCD FDCAN1_IT0_IRQHandler ; FDCAN1 interrupt line 0 DCD FDCAN2_IT0_IRQHandler ; FDCAN2 interrupt line 0 DCD FDCAN1_IT1_IRQHandler ; FDCAN1 interrupt line 1 DCD FDCAN2_IT1_IRQHandler ; FDCAN2 interrupt line 1 DCD EXTI9_5_IRQHandler ; External Line[9:5]s DCD TIM1_BRK_IRQHandler ; TIM1 Break interrupt DCD TIM1_UP_IRQHandler ; TIM1 Update Interrupt DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation Interrupt 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 ; External Line[15:10] DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line DCD 0 ; Reserved DCD TIM8_BRK_TIM12_IRQHandler ; TIM8 Break Interrupt and TIM12 global interrupt DCD TIM8_UP_TIM13_IRQHandler ; TIM8 Update Interrupt and TIM13 global interrupt DCD TIM8_TRG_COM_TIM14_IRQHandler ; TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare Interrupt DCD DMA1_Stream7_IRQHandler ; DMA1 Stream7 DCD FMC_IRQHandler ; FMC DCD SDMMC1_IRQHandler ; SDMMC1 DCD TIM5_IRQHandler ; TIM5 DCD SPI3_IRQHandler ; SPI3 DCD UART4_IRQHandler ; UART4 DCD UART5_IRQHandler ; UART5 DCD TIM6_DAC_IRQHandler ; TIM6 and DAC1&2 underrun errors DCD TIM7_IRQHandler ; TIM7 DCD DMA2_Stream0_IRQHandler ; DMA2 Stream 0 DCD DMA2_Stream1_IRQHandler ; DMA2 Stream 1 DCD DMA2_Stream2_IRQHandler ; DMA2 Stream 2 DCD DMA2_Stream3_IRQHandler ; DMA2 Stream 3 DCD DMA2_Stream4_IRQHandler ; DMA2 Stream 4 DCD ETH_IRQHandler ; Ethernet DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line DCD FDCAN_CAL_IRQHandler ; FDCAN calibration unit interrupt DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD DMA2_Stream5_IRQHandler ; DMA2 Stream 5 DCD DMA2_Stream6_IRQHandler ; DMA2 Stream 6 DCD DMA2_Stream7_IRQHandler ; DMA2 Stream 7 DCD USART6_IRQHandler ; USART6 DCD I2C3_EV_IRQHandler ; I2C3 event DCD I2C3_ER_IRQHandler ; I2C3 error DCD OTG_HS_EP1_OUT_IRQHandler ; USB OTG HS End Point 1 Out DCD OTG_HS_EP1_IN_IRQHandler ; USB OTG HS End Point 1 In DCD OTG_HS_WKUP_IRQHandler ; USB OTG HS Wakeup through EXTI DCD OTG_HS_IRQHandler ; USB OTG HS DCD DCMI_IRQHandler ; DCMI DCD 0 ; Reserved DCD RNG_IRQHandler ; Rng DCD FPU_IRQHandler ; FPU DCD UART7_IRQHandler ; UART7 DCD UART8_IRQHandler ; UART8 DCD SPI4_IRQHandler ; SPI4 DCD SPI5_IRQHandler ; SPI5 DCD SPI6_IRQHandler ; SPI6 DCD SAI1_IRQHandler ; SAI1 DCD LTDC_IRQHandler ; LTDC DCD LTDC_ER_IRQHandler ; LTDC error DCD DMA2D_IRQHandler ; DMA2D DCD SAI2_IRQHandler ; SAI2 DCD QUADSPI_IRQHandler ; QUADSPI DCD LPTIM1_IRQHandler ; LPTIM1 DCD CEC_IRQHandler ; HDMI_CEC DCD I2C4_EV_IRQHandler ; I2C4 Event DCD I2C4_ER_IRQHandler ; I2C4 Error DCD SPDIF_RX_IRQHandler ; SPDIF_RX DCD OTG_FS_EP1_OUT_IRQHandler ; USB OTG FS End Point 1 Out DCD OTG_FS_EP1_IN_IRQHandler ; USB OTG FS End Point 1 In DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI DCD OTG_FS_IRQHandler ; USB OTG FS DCD DMAMUX1_OVR_IRQHandler ; DMAMUX1 Overrun interrupt DCD HRTIM1_Master_IRQHandler ; HRTIM Master Timer global Interrupts DCD HRTIM1_TIMA_IRQHandler ; HRTIM Timer A global Interrupt DCD HRTIM1_TIMB_IRQHandler ; HRTIM Timer B global Interrupt DCD HRTIM1_TIMC_IRQHandler ; HRTIM Timer C global Interrupt DCD HRTIM1_TIMD_IRQHandler ; HRTIM Timer D global Interrupt DCD HRTIM1_TIME_IRQHandler ; HRTIM Timer E global Interrupt DCD HRTIM1_FLT_IRQHandler ; HRTIM Fault global Interrupt DCD DFSDM1_FLT0_IRQHandler ; DFSDM Filter0 Interrupt DCD DFSDM1_FLT1_IRQHandler ; DFSDM Filter1 Interrupt DCD DFSDM1_FLT2_IRQHandler ; DFSDM Filter2 Interrupt DCD DFSDM1_FLT3_IRQHandler ; DFSDM Filter3 Interrupt DCD SAI3_IRQHandler ; SAI3 global Interrupt DCD SWPMI1_IRQHandler ; Serial Wire Interface 1 global interrupt DCD TIM15_IRQHandler ; TIM15 global Interrupt DCD TIM16_IRQHandler ; TIM16 global Interrupt DCD TIM17_IRQHandler ; TIM17 global Interrupt DCD MDIOS_WKUP_IRQHandler ; MDIOS Wakeup Interrupt DCD MDIOS_IRQHandler ; MDIOS global Interrupt DCD JPEG_IRQHandler ; JPEG global Interrupt DCD MDMA_IRQHandler ; MDMA global Interrupt DCD 0 ; Reserved DCD SDMMC2_IRQHandler ; SDMMC2 global Interrupt DCD HSEM1_IRQHandler ; HSEM1 global Interrupt DCD 0 ; Reserved DCD ADC3_IRQHandler ; ADC3 global Interrupt DCD DMAMUX2_OVR_IRQHandler ; DMAMUX Overrun interrupt DCD BDMA_Channel0_IRQHandler ; BDMA Channel 0 global Interrupt DCD BDMA_Channel1_IRQHandler ; BDMA Channel 1 global Interrupt DCD BDMA_Channel2_IRQHandler ; BDMA Channel 2 global Interrupt DCD BDMA_Channel3_IRQHandler ; BDMA Channel 3 global Interrupt DCD BDMA_Channel4_IRQHandler ; BDMA Channel 4 global Interrupt DCD BDMA_Channel5_IRQHandler ; BDMA Channel 5 global Interrupt DCD BDMA_Channel6_IRQHandler ; BDMA Channel 6 global Interrupt DCD BDMA_Channel7_IRQHandler ; BDMA Channel 7 global Interrupt DCD COMP1_IRQHandler ; COMP1 global Interrupt DCD LPTIM2_IRQHandler ; LP TIM2 global interrupt DCD LPTIM3_IRQHandler ; LP TIM3 global interrupt DCD LPTIM4_IRQHandler ; LP TIM4 global interrupt DCD LPTIM5_IRQHandler ; LP TIM5 global interrupt DCD LPUART1_IRQHandler ; LP UART1 interrupt DCD 0 ; Reserved DCD CRS_IRQHandler ; Clock Recovery Global Interrupt DCD 0 ; Reserved DCD SAI4_IRQHandler ; SAI4 global interrupt DCD 0 ; Reserved DCD 0 ; Reserved DCD WAKEUP_PIN_IRQHandler ; Interrupt for all 6 wake-up pins __Vectors_End 主要需要注意第一行第二行, __Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler 每次芯片复位后,就从中断向量表的第一个位置处取出栈顶指针,然后设置到SP。 然后从第二个位置也就是Reset Handler中断向量里取出复位后PC的值,也就是下一步就跳转到Reset Handler所指示的地址处执行。 原理搞清楚了,程序代码就很简单了,如下所示: #define RAM_BOOT_ADDR 0X24000000 __asm void set_sp(unsigned int SP_addr) { mov R13, r0 BX LR ALIGN } Reset_Handler_addr=*((unsigned int*)(RAM_BOOT_ADDR+4)); set_sp(*((unsigned int*)RAM_BOOT_ADDR)); ((void(*)(void))Reset_Handler_addr)();//(*(void(*)(void))RAM_BOOT_ADDR)(); 是不是感觉跟前面mdk调试模式中的初始化文件机制很相似啊?他们根本就是一样的,因为这本来就是由cortexM3的存储模型和启动机制决定的。
|
|