Forum: Mikrocontroller und Digitale Elektronik [NRF] Flashvorgang per SWD


von Archangel N. (archangel_n)


Lesenswert?

Hallo liebe Gemeinde,

habe ein Paar grundsätzliche Fragen zum Schreiben/Flashen einer Firmware 
über einen Mikrocontroller in einen anderen (i.d.F. einen Nordic)

1. Derzeit schreibe ich per SWD-Protokoll mit DAP (Debug Access Port) in 
den Flash-Speicher des NRF52180 das Image der Firmware folgendermaßen 
rein:
- Erste bis vorletzte Memory Page werden seitenweise geschrieben
- Letzte Memory Page wird word-/byte-weise geschrieben
Gibt es technische Möglichkeiten den Prozess des Flash-Vorgangs zu 
beschleunigen? Aktuell verzichte ich probeweise auch auf das Auslesen 
des READY-Flags und benutze stattdessen ein us-Delay. Das angepeilte 
Ziel wären <4s für 0x3000 Flash-Speicher des N52180.

2. Welche Verifizierungsmöglichkeiten bestehen bei so einem 
Flashvorgang? Ich benutze derzeit einen Prüfsummenabgleich für das 
Gesamtimage. Außerdem lese ich das Image einmal komplett aus und 
vergleiche es mit der Referenz. Was gäbe es außerdem für Möglichkeiten?

3. Hat jemand Erfahrungen mit dem im Referenzdokument erwähnten 
Flashloader gemacht? Ich komme mit dem EFM32-Beispiel auf keine bessere 
zeit als mit dem direkten Flashzugriff.

Vielen Dank im Voraus!

LG Nik

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Du könntest einen flash loader in's RAM laden. Danach lädst Du den 
Inhalt einer Seite in einen von 2 Puffern und startest den flash loader. 
Während der flash loader die Seite in den flash Speicher schreibt (und 
auch korrekt auf das READY event wartet), kann eine 2. Seite im RAM 
schon via SWD mit dem Inhalt der nächsten Seite gefüllt werden.

So erreichst Du minimale (und korrekte) Wartezeiten und kannst die 
Wartezeit bereits zum Transport der nächsten Daten verwenden.

Zum Verifizieren fällt mir auch nichts besseres ein, als eine CRC über 
den gesamten Speicher zu bilden (das kann z.B. auch der im RAM liegende 
flash loader machen).

Keine Ahnung, welches Referenzdokument Du referenzierst.

von Andreas B. (abm)


Lesenswert?

Da würde ich mal in die Eingeweide von OpenOCD z.B. für STM32xxx 
schauen: Da wird eine einfache Schleife ins RAM geladen, die sich aus 
einem Ringpuffer bedient und ins Flash schreibt, der Ringpuffer wird 
seinerseits parallel über SWD (oder JTAG) nachgefüllt. Der Engpass ist 
da eher die SWD-Taktfrequenz.

Verify macht man sinnvollerweise über CRC, das läuft komplett intern und 
es ist damit kein Datentransport über SWD nötig.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Andreas B. schrieb:
> Da würde ich mal in die Eingeweide von OpenOCD z.B. für STM32xxx
> schauen: Da wird eine einfache Schleife ins RAM geladen, die sich aus
> einem Ringpuffer bedient und ins Flash schreibt, der Ringpuffer wird
> seinerseits parallel über SWD (oder JTAG) nachgefüllt. Der Engpass ist
> da eher die SWD-Taktfrequenz.

Diese "einfache Schleife" nenne andere halt flash loader ;-) Der Aufwand 
besteht im wesentlich darin, seine Toolchain dazu zu bekommen, einem so 
einfachen code zu generieren (ohne vector table, ohne runtime etc.).

von Andreas B. (abm)


Lesenswert?

Naja, "Flash Loader" klingt nach wer weiß was ... Das sind nur ein (je 
nach Komplexität des Flash Interfaces) zwei bis drei Dutzend Zeilen 
Assembler (ja Assembler, das spart halt den ganzen Aufwand mit Stack, 
Vektor-Tabelle, Lib und sonstigem Gerümpel).

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Angehängte Dateien:

Lesenswert?

Andreas B. schrieb:
> Naja, "Flash Loader" klingt nach wer weiß was ... Das sind nur ein (je
> nach Komplexität des Flash Interfaces) zwei bis drei Dutzend Zeilen
> Assembler (ja Assembler, das spart halt den ganzen Aufwand mit Stack,
> Vektor-Tabelle, Lib und sonstigem Gerümpel).

Anbei der Code meines flash loaders. Im linker script muss 
SUPPORT_LIB_RAM_BASE und SUPPORT_LIB_RAM_SIZE entsprechend ersetzt 
werden. Der ganze loader muss nicht in Assembler geschrieben werden.

von Archangel N. (archangel_n)


Lesenswert?

Erstmal vielen lieben Dank für eure Antworten! Schade, dass nur das 
Radio-Modul einen automatischen CRC Checker bieten :)

Torsten R. schrieb:
> Du könntest einen flash loader in's RAM laden. Danach lädst Du den
> Inhalt einer Seite in einen von 2 Puffern und startest den flash loader.
> Während der flash loader die Seite in den flash Speicher schreibt (und
> auch korrekt auf das READY event wartet), kann eine 2. Seite im RAM
> schon via SWD mit dem Inhalt der nächsten Seite gefüllt werden.

Obwohl ich keine Probleme mit dem delay_us habe (im schlimmsten Fall 
bekomme ich beim Schreiben in das Register einen WAIT und warte auf das 
READY), ist der flashloader natürlich eleganter. Welche Werte beim 
Flashen erreichst du damit erfahrungsgemäß, mal nachgemessen gehabt? Mit 
meinem aktuellen Konstrukt erreiche ich "nur" 8,2s für den gesamten 
Flashspeicher (0x3000)

: Bearbeitet durch User
von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Archangel N. schrieb:
> Erstmal vielen lieben Dank für eure Antworten! Schade, dass nur das
> Radio-Modul einen automatischen CRC Checker bieten :)

Ja, mir würde auch nicht einfallen, wie man den für seine Zwecke nutzen 
könnte, zumal DMA in der Regel auch nur im RAM funktioniert. Du könntest 
aber z.B. die Checksumme über den Inhalt der RAM-Puffer machen. Z.B: 
nach dem Du das flashen gestartet hast, dann muss Du nicht auf das 
READY-Flag pollen, sondern rechnest die CRC und vergleichst danach das 
RAM mit dem geschriebenen Flash.

> Welche Werte beim
> Flashen erreichst du damit erfahrungsgemäß, mal nachgemessen gehabt? Mit
> meinem aktuellen Konstrukt erreiche ich "nur" 8,2s für den gesamten
> Flashspeicher (0x3000)

Das Projekt ist schon etwas länger her (ein Bluetooth LE SWD Debugger). 
Ich meine mich aber zu erinnern, dass der Flaschenhals Bluetooth war und 
damit sollte es bestimmt mit mindestens 40kByte/s geschrieben haben (in 
einem sehr alten Protokoll finde ich auf jeden Fall 7kBytes/s).

Du must mal gucken, was bei Dir im System der Flaschenhals ist. "Time to 
Write one word" ist mit maximal 338µs angegeben (nRF53832). Damit 
müssten also mindestens 11,5kBytes/s möglich sein. Als Minimum ist 
67,5µs angegeben, was dann ein Maximum von ~58kBytes/s.

Wenn Du für jedes Wort mindestens 338µs wartest und mit jedem Wort die 
Latenz zum Abfragen und Schreiben mehrere Register via SWD hast (Wort 
Schreiben, Flashen Starten, Wort zurück lesen), dann kommst Du natürlich 
sehr schnell auf Zeiten im Millisekunden-Bereich pro Wort.

von Andreas B. (abm)


Lesenswert?

Archangel N. schrieb:
> Erstmal vielen lieben Dank für eure Antworten! Schade, dass nur das
> Radio-Modul einen automatischen CRC Checker bieten :)
CRC per Software ist bei den paar kB in max. ein paar Dutzend ms 
erledigt. Das fällt ggü. dem Flash-Programmieren nicht ins Gewicht.

von Frank K. (fchk)


Lesenswert?

Archangel N. schrieb:

> Gibt es technische Möglichkeiten den Prozess des Flash-Vorgangs zu
> beschleunigen? Aktuell verzichte ich probeweise auch auf das Auslesen
> des READY-Flags und benutze stattdessen ein us-Delay. Das angepeilte
> Ziel wären <4s für 0x3000 Flash-Speicher des N52180.

Gibt es einen technischen Grund für die Zeitvorgabe? Beim interaktiven 
Flashen sind auch 10s so kurz, dass das An- und abklemmen schon deutlich 
länger dauert.

fchk

von Michael G. (michael_g968)


Lesenswert?

Hallo,

Wir flashen per SWD. bei einem lehren IC war das ganze auch recht fix.

Wenn der IC aber schon beschrieben war, kam noch die erase time mit 
dazu, die war deutlich groesser als die reine flash time.

Im MCU boot gibt es sogar eine option das erase verhalten umzustellen 
von erase befor programming auf erase on demand.

Zahlen hab ich jetzt nicht im kopf, aber das waren fuer die 512kb ein 
paar sekunden, und keine minuten.

von Archangel N. (archangel_n)


Lesenswert?

Andreas B. schrieb:
> CRC per Software ist bei den paar kB in max. ein paar Dutzend ms
> erledigt. Das fällt ggü. dem Flash-Programmieren nicht ins Gewicht.

Das sind schon paar Hundert KB, aber da gebe ich dir wohl Recht :)

Michael G. schrieb:
> Im MCU boot gibt es sogar eine option das erase verhalten umzustellen
> von erase befor programming auf erase on demand.
>
> Zahlen hab ich jetzt nicht im kopf, aber das waren fuer die 512kb ein
> paar sekunden, und keine minuten.

nRF hat zum Glück eine ERASEALL-Funktionalität, welche deutlich unter 
page-wise erasing liegt. Wenn die Anforderungen es sonst erlauben, kann 
ich jedes mal einen kompletten Löschvorgang ausführen. Habe mal 
nachgemessen:
erase page: 83ms (von insgesamt 0x30 pages) → 3984ms für alle
erase all: 165ms

Frank K. schrieb:
> Gibt es einen technischen Grund für die Zeitvorgabe? Beim interaktiven
> Flashen sind auch 10s so kurz, dass das An- und abklemmen schon deutlich
> länger dauert.

Es ist eine Anforderung, hängt mit einem Initial-Flashvorgang während 
der Gerätemontage zusammen. Wenn sich die Manager dadurch effektiver 
fühlen, sei es drum ;) Für mich an der Stelle eine interessante 
technische Herausforderung.

Torsten R. schrieb:
> Damit
> müssten also mindestens 11,5kBytes/s möglich sein. Als Minimum ist
> 67,5µs angegeben, was dann ein Maximum von ~58kBytes/s.

Im Durchschnitt in etwa, was ich derzeit erreiche - wobei das Maximum 
mit 3-4s für einen reinen Flashvorgang natürlich schmeckt :)

von Michael G. (michael_g968)


Lesenswert?

Ok, ...

und wieso nimmt man nichts von der stange?
Wir verwenden z.B. Segger JFLASH in der Produktion. Der kann auch den 
NRF programmieren ueber SWD. Inital programmiert wird im ICT.

und bei einer Inital programmierung gehe ich davon aus, das der flash 
lehr ist, bzw das ich einen erase all vorneweg absetzen kann.

Zeitlich haengt das ganze ggf auch noch von der SWD geschwindigeit hab. 
Was kann der Programmer, und was hat man eingestellt.

Alles anderes ist dann fuer mich updating mit einem selber geschriebenen 
(oder uebernommenen) flasching rotine.

Da funktioniert dann nur noch page erase. da kann man dann ggf zeit 
sparen wenn man waerend des programmerens von page 1 page 2 loescht.

aber vermutlich geht irgend wo ganz anders die zeit drauf. Wenn du 
schnell sein willst, muss empfang der daten, loeschen und programieren, 
crc berechnen quasie parallel laufen. und nicht sequenziell.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Michael G. schrieb:

> und wieso nimmt man nichts von der stange?

"habe ein Paar grundsätzliche Fragen zum Schreiben/Flashen einer 
Firmware
über einen Mikrocontroller in einen anderen"

Weil man z.B. Firmware-Updates über eine Schnittstelle bekommt, die an 
dem einen, aber nicht an dem anderen µC angeschlossen ist. Auf dem µC, 
der die Updates bekommen soll, könnte man auch einen Bootloader 
installieren, der kostet dann aber extra Flash und auf der client Seite 
braucht es auch einen bootloader client, da kann dann SWD machmal 
einfacher sein.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.