2017-01-27 6 views
1

Ich versuche, eine Bootloader-Anwendung für STM32F030x8 zu schreiben. Ich schreibe die Bin-Datei über UART in den Controller. Wenn Daten im UART-RDR-Register vorhanden sind, lege ich es in einen global deklarierten Puffer von 1 KB. Jedes Mal, wenn der Puffer voll ist, versuche ich ihn in FLASH zu schreiben. Nach dem Schreiben in FLASH gibt die App eine Bestätigung an die PC-Software und sie ist bereit, einen neuen 1-KB-Block zu akzeptieren. Daher wird nicht in den Puffer geschrieben, während auf das Schreiben in FLASH zugegriffen wird. Wenn ich versuche, den globalen Puffer in FLASH zu schreiben, geht die Anwendung in den Hardfault-Handler.STM32 Hardfault Ausnahme beim Schreiben global deklarierten Puffer zu FLASH

Aber wenn ich den Puffer in einen lokal deklarierten Puffer von 1 KB mit memcpy() kopieren und versuche, diesen Puffer in FLASH zu schreiben, gibt es überhaupt kein Problem.

Warum kann ich nicht einfach den global deklarierten Puffer direkt in FLASH schreiben? Warum gibt es kein Problem, wenn der lokal deklarierte Puffer in FLASH geschrieben wird?

Vielen Dank im Voraus!

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); 
} 

Die Hardfault scheint zu passieren, wenn diese Funktion der for-Schleife eintritt.

Wenn in hardfault Ausnahme der LR-Register ist 0xFFFFFFF9, SP = 0x200011E8

Was seltsam ist, dass die for-Schleife in es in den Puffer nicht jede Bezugnahme ist, so ist es eigentlich nie abgerufen. Aber es funktioniert, wenn der Puffer in einen lokalen kopiert wird. Was fehlt mir hier?

EDIT 2:

global Puffer erklärt:

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]; 

auf Puffer empfangen Ereignis:

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

Erhalten Sie den Hardfault als direkte Folge des Kopiervorgangs? Oder gibt es möglicherweise einen Scheduler (d. H. Ein OS) als Teil Ihrer SW, der möglicherweise zu einem anderen Thread wechselt, der dann den harten Fehler verursacht? Tatsächlich, ist es auch ohne ein Betriebssystem möglich, dass der Hard-Fehler in einem Ihrer hw-Interrupt-Handler (ISR) auftritt? Ich schlage vor, dass Sie einen Breakpoint in Ihren Hard-Fault-Interrupt-Handler setzen und die Werte von PC und LR überprüfen, nur um das sicherzustellen. Möglicherweise möchten Sie auch die STM-Spezifikation für andere Register überprüfen, die möglicherweise weitere Informationen zur Ursache des Problems enthält. –

+0

Zeigen Sie vollständigen Code - wie Sie den Puffer deklarieren, wie Sie ihn an die Funktion übergeben, wie Sie ihn verwenden. –

+0

BTW - der Code der Funktion, die Sie zeigten, ist ein kompletter Unsinn. Wenn dieser Code von ST kommt, ist das nicht wirklich überraschend, da die ganze HAL/SPL zeigt, dass sie keine Ahnung von der richtigen Softwareentwicklung haben. –

Antwort

5

Beachten Sie, dass die Funktion auf uint32_t arbeitet, während Sie es einen uint8_t Puffer übergeben. ARM Cortex-M0-Kern (wie in STM32F0 gefunden) unterstützt NICHT unterstützt nicht ausgerichteten Zugriff und jeder Versuch, dies zu tun, führt zu einem Fehler.

Es funktionierte für den lokalen Puffer nur durch Zufall - es wurde auf 4-Byte-Grenze ausgerichtet, während der globale Puffer nicht war. Es könnte auch mit dem globalen Puffer arbeiten, wenn es richtig ausgerichtet wäre - wieder rein zufällig.

+0

Also wenn ich das richtig verstehe, um dies zu arbeiten, muss ich einen Uint32_t Puffer von 256 Einträgen deklarieren, schreibe etwas Code, um den Uint8_t Puffer hinein zu kopieren, und dann den Uint32_t Puffer übergeben? – BertVano

+0

@BertVano Es ist eine Möglichkeit, ja, oder du könntest einfach diesen Uint32_t-Puffer in deinem UART-Interrupt verwenden, um die Kopie zu vermeiden –

+0

Danke für deine Hilfe! – BertVano

Verwandte Themen