2017-05-17 2 views
4

ARM Cortex M3 (LPC1519)ARM M3 relocaliser le code -> défauts

J'ai écrit un bootloader (qui semble jusqu'à présent au travail) qui fonctionne en flash et écrit le programme dans Flash (derrière le bootloader). Le programme est écrit et commence à s'exécuter correctement (au moins lors du débogage). Lorsque j'utilise le débogueur SEGGER Ozone, je peux définir un point d'arrêt sur 'main' et parcourir le firmware. Cependant, quand je lance un reagion plus grand dans le code (à un autre point d'arrêt), je reçois toujours des interruptions inattendues:

  • UsageFault_Handler
  • BusFault_Handler
  • etc.

Cela ne se produit pas , quand je passe la commande de code par commande. Il semble que les interruptions ne fonctionneront pas correctement.

Le programme s'exécute correctement lorsque je le flash à l'adresse 0x00000000. J'ai modifié le script de l'éditeur de liens de sorte que l'origine se situe au décalage supérieur (où le chargeur de démarrage place le microprogramme).

Est-ce que quelqu'un a rencontré des problèmes similaires?

Merci, Johann

PS: désolé, je ne peux pas fournir un échantillon minimal, parce que je ne sais pas où commencer

Edition - Informations complémentaires: I maintenant téléchargé un plus petit projet où je peux trouver une erreur dans le débogueur. Il existe une variable uint32_t dans une structure qui semble déclencher l'erreur. Il dit:

mémoire Mis-alligned lire: Adresse: 0x00001596, numBytes: 8, alignement: 4 (Word aligné)

En 0x1596 de fait n'est pas devideable par 4 si l'erreur est justifié, mais comment cela peut-il être? Le compilateur ne devrait-il pas prendre soin d'aligner les variables dans les structures?

Edition - Informations complémentaires: Il semble que cette erreur se produit toujours quand se déclenche la USART0 IRQ (txReady). Est-il possible que j'ai un problème avec les interruptions? L'ARM Cortex SysTick (SysTick_Handler) fonctionne bien !?

[[noreturn]] 
inline void startFirmware(std::uint32_t address) noexcept 
{ 
    //<removed checks for correct address> 

    //pointer to the address 
    const auto ptr = reinterpret_cast<std::uint32_t*>(address); 

    // Set vector table offset 
    SCB->VTOR = address & SCB_VTOR_TBLOFF_Msk; 

    // Set top stack handler 
    __set_MSP(*ptr); 

    // Get address of reset handler 
    const auto resetHandler = *(ptr + 1); 

    // Jump to reset handler 
    reinterpret_cast<internal::ResetHandlerFunction>(resetHandler)(); 
    while(true); 
} 

Edition - Informations complémentaires: Il semble que tous les Interruptions déclenchées par USART, CCTimer, etc. finissent par des exceptions, mais je ne peux pas savoir la raison pour laquelle.

+1

Avez-vous déménagé la table de vecteur au début de votre application principale? –

+0

En fait, 0x1594 IS est divisible par 4 (mais pas par 8)! –

+0

oui, mais pas 0x1596. Je l'avais bien dans le message d'erreur, mais l'ai foiré dans la phrase ci-dessous ;-(l'ai corrigé - merci – Traummaennlein

Répondre

2

J'ai découvert pourquoi les interruptions n'auraient pas fonctionné.

Dans le ARM Doku je trouve cette phrase:

Lors de la mise TBLOFF, vous devez aligner le décalage au nombre de entrées d'exception dans le tableau vectoriel. L'alignement minimum est de 32 mots, suffisant pour jusqu'à 16 interruptions. Pour plus d'interruptions, ajustez l'alignement en arrondissant à la puissance suivante de deux. Par exemple, si requiert 21 interruptions, l'alignement doit être sur une limite de 64 mots car la taille de la table requise est de 37 mots et la puissance suivante de deux est de 64. Consultez la documentation de votre fournisseur pour les détails d'alignement pour votre appareil.

Cela signifie, lorsque vous avez plus de 16 interruptions, vous ne pouvez pas placer votre SCB-> VTOR à des adresses qui sont 32 mots alligned (se terminant par 0x80), mais seulement à 64 adresse alignée mot (la fin avec 0x00). Dans mon cas 0x1100 au lieu de 0x1080 (j'utilise le premier 128byte pour les informations sur le programme, que le bootloader peut vérifier).