我正在使用Cortex-M0 +处理ATSAMC21(ATSAMC21J18A),制作我的CAN bootloader。我的IDE是ATMEL工作室。 闪烁我的应用程序是好的,但是当我跳入i时,它失败了。(我尝试使用调试而没有) 在dissaseembly中,它指向这两行中的第一行:
*FFFFFFFE ?? ?? ??? Memory out of bounds or read error*
*00000000 a0.32 adds r2, #160*
我的链接器中的我的引导程序空间:
MEMORY
{
rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00008000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
我的链接器中的应用程序(或固件)空间:
MEMORY
{
rom (rx) : ORIGIN = 0x00010000, LENGTH = 0x00030000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
跳跃之前,
我禁用了irq中断,定义了我的入口点和我的堆栈指针,并改变了VTOR。 这是我要跳的代码:
void JumpToApp(void) {
uint16_t i;
uint32_t startAddress, applicationStack;
/* Check if WDT is locked */
if (!(WDT->CTRLA.reg & WDT_CTRLA_ALWAYSON)) {
/* Disable the Watchdog module */
WDT->CTRLA.reg &= ~WDT_CTRLA_ENABLE;
}
//stop general IT
__disable_irq();
// Disable SysTick
SysTick->CTRL = 0;
// Disable IRQs & clear pending IRQs
for (i = 0; i < 8; i++) {
NVIC->ICER[i] = 0xFFFFFFFF;
NVIC->ICPR[i] = 0xFFFFFFFF;
}
// Pointer to the Application Section
void (*application_code_entry)(void);
startAddress = FLASH_APP_VADRESS; //HERE 0x00010000, my start App
applicationStack = (uint32_t) *(volatile unsigned int*) (startAddress);
application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)(FLASH_APP_VADRESS + 4)); //HERE 0x00010004
// Rebase the Stack Pointer
__DSB();
__ISB();
__set_MSP(*(uint32_t *)applicationStack); //HERE 0x00010000, my start App
// Rebase the vector table base address
SCB->VTOR = ((uint32_t)startAddress & SCB_VTOR_TBLOFF_Msk);
__DSB();
__ISB();
// Jump to user Reset Handler in the application
application_code_entry();
}
我试图在我的application_code_entry上添加+1,就像一个奇怪的Thumb模式,我看到这个用于Cortex-M3,但它不起作用,在一般IT中失败。
然后我通过main_boot()重命名main() 和Reset_Handler()通过Reset_Handler_Boot()(并通过更改propety标志链接器--entry = Reset_Handler_Boot)
但仍然没有跳跃。
我不知道我做得不好。可能有一个长跳吗? 拆分内存? 如果有人有想法?
谢谢!!!!!!!!!!!!!!!!!!!
谢谢,(这是一个错误:))但是这个硬错误并没有解决我的跳转(事实上我直接使用了地址__set_MSP(*(uint32_t *)(FLASH_APP_VADRESS));
我的MSP不是0x0000000,它是0x20003240所以它是否适用于我的新MSP? (见图片链接)
这是我测试MSP的代码
ReadMsp=__get_MSP(); //result 0x20003240, before change it
__DSB();
__ISB();
__set_MSP(*(uint32_t *)applicationStack);
// Rebase the vector table base address TODO: use RAM
SCB->VTOR = ((uint32_t)startAddress & SCB_VTOR_TBLOFF_Msk);
__DSB();
__ISB();
ReadMsp=__get_MSP(); //result is 0xFFFFFFFC , why ???
__DSB();
__ISB();
__set_MSP(0x00010000);
__DSB();
__ISB();
ReadMsp=__get_MSP(); //result is 0x00010000, better than my same #define FLASH_APP_VADRESS or *(uint32_t *)applicationStack in __MSP
//applicationEntry();
// Load the Reset Handler address of the application
//application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)(FLASH_APP_VADRESS ));
// Jump to user Reset Handler in the application
application_code_entry();
我应该使用(0x20003240 + 0x00010000)我的新MSP吗?
答案 0 :(得分:1)
您将取消引用SP
堆栈指针两次:
applicationStack = (uint32_t) *(volatile unsigned int*) (startAddress);
// ... --^
__set_MSP(*(uint32_t *)applicationStack);
// -^
您只需要一次。第二次设置SP
非常可能为零,一旦使用堆栈就会导致错误。
答案 1 :(得分:0)
我找到了答案!!!
最后跳转,就像atmel在我需要未初始化某个模块之前说的那样。
所以:ATMEL部分:
*// Pointer to the Application Section
void (*application_code_entry)(void);
// Rebase the Stack Pointer
__set_MSP(*(uint32_t *)FLASH_APP_VADRESS);
// Rebase the vector table base address TODO: use RAM
SCB->VTOR = ((uint32_t)FLASH_APP_VADRESS & SCB_VTOR_TBLOFF_Msk);
// Load the Reset Handler address of the application
application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)
(FLASH_APP_VADRESS + 4));
// Jump to user Reset Handler in the application
application_code_entry();*
我执行此操作前的部分:
*Flash_Deinit(); //flash uninit
config_TC_Deinit(); //time clock uninit, scheduler
can_deinit0(); // module CAN0
can_deinit1(); // module CAN1
Handle_Wdt_Disable();
__disable_irq();
// Disable SysTick
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
// Disable IRQs & clear pending IRQs
for (i = 0; i < 8; i++) {
NVIC->IP[i] = 0x00000000;
}
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICPR[0] = 0xFFFFFFFF;*
我希望它会帮助别人! :)