Programmieren von ARM-Optionsbytes mit Assembly-Direktiven

Wenn wir uns also das Datenblatt für einen bestimmten ARM-Controller ansehen, finden wir den zuzuordnenden Adressraum wie folgt:

Geben Sie hier die Bildbeschreibung ein

Es gibt mehrere Möglichkeiten, dies zu erreichen, eine davon ist eine automatisch generierte Datei mit den folgenden (komprimierten) Inhalten:

; Option byte organization
;-------------------------
;   Address     [31:24] [23:16] [15:8] [7:0]
; 0x1FF80000       -     nRDP      -    RDP     (0xFF5500AA)
; 0x1FF80004       -     nUSER     -    USER    (0xFF870078)
; 0x1FF80008     nWRP1   nWRP0   WRP1   WRP0    (0xFFFF0000)
; 0x1FF8000C     nWRP3   nWRP2   WRP3   WRP2    (0xFFFF0000)

FLASH_OPT       EQU     1

RDP             EQU     0xAA
nRDP            EQU     RDP:EOR:0xFF
WRP00           EQU     0x00
WRP01           EQU     0x00
WRP02           EQU     0x00
WRP03           EQU     0x00
nWRP00          EQU     WRP00:EOR:0xFF
nWRP01          EQU     WRP01:EOR:0xFF
nWRP02          EQU     WRP02:EOR:0xFF
nWRP03          EQU     WRP03:EOR:0xFF
USER            EQU     0x78
nUSER           EQU     USER:EOR:0xFF

IF      FLASH_OPT <> 0
    AREA    |.ARM.__AT_0x1FF80000|, CODE, READONLY
        DCB     RDP,   0x00,   nRDP,   0xFF      
        DCB     USER,  0x00,   nUSER,  0xFF      
        DCB     WRP00, WRP01,  nWRP00, nWRP01
        DCB     WRP02, WRP03,  nWRP02, nWRP03
ENDIF

Es scheint, als ob diese Datei einfach eine gut konfigurierbare Möglichkeit bietet, diese Optionsbytes zu setzen, aber wie wird das gemacht? Ich habe ein wenig recherchiert und es stellt sich heraus, dass die AREADirektive den Assembler anweist, einen neuen Bereich zu generieren, in diesem Fall einen Codebereich , der nur gelesen wird .

Außerdem DCBweist die Direktive Speicher zu, in diesem Fall 16 Bytes, und initialisiert sie mit den jeweiligen angegebenen Werten.

Meine Frage ist dann, wo ist die Spezifikation bezüglich der Position dieses neu zugewiesenen Speicherblocks? Wie wird nämlich der Wert dieses 16-Byte-Blocks in die entsprechenden Register (0x1FF80000 usw.) geschrieben?

Die einzige Erwähnung dieser Adresse wird durch das |.ARM.__AT_0x1FF80000|an übergebene Argument gegeben AREA. Dieses erste Argument ist jedoch laut Dokumentation nur der Name dieses neuen Bereichs .

Oder vielleicht ist die bessere Frage: Wie können wir angeben, wo ein AREA im Speicher gespeichert wird?

Normalerweise Linker-Skripte. In gcc-basierten Compilern sind dies Textdateien mit der Erweiterung .ld.
@BrianDrummond, Dieses Beispiel stammt aus einer Assemblydatei mit dem Namen STM32xxxx_MD_OPT.s

Antworten (1)

Der ARM-Linker platziert automatisch Abschnitte mit dem Präfix __atin der angegebenen Adresse. In C-Code würden Sie den Abschnitt mit dem sectionAttribut wie folgt angeben:

// place flash_key in a section called .ARM.__at_0x8000
long flash_key __attribute__((section(".ARM.__at_0x8000")));

Sie können das Verhalten steuern, indem Sie --autoat oder --noautoat an den Linker übergeben.

Weitere Einzelheiten finden Sie im Abschnitt Platzierung eines Schlüssels im Flash-Speicher mit einem __at im ARM Linker-Benutzerhandbuch.

Danke schön! Ist das Präfix .ARM.in diesem Fall notwendig oder Konvention?
.ARM.ist bei der Angabe des Abschnittsnamens notwendig, aber Sie könnten die Daten auch mit dem atAttribut an der Adresse platzieren. Siehe Platzierung von __at-Abschnitten an einer bestimmten Adresse . Dies gilt natürlich nur für den ARM-eigenen Compiler, nicht für GCC oder andere.