2016-08-11 1 views
0

Bonjour à tous, j'ai une exception HardFault sur mon cortex m1 plusieurs fois au même endroit. J'ai mise en œuvre HardFault et je peux lire les registres empilés:cortex m1 faute matérielle à ldrsh

stacked_r0 unsigned int 0x4 (Hex)
stacked_r1 unsigned int 0x60905f98 (Hex)
stacked_r2 unsigned int 0x0 (Hex)
stacked_r3 unsigned int 0x6092304b (Hex)
stacked_r12 unsigned int 0x60922ff8 (Hex)
stacked_lr unsigned int 0x60810be3 (Hex)
stacked_pc unsigned int 0x60810ce2 (Hex)
stacked_psr unsigned int 0x41000000 (Hex)

l'opération à PC empilés est: 60810ce2: ldrsh, [r3 r2, r2]

pourquoi il provoque la faute?

UPD j'ai réarrangé les variables et pour l'instant, il est tombé en panne dans memcpy appelé à partir du code FreeRTOS

stacked_r0 unsigned int 0x6090c858 (Hex)
stacked_r1 unsigned int 0x6091f8b4 (Hex)
stacked_r2 non signé int 0x3c (hex)
stacked_r3 unsigned int 0x6091f8a4 (hex)
stacked_r12 unsigned int port 0x280 (hex) stacked_lr unsigned int 0x60827f89 (hex)
stacked_pc unsigned int 0x6082b0dc (hex)
stacked_psr unsigned int 0x1000000 (Hex)

6082b0ba: bne.n 0x6082b120

6082b0bc: ajoute r5, R 2, # 0

6082b0be: ajoute r4, r0, # 0

6082b0c0: r5 des sous-marins, n ° 16

6082b0c2: ESRLS r5, r5, # 4

6082b0c4: ajoute r5, # 1

6082b0c6: lsls r5, r5, # 4

6082b0c8: ajoute r1, r1, r5

6082b0ca: LDR r6, [r3, # 0]

6082b0cc: str r6, [r4, # 0]

6082b0ce: LDR r6, [r3 , # 4]

6082b0d0: str r6, [r4, # 4]

6082b0d2: LDR r6, [r3, # 8]

6082b0d4: str r6, [r4, # 8]

6082b0d6: LDR r6, [r3, # 12]

6082b0d8: ajoute r3, # 16

6082b0da: str r6, [r4, # 12]

6082b0dc: permet d'ajouter r4, # 16

+0

qui est un accès non aligné. –

+0

D'accord, mais pourquoi? r3 points à la pile – qmor

+0

pile est ram, qu'est-ce que la pile doit faire avec elle les bits inférieurs sont 0xB ou 1011 pour ldrsh ou ldrh le bit inférieur doit être un zéro pour ldr, les deux inférieurs doivent être des zéros pour ldrd le bas trois doivent être des zéros. vous essayez de faire un accès demi-mot non aligné et le processeur vous a empêché de le faire. –

Répondre

1

exemple simple d'alignement de génération de compilateur en utilisant ldrsh:

short more_fun (short); 
short fun (short a) 
{ 
    unsigned int ra; 
    short x[16]; 
    for(ra=0;ra<16;ra++) 
    { 
     a+=more_fun(x[ra]); 
    } 
    return(a); 
} 

bras-none-eabi-gcc -O2 -mthumb -c -o so.c so.o -march = ARMv6-m bras-none-eabi-objdump -D so.o

00000000 <fun>: 
    0: b570  push {r4, r5, r6, lr} 
    2: b088  sub sp, #32 
    4: 0004  movs r4, r0 
    6: 466d  mov r5, sp 
    8: ae08  add r6, sp, #32 
    a: 2300  movs r3, #0 
    c: 5ee8  ldrsh r0, [r5, r3] 
    e: f7ff fffe bl 0 <more_fun> 
    12: 3502  adds r5, #2 
    14: 1904  adds r4, r0, r4 
    16: b224  sxth r4, r4 
    18: 42b5  cmp r5, r6 
    1a: d1f6  bne.n a <fun+0xa> 
    1c: 0020  movs r0, r4 
    1e: b008  add sp, #32 
    20: bd70  pop {r4, r5, r6, pc} 
    22: 46c0  nop   ; (mov r8, r8) 

la pile est aligné restant, la manipulation de la pile, pousser, sauter et cadre de pile sont tous des multiples de 8 octets (deux mots). Le tableau est sur la pile et utilise r5 comme index dans le tableau. Il semble que ldrsh nécessite deux registres, donc ils mettent r3 à zéro pour qu'ils puissent avoir un second registre. Et la clé ici est qu'ils commencent alignés, l'adresse sp a au moins les zéros trois bits inférieurs en supposant que tout le monde en dehors de ce code a été conforme à la convention. Ensuite, le code ajoute 2 à r5 à chaque fois à travers la boucle, en gardant le pointeur sur le tableau aligné sur une limite de demi-mot, le bit inférieur reste nul pour l'adresse pour chaque utilisation de ldrsh. Aucun problème d'alignement.

Veuillez fournir un exemple similaire, peut-être des fragments de code, mais certainement les fragments pertinents autour du ldrsh non aligné.