STM32F4xx/2xx/1xx的实现
设置寄存器VTOR来设置中断向量表的位置
typedef struct
{
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
__IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)
{
/* Check the parameters */
assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
assert_param(IS_NVIC_OFFSET(Offset));
SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
}
#define VECT_TAB_OFFSET XXXX
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
修改sct
LR_IROM1 0x08020000 0x00080000 { ; load region size_region
ER_IROM1 0x08020000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
STM32F0xx的实现
由于没有VTOR
__IO uint32_t VectorTable[48] __attribute__((at(0X20000000)));
#define SYSCFG_MemoryRemap_SRAM ((uint8_t)0x03)
void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap)
{
uint32_t tmpctrl = 0;
/* Check the parameter */
assert_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap));
/* Get CFGR1 register value */
tmpctrl = SYSCFG->CFGR1;
/* Clear MEM_MODE bits */
tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);
/* Set the new MEM_MODE bits value */
tmpctrl |= (uint32_t) SYSCFG_MemoryRemap;
/* Set CFGR1 register with the new memory remap configuration */
SYSCFG->CFGR1 = tmpctrl;
}
uint32_t i = 0;
for(i = 0; i < 48; i++)
{
VectorTable
= *(__IO uint32_t*)((FLASH_BASE | VECT_TAB_OFFSET) + (i<<2));
}
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
修改SRAM的起始地址及长度
LR_IROM1 0x08003000 0x000e000 { ; load region size_region
ER_IROM1 0x08003000 0x000e000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x200000C0 0x00003F40 { ; RW data
.ANY (+RW +ZI)
}
}
bootloader中跳转
#define ApplicationAddress 0x8004000
typedef void (*pFunction)(void);
pFunction JumpToApplication;
uint32_t m_JumpAddress;
static void JumpToApp(void)
{
if (((*(uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
{
DBG("rnJump to Application !rn");
/* Jump to user application */
m_JumpAddress = *(uint32_t*) (ApplicationAddress + 4); //应用程序起始地址偏移4,为reset中断服务程序地址
JumpToApplication = (pFunction) m_JumpAddress; //将reset中断服务程序地址转换为函数指针
/* Initialize user application's Stack Pointer */
__set_MSP(*(uint32_t*) ApplicationAddress);
JumpToApplication();
}else{
DBG("not find APPlication...");
}
第一个4bytes是栈顶指针
第二个4bytes是 reset程序地址
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD WWDG_IRQHandler ; Window Watchdog
DCD PVD_VDDIO2_IRQHandler ; PVD through EXTI Line detect
DCD RTC_IRQHandler ; RTC through EXTI Line
DCD FLASH_IRQHandler ; FLASH
.....
; Reset handler routine
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
STM32F4xx/2xx/1xx的实现
设置寄存器VTOR来设置中断向量表的位置
typedef struct
{
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
__IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)
{
/* Check the parameters */
assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
assert_param(IS_NVIC_OFFSET(Offset));
SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
}
#define VECT_TAB_OFFSET XXXX
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
修改sct
LR_IROM1 0x08020000 0x00080000 { ; load region size_region
ER_IROM1 0x08020000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
STM32F0xx的实现
由于没有VTOR
__IO uint32_t VectorTable[48] __attribute__((at(0X20000000)));
#define SYSCFG_MemoryRemap_SRAM ((uint8_t)0x03)
void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap)
{
uint32_t tmpctrl = 0;
/* Check the parameter */
assert_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap));
/* Get CFGR1 register value */
tmpctrl = SYSCFG->CFGR1;
/* Clear MEM_MODE bits */
tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);
/* Set the new MEM_MODE bits value */
tmpctrl |= (uint32_t) SYSCFG_MemoryRemap;
/* Set CFGR1 register with the new memory remap configuration */
SYSCFG->CFGR1 = tmpctrl;
}
uint32_t i = 0;
for(i = 0; i < 48; i++)
{
VectorTable = *(__IO uint32_t*)((FLASH_BASE | VECT_TAB_OFFSET) + (i<<2));
}
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
修改SRAM的起始地址及长度
LR_IROM1 0x08003000 0x000e000 { ; load region size_region
ER_IROM1 0x08003000 0x000e000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x200000C0 0x00003F40 { ; RW data
.ANY (+RW +ZI)
}
}
bootloader中跳转
#define ApplicationAddress 0x8004000
typedef void (*pFunction)(void);
pFunction JumpToApplication;
uint32_t m_JumpAddress;
static void JumpToApp(void)
{
if (((*(uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
{
DBG("rnJump to Application !rn");
/* Jump to user application */
m_JumpAddress = *(uint32_t*) (ApplicationAddress + 4); //应用程序起始地址偏移4,为reset中断服务程序地址
JumpToApplication = (pFunction) m_JumpAddress; //将reset中断服务程序地址转换为函数指针
/* Initialize user application's Stack Pointer */
__set_MSP(*(uint32_t*) ApplicationAddress);
JumpToApplication();
}else{
DBG("not find APPlication...");
}
第一个4bytes是栈顶指针
第二个4bytes是 reset程序地址
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD WWDG_IRQHandler ; Window Watchdog
DCD PVD_VDDIO2_IRQHandler ; PVD through EXTI Line detect
DCD RTC_IRQHandler ; RTC through EXTI Line
DCD FLASH_IRQHandler ; FLASH
.....
; Reset handler routine
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
举报