2017-01-27 2 views
1

J'essaye d'écrire une application de chargeur de démarrage pour STM32F030x8. J'écris le fichier bin au contrôleur via UART. quand les données sont présentes sur le registre UART RDR, je le place dans un tampon globalement déclaré de 1Kb. Chaque fois que le tampon est plein, j'essaye de l'écrire en FLASH. Après avoir écrit sur FLASH, l'application donne un accusé de réception au logiciel PC et elle est prête à accepter un nouveau bloc de 1Kb. Donc, le tampon n'est pas écrit lors de l'accès pour écrire dans FLASH. quand j'essaye d'écrire le tampon global à FLASH, l'application va dans le gestionnaire Hardfault. Mais quand je copie le tampon dans un tampon déclaré localement de 1Kb en utilisant memcpy(), et que j'essaye d'écrire ce buffer sur FLASH, cela ne me pose aucun problème. Pourquoi ne puis-je pas écrire le droit de tampon déclaré globalement à FLASH? Pourquoi n'y a-t-il aucun problème lorsque le tampon déclaré localement est écrit dans FLASH?STM32 Hardfault exception lors de l'écriture globalement déclaré tampon à FLASH

Merci d'avance!

EDIT:

uint32_t FLASH_If_Write(__IO uint32_t* FlashAddress, uint32_t* Data ,uint16_t DataLength) 
{ 
    uint32_t i = 0; 

    for (i = 0; (i < DataLength) && (*FlashAddress <= (USER_FLASH_END_ADDRESS-4)); i++) 
    { 
    /* the operation will be done by word */ 
    if (FLASH_Program(FLASH_TYPEPROGRAM_WORD, *FlashAddress, *(uint32_t*)(Data+i)) == 1) 
    { 
    /* Check the written value */ 
     if (*(uint32_t*)*FlashAddress != *(uint32_t*)(Data+i)) 
     { 
     /* Flash content doesn't match SRAM content */ 
     return(2); 
     } 
     /* Increment FLASH destination address */ 
     *FlashAddress += 4; 
    } 
    else 
    { 
     /* Error occurred while writing data in Flash memory */ 
     return (1); 
    } 
    } 

    return (0); 
} 

Le Hardfault semble se produire lorsque cette fonction entre dans la boucle.

Lorsqu'en exception hardfault le registre LR est 0xFFFFFFF9, SP = 0x200011E8

Ce qui est étrange est que dans la boucle, il n'y a pas de référence à la mémoire tampon, il est donc en fait jamais accédé. Mais cela fonctionne quand le tampon est copié dans un tampon local. Qu'est-ce que j'oublie ici?

EDIT 2:

déclarés globalement tampons:

in globals.c: 
uint8_t rec_buffer_uart1[REC_BUFFER_SIZE] = {0}; 
uint8_t send_buffer_uart1[SEND_BUFFER_SIZE] = {0}; 

in globals.h: 
#define REC_BUFFER_SIZE   1029 
extern uint8_t rec_buffer_uart1[REC_BUFFER_SIZE]; 
#define SEND_BUFFER_SIZE  1031 
extern uint8_t send_buffer_uart1[SEND_BUFFER_SIZE]; 

sur événement reçu tampon:

uint32_t flashdestination = APPLICATION_ADDRESS; 
uint8_t *buf_ptr = &buf; // buf is locally declared buffer 

// every time buffer is full: 
{ 
    memcpy(buf_ptr, &rec_buffer_uart1[3], 1024); 
    // works: 
    ramsource = (uint32_t)&buf; 
    // generates Hardfault: 
    ramsource = (uint32_t)&rec_buffer_uart1[3]; 

    /* Write received data in Flash */ 
    if (FLASH_If_Write(&flashdestination, (uint32_t*) ramsource , (uint16_t) 1024/4) == 0) 
    { 
     // send acknowledge 
    } 
} 
+0

La panne est-elle directement due à l'opération de copie? Ou y a-t-il éventuellement un planificateur (c'est-à-dire, un système d'exploitation) dans votre logiciel, qui passe éventuellement à un autre thread qui provoque alors la panne matérielle? En fait, même sans système d'exploitation, est-il possible que la panne se produise dans l'un de vos gestionnaires d'interruption hw (ISR)? Je suggère que vous mettiez un point d'arrêt dans votre gestionnaire d'interruption de panne matérielle, et vérifiiez les valeurs de PC et de LR, juste pour vous assurer de cela. En outre, vous pouvez vérifier les spécifications STM pour d'autres registres qui peuvent vous donner plus d'informations sur la source du problème. –

+0

Afficher le code complet - comment vous déclarez le tampon, comment vous le passez à la fonction, comment vous l'utilisez. –

+0

BTW - le code de la fonction que vous avez montré est un non-sens complet. Si ce code provient de ST, ce n'est pas vraiment surprenant, car HAL/SPL montre qu'il n'a aucune idée du bon développement logiciel. –

Répondre

5

Notez que la fonction fonctionne sur uint32_t, pendant que vous passez un tampon uint8_t. Le noyau ARM Cortex-M0 (tel que trouvé dans STM32F0) ne prend pas en charge les accès non alignés et toute tentative de le faire entraînera une erreur.

Il a travaillé pour le tampon local uniquement par coïncidence - il était aligné sur une limite de 4 octets, alors que le tampon global ne l'était pas. Il pourrait aussi bien fonctionner avec un tampon global s'il était correctement aligné - encore une fois par pure coïncidence.

+0

Donc, si je comprends bien, pour que cela fonctionne, je dois déclarer un tampon uint32_t de 256 entrées, écrire du code pour y copier le tampon uint8_t, puis passer le tampon uint32_t? – BertVano

+0

@BertVano une possibilité, oui Ou vous pouvez simplement utiliser ce tampon uint32_t dans votre interruption UART pour éviter la copie –

+0

Merci pour votre aide! – BertVano