2015-12-22 1 views
3

Je suis en train de coder un petit bootloader cortex M0 +. J'ai un assembly inline ci-dessous qui démarre l'application principale à partir du bootloader en chargeant le pointeur de la pile et réinitialiser le gestionnaire de la position de l'application dans Flash.bras gcc __asm ​​inline passant constante dans le paramètre

#define FLASH_APP_START 0x1000 

[...] 

    __asm(
      // Update stack pointer from user code vector table 
      "LDR  r0, =%0 \n" 
      "LDR  r1, [r0] \n" 
      "MOV  sp, r1 \n" 

      // Load user code reset handler and jump to the user code 
      "LDR  r0, [r0, #4] \n" 
      "BX  r0 \n" 
      : 
      : "X"(FLASH_APP_START) 
      : 
     ); 

Lors de la compilation de ce code, je reçois l'erreur suivante:

Error: bad expression -- `ldr r0,=#4096'

GCC ajouter le # avant la constante qui ne devrait pas être là. Si je remplace la première ligne par la suivante, cela fonctionne parfaitement. Donc, la question est de savoir comment pourrais-je utiliser la constante définie?

Merci à l'avance pour toute aide

+1

A Quelques réflexions: Vous changez r0 et r1 dans ce modèle sans les écraser. Cela semble mauvais. Comme pour le '#', vous pouvez essayer '% c0'. –

+0

Un 'R' majuscule comme contrainte pour le pool littéral est incorrectement documenté dans le [manuel gcc] (https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Machine-Constraints.html#Machine -Contraintes). La suggestion de David est correcte. utilisez le modificateur '% c ** reg **' selon [exemple godbolt] (https://goo.gl/OEsdtN). [Le manuel] (https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Extended-Asm.html#Extended-Asm) a ceci sous le titre 'Description du modificateur'. –

+0

A [question connexe] (http://stackoverflow.com/questions/28833189/what-is-the-right-way-to-create-a-constant-pool-for-inline-assembly) sur l'assembleur en ligne et le piscine constante. –

Répondre

1

Il y a d'abord comme aucune raison d'utiliser l'assembleur en ligne ici, la solution simple serait d'écrire tout ce code dans un fichier de langage assembleur normal. Vous pouvez définir la macro FLASH_APP_START dans un fichier d'en-tête que vous pouvez inclure dans les fichiers source de l'assembly et du C si nécessaire.

Si vous voulez continuer à utiliser l'assembleur en ligne alors solution suivante la plus simple serait de laisser le compilateur faire la plupart du travail pour vous et réduire la déclaration d'assemblage juste ce qu'il ne peut pas faire:

void ** const flash_vector_table = (void **) FLASH_APP_START; 
    asm volatile ("mov sp, %[stack]\n\t" 
        "bx %[reset]\n" 
        : 
        : 
        [stack] "r" (flash_vector_table[0]), 
        [reset] "r" (flash_vector_table[1])); 
+0

Comme il se doit. Merci ! – pge