typedef void (*user_code_pointer_type)(void); void run_user_code(void){ user_code_pointer_type user_code_entry; //user_code_entry = (user_code_pointer_type)((uint32_t*)(user_start_sector_address + 4));//causes invstate at 0x6004 user_code_entry = (user_code_pointer_type)(user_start_sector_address|1);//causes impreciserr at 0x6006 //user_code_entry = (user_code_pointer_type)(user_start_sector_address);//causes invstate at 0x6000 //NVIC_SetVTOR(user_start_sector_address);//hardfault handler of user code is called instead (user_code_entry)(); } |
SCB->VTOR = _vector_table_location & 0x3FFFFC00; |
#if (_vector_table_location)&(1024-1) #error vector table not properly aligned #endif __disable_irq();//no interrupt should be enabled by bootloader, but disable interrupts to be on safe side SCB->VTOR = _vector_table_location; __enable_irq(); |
SCB->VTOR = _vector_table_location & 0x3FFFFF80; |
SCB->VTOR = _vector_table_location & 0x3FFFFC00; |
typedef struct{ uint32_t stack_address; //initial value of stack pointer is stored at top of vector table void (*reset_address)(void); //reset vector with entry address is located at second 32-bit word }vector_table_layout; void run_user_code(void){ vector_table_layout const*const user_vector_table=(vector_table_layout*)user_start_sector_address; __disable_irq(); //no interrupt should be enabled by bootloader, but disable interrupts to be on safe side NVIC_SetVTOR(user_start_sector_address); //set vector table offset to user code __enable_irq(); __set_MSP(user_vector_table->stack_address);//load stackpointer with initial value (user_vector_table->reset_address)(); //call user code } |
#else //SCB->VTOR = 0x00000000 & 0x3FFFFF80; //loads incorrect address in case user code has an offset __disable_irq();//no interrupt should be enabled by bootloader, but disable interrupts to be on safe side SCB->VTOR = _vector_table_location & 0x3FFFFF80; __enable_irq(); #endif |
user_code_entry = (user_code_pointer_type)((uint32_t*)(user_start_sector_address + 4));//causes invstate at 0x6004 |
#include < stdint.h > #include "LPC177x_8x.h" #define user_start_sector_address 0x06000 typedef void (*user_code_pointer_type)(void); void run_user_code(void){ uint32_t user_stack_pointer; user_code_pointer_type user_code_entry; user_code_entry = (user_code_pointer_type)((uint32_t*)(user_start_sector_address + 4));//causes invstate at 0x6004 //user_code_entry = (user_code_pointer_type)(user_start_sector_address|1);//causes impreciserr at 0x6006 //user_code_entry = (user_code_pointer_type)(user_start_sector_address);//causes invstate at 0x6000 //NVIC_SetVTOR(user_start_sector_address);//hardfault handler of user code is called instead user_stack_pointer=*((uint32_t*)user_start_sector_address);//initial value of stack pointer is stored at top of vector table __set_MSP(user_stack_pointer); (user_code_entry)(); } int main(void){ run_user_code(); while(1); } |
typedef void (*user_code_pointer_type)(void); void run_user_code(void){ uint32_t initial_sp = *(uint32_t*)(user_start_sector_address + 0); user_code_pointer_type user_code_entry = (user_code_pointer_type)(*(uint32_t*)(user_start_sector_address + 4)); NVIC_SetVTOR(user_start_sector_address); __set_MSP (initial_sp); (user_code_entry)(); } |