Carregador de inicialização para Cortex M3
-
13-12-2019 - |
Pergunta
Estou usando uma placa LPC 1768 da mbed, (com cpu cortex M3) e estou tentando conseguir algo aqui, principalmente atualizar o aplicativo do usuário do cartão SD, estou escrevendo dois programas, primeiro um bootloader/nano-kernel, e um aplicativo de usuário (helloworld servirá para começar):
- Bootloader/nano-kernel no endereço 0x00 é executado, ele fará algumas verificações e eventualmente capturará o arquivo binário no cartão SD
- Bootloader/nano-kernel irá copiar este binário no endereço 0x9000 (isso pode ter que mudar mais tarde, mas este espaço não é usado pelo bootloader/nano-kernel então deve estar ok)
- Bootloader salta para o aplicativo do usuário em 0x9000 + 4
O cartão SD é bastante fácil de resolver, estou tendo problemas com a parte do salto.Aqui está o código da função de salto.
void run(void) {
void (*user_code_entry)(void);
unsigned *p;
SCB->VTOR = (USER_FLASH_START & 0x1FFFFF80);
// Load contents of second word of user flash - the reset handler address
// in the applications vector table
p = (unsigned *)(USER_FLASH_START +4); // USER_FLASH_START is 0x9000
user_code_entry = (void (*)(void))p;
// Jump to user application
user_code_entry();
}
Então compilei (estou usando Keil uvision4) o aplicativo do usuário alterando o endereço inicial para 0x9000.Se eu programar minha placa (usando flashmagictool) e depois pular manualmente (ainda usando flashmagictool) para 0x9004 (0x9000 + 4), o aplicativo do usuário será executado, então acredito que a compilação funcionou bem, então o aplicativo do usuário pode ser executado em 0x9000.
Mas se eu executar o bootloader/nano-kernel, este não pulará para o aplicativo do usuário e, infelizmente, como não consigo depurar, não tenho certeza do que está acontecendo...Eu também tentei não usar a parte de cópia SD, então programei o bootloader primeiro basicamente apenas com o salto para 0x9004.Em seguida, programo o aplicativo do usuário que ficará em 0x9000.Se eu reiniciar a placa, o bootloader será executado, mas não saltará para o aplicativo do usuário.Verifiquei a memória e parece que ambos os programas (bootloader + user-app) estão corretos e no lugar certo.
Tenho certeza de que estou faltando alguma coisa aqui. Há algum código de baixo nível que eu deveria examinar?Eu li muitos documentos on-line e, pelos exemplos que encontrei, eles estão pulando para o código do usuário da mesma maneira que eu ...Muito obrigado por qualquer ajuda.
Solução
O Cortex M3 só pode ser executado no modo Thumb.Assim você sempre tem que pular para address +1
, caso contrário irá gerar uma falha.
Apenas tente:
user_code_entry = (void (*)(void))(USER_FLASH_START +4 +1);
Outras dicas
Basta ler o documento AN10866 no Site NXP.Você carregou o ponteiro do PC e da pilha e depois saltou para a interrupção de redefinição:
__asm void boot_jump( uint32_t address ){
LDR SP, [R0] ;Load new stack pointer address
LDR PC, [R0, #4] ;Load new program counter address
}
void execute_user_code(void)
{
/* Change the Vector Table to the USER_FLASH_START
in case the user application uses interrupts */
SCB->VTOR = USER_FLASH_START & 0x1FFFFF80;
boot_jump(USER_FLASH_START);
}