Automatisieren der Änderung der Linker-Datei

Ich arbeite an einem Firmware-Projekt, in dem ich eine CRC16-Prüfung auf Flash-Integrität durchführen muss.

Controller: MSP430 IDE: IAR EW 5.40 (Linker Xlink)

Der CRC wird mit dem IAR Xlink-Linker berechnet und am Ende des Flashs gespeichert. Wiederum wird crc zur Laufzeit aus dem Code berechnet und mit dem im Flash gespeicherten Wert verglichen, um die Integrität zu prüfen. Wir können crc jedoch nur auf dem Codesegment des Flash-Speichers berechnen. Seine Größe kann sich ändern, wenn wir einige Änderungen im Code vornehmen. Kann ich diesen Prozess automatisieren, den ich gerade manuell mache?

aus der .xcl-Linker-Datei:

// ---------------------------------------------------------
// CRC16 Essentials: -H for fill,-J for checksum calculation
// ---------------------------------------------------------

-HFF         

-J2,crc16,,,CHECKSUM2,2=(CODE)5C00-FF7F;(CODE)10000-0x20A13

Hier muss ich den Endwert des zweiten Codesegments ändern, das jetzt 0x20A13 ist. Ich bekomme diesen Wert aus der .map-Datei, dh wie viel Speicherbereich mein Code im Flash liegt. Dies ist die 1. Änderung, die ich mache.

Hier muss ich die zweite Änderung vom Code vornehmen:

sum = fast_crc16(sum, 0x5C00, 0xFF7F-0x5C00+1);

  sum = fast_crc16(sum, 0x10000,0x20A13-0x10000+1); 

  //Check the crc16 values 
   if(sum != __checksum)
   {
    // Action to be taken if checksum doesn't match
   }

Bitte helfen Sie mit, diesen Prozess zu automatisieren!!

Antworten (2)

Ich kenne Ihren Linker nicht, aber der gcc-Linker kann ein Label bereitstellen, dessen Adresse im Code verwendet werden kann. Diese Funktion wird üblicherweise verwendet, um den Startcode über den Start und das Ende der DATA- und BSS-Segmente zu informieren, damit das BSS gelöscht und die DATA (im RAM) von ihrer Kopie im ROM initialisiert werden können.

Fragment aus einem (LPC1343) Linkerscript, das ich verwende:

.text :
{
    . = ALIGN(4);
    __text_start = .;
    PROVIDE(__text_start = __text_start);

            // all text segments are listed here

    . = ALIGN(4);
    __text_end = .;
    PROVIDE(__text_end = __text_end);
} > rom 

Das Label __text_end befindet sich an der Adresse hinter dem Text. Es kann im Code für die CRC-Berechnung verwendet werden.

Zwei Anmerkungen:

  • Sie sagen, Sie überprüfen das Codesegment. Überprüfen Sie auch das DATA-Segment (initialisierte globale Werte)?

  • Wenn mir diese Aufgabe übertragen würde, würde ich in Betracht ziehen, die unbenutzten Flash-Speicherplätze mit einem bekannten Wert zu füllen und die Prüfsumme über den gesamten Flash zu legen.

Wir können Bezeichnungen für bestimmte Segmente im Linker definieren und sie im Code verwenden, aber das ist nützlich, wenn Adressbereiche festgelegt sind. Ich habe tatsächlich herausgefunden, ob es eine Möglichkeit gibt, die Änderungen im Code-Adressbereich außer der Zuordnungsdatei widerzuspiegeln, um eine manuelle Bearbeitung der Linker-Datei zu vermeiden.
Sie können einen vom Linker bestimmten Wert (in Ihrem Fall: das Ende des Codesegments) als Label an den Code zurückgeben. Siehe Fragment in meiner aktualisierten Antwort.
1. Datensegment wird nicht geprüft. 2. - Der HFF-Linker-Befehl soll unbenutzten Flash mit 0xFF füllen. Die Berechnung der Prüfsumme über den gesamten Flash funktioniert gut, dauert aber etwas länger. Über 1 Sekunde :( Inakzeptabel.
Warum nicht das Datensegment überprüfen? Ich würde denken, dass die Anfangswerte globaler Variablen genauso wichtig sind wie der Code!

Ich verwende EW8051, aber es verwendet auch Xlink. Es gibt zwei Größen zu beachten: Die eine ist die Größe des CODE-Segments, die Sie im Allgemeinen nicht ändern werden; und der andere ist die Größe, die Ihr Code einnimmt, die sich ändert (normalerweise wächst), wenn Sie Ihr Programm aktualisieren und den Link kompilieren.

Zum Beispiel können Sie hier aus meiner Linker-.xcl-Datei sehen, dass die Größe des CODE-Segments 0x8000 ist:

/
//    CODE
//    ----
-D_CODE0_START=0x000000
-D_CODE0_END=0x007FFF         // CC1111F32 has 32 kB code (flash)

Der Teil davon, der tatsächlich von meinem Code verwendet wird, ist jedoch in der .map-Datei aufgeführt:

30 739 bytes of CODE  memory

Wenn Sie sich den Abschnitt zur Prüfsummenberechnung des IAR Linker and Library Tools Reference Guide ansehen, scheint es, dass Sie den Linker normalerweise anweisen würden, die Prüfsumme über das gesamte CODE-Segment (in meinem Fall alle 0x8000 Bytes) zu berechnen. Dies ist der Beispielcode, den sie bereitstellen:

Calculating a checksum in your source code
This source code gives an example of how the checksum can be calculated:
/* Start and end of the checksum range */
/* Must exclude the checksum itself */
unsigned long ChecksumStart = 0x8000+2;
unsigned long ChecksumEnd = 0x8FFF;

/* The checksum calculated by XLINK */
extern unsigned short __checksum;

void TestChecksum()
{
    unsigned short calc = 0;
    /* Run the checksum algorithm */
    calc = slow_crc16(0,
                      (unsigned char *) ChecksumStart,
                      (ChecksumEnd - ChecksumStart+1));
    /* Rotate out the answer */
    unsigned char zeros[2] = {0, 0};
    calc = slow_crc16(calc, zeros, 2);

   /* Test the checksum */
   if (calc != __checksum)
   {
       abort(); /* Failure */
    }
}

Die Start- und Endadresse legen für mich stark nahe, dass die Prüfsumme über das gesamte Segment zu berechnen ist.

Beim Dokumentieren des -J-Flags heißt es in der Referenz: " Hinweis : Wenn Sie keine Bereiche explizit angeben, werden alle Bytes in der endgültigen Anwendung in die Berechnung einbezogen." Ich gebe zu, dass es einige Unklarheiten gibt, was "alle Bytes" bedeutet - das gesamte CODE-Segment oder nur der verwendete Teil.

Natürlich kann dieses Schema nur funktionieren, wenn alle unbenutzten Bytes im CODE-Segment mit Null initialisiert werden. Sie sollten dies überprüfen. :^)

Zusammenfassend: Verwenden Sie das Flag -J, um das gesamte CODE-Segment zu prüfen, machen Sie dasselbe in Ihrem Code und sehen Sie, ob das funktioniert (nachdem Sie mit dem Debugger überprüft haben, dass z. B. der nicht verwendete Teil des CODE-Segments nicht mit Müll gefüllt ist ).

-H-Flag wird für die Füllung verwendet. Es füllt den nicht verwendeten Codesegmentteil mit 0xFF, sodass die Prüfsumme für den gesamten Flash funktioniert. Dies hat auch einen Mehraufwand an erhöhter Rechenzeit zur Folge. Ich wollte nur wissen, ob wir die Bereiche automatisch einstellen können.