2012-10-03 27 views
9

Estoy usando una placa LPC 1768 de mbed, (con córtex M3 cpu) y estoy tratando de lograr algo aquí, principalmente actualizo la aplicación de usuario desde la tarjeta SD, estoy escribiendo dos programas, primero un gestor de arranque/nano-núcleo, y un usuario de la aplicación (holamundo va a hacer por un comienzo):Bootloader for Cortex M3

  • gestor de arranque/nano-kernel en el 0x00 carreras de dirección, que va a hacer algunas comprobaciones y, finalmente, agarrar el archivo binario en el SD tarjeta
  • Bootloader/nano-kernel copiará este binario en la dirección 0x9000 (que podría tener que cambiar más tarde, pero este espacio no es usado por el bootloader/nano-kernel así que debería estar bien)
  • Bootloader salta a la aplicación de usuario en 0x9000 + 4

La tarjeta Sd es bastante fácil de resolver, tengo problemas con la parte de salto. Aquí está el código de la función 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(); 

}

Así que he recopilado (estoy usando Keil uvision4) la aplicación de usuario cambiar la dirección de inicio a 0x9000. Si programo mi placa (usando flashmagictool), y luego salto manual (todavía usando flashmagictool) a 0x9004 (0x9000 + 4), la aplicación de usuario se ejecutará, así que creo que la compilación ha funcionado bien para que user-app pueda ejecutarse en 0x9000.

Pero si ejecuto el gestor de arranque/nano-kernel, este no salta a la aplicación de usuario y, lamentablemente, como no puedo depurar, no estoy seguro de lo que está pasando ... También he intentado no use la parte de copia SD, así que programo el gestor de arranque primero, básicamente con el salto a 0x9004. Luego programo la aplicación de usuario que se ubicará en 0x9000. Si reinicio la placa, el gestor de arranque se ejecuta pero no salta a la aplicación del usuario. Revisé la memoria y parece que ambos programas (gestor de arranque + aplicación de usuario) son correctos y están en el lugar correcto.

Estoy seguro de que me falta algo aquí, ¿hay algún código de bajo nivel que debería estar mirando? He leído tonos de documentos en línea, y de los ejemplos que he encontrado, están saltando al código de usuario de la misma manera que yo ... Muchas gracias por cualquier ayuda.

+0

esto debería funcionar bastante similares en su PC también, pero con direcciones virtuales, en lugar de física - probarlo y ver si funciona, entonces mover el código a Keil – Ulterior

+1

Cortex M3 no tiene MMU, por lo que no hay direcciones virtuales. –

Respuesta

8

Cortex M3 solo se puede ejecutar en modo Thumb. Por lo tanto, siempre debe saltar a address +1, de lo contrario generará un error.

sólo trato:

user_code_entry = (void (*)(void))(USER_FLASH_START +4 +1);

+0

¡No puedo creer que fue eso! Muchas gracias Turbo J :) – batmat

+3

Me doy cuenta de que esto probablemente funcionó, pero no tiene sentido. El compilador debería generar las instrucciones de Thumb para ti. Hago exactamente lo mismo que hiciste allí (no +1) y parece funcionar para mí. ¿Tiene el indicador 'thumb' establecido para el compilador' arm-none-eabi-gcc'? – nonsensickle

+0

¡Gracias! Esto también funcionó para mí en un M4. Todo compilado bien, el depurador ejecutó todo el código muy bien, con la única excepción de esta advertencia del depurador IAR que ocurriría al saltar al recorrer el código: "T-bit de XPSR es 0 pero debería ser 1. Cambiado a 1 ." – tniles09

3

acaba de leer el documento AN10866 en NXP sitio. Hay que cargar el PC y el puntero de pila y luego salta a la interrupción de restablecimiento:

__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); 
} 
+0

También me gustaría agregar que http://infocenter.arm.com/help/topic/com.arm.doc.dui0056d/DUI0056.pdf en la página 4-6 y 4-7 bajo las" Diferencias entre el ensamblador en línea " y armasm "establece que no puede almacenar valores en la PC. También indica que la instrucción 'bx' no es compatible, pero tengo un código que lo está usando actualmente en el asm en línea que funciona (aunque lo estoy comprobando de nuevo). – nonsensickle

+0

Mi comentario anterior se refiere al ensamblaje en línea como el que utilizó John Sinclair. Sin embargo, tengo una versión que hace lo mismo en el ensamblaje en línea y también funcionó bien, así que no estoy seguro de qué hacer con las recomendaciones de ARM. – nonsensickle

Cuestiones relacionadas