Forum: Mikrocontroller und Digitale Elektronik Bootloader beim SAME54 überschreiben


von Mike (linne78)


Lesenswert?

Hallo, ich bin ganz neu in der Welt der SAM Mikrocontroller und habe 
jetzt für den Microchip SAME54 einen Bootloader, über UART, geschrieben. 
Hierfür habe ich jetzt den NVM Bootloader Size auf 8 kByte gesetzt, da 
ich den Bootloaderbereich auf 8 kByte festlegen wollte. Scheinbar ist 
dadurch jetzt der Speicher schreibgeschützt. Ich kann jetzt keine neue 
Version des Bootloaders drauf spielen. Gibt es eine Möglichkeit den 
Schreibschutz wieder aufzuheben oder ist der Mikrocontroller jetzt hin?

Noch eine Frage für die Experten von SAM-Mikrocontrollern. Hat es 
abgesehen vom Schreibschutz irgendeinen anderen Vorteil eine NVM 
Bootloader Size? Ich habe zumindest nichts anders im Datenblatt 
gefunden- Ich benötige zwar ein Bootloader, aber der soll nicht 
schreibgeschützt sein. Wenn es funktioniert, würde ich in Zukunft dann 
die NVM Bootloader Size auf 0 kByte lassen.

Gruß Linne

von Rudolph R. (rudolph)


Lesenswert?

Mit "USER_WORD_NVMCTRL_BOOTPROT" setzt man den Schreibschutz, also erst 
flashen, dann setzen.
Und ja, das kann man auch zurück setzen.

Das bringt halt im normalen Betrieb den Schreibschutz, man kann nicht 
einfach so aus Versehen etwa per Debugger mit einem Programm den 
Bootloader überschreiben.

von Mike (linne78)


Lesenswert?

Stimmt, jetzt sehe ich auch, dass man das unter Fuse einstellen kann. 
Aber jetzt ist es glaube ich schon zu spät. Ich habe die NVM Bootloader 
Size in der Initialisierung des Bootloader gesetzt. Nach jedem ändern 
der Fuses startet der Bootloader neu und setzt die NVM Bootloader Size 
wieder auf 8 kByte. Erkenne ich an meiner Debug-Ausgabe:(

Von den ganzen Lock-Bits habe ich ja schon die Finger gelassen, da ich 
sowas vermeiden wollte. Über die NVM Bootloader Size habe ich mich aber 
nicht genug informiert und gedacht, das ist für die Sprungpunkte der 
Interrupts relevant. Naja, da habe ich wohl Lehrgeld bezahlt.

von Rudolph R. (rudolph)


Lesenswert?

Tja, der Schutz überlebt auch ein Chip-Erase, ich war mir nicht sicher, 
musste ich gerade mal ausprobieren.
Den Reset Pin runter ziehen könnte helfen, das verhindert ja den 
Neustart, schaltet aber das Debug-Interface nicht ab.

von Mike (linne78)


Lesenswert?

Leider verweigert der Programmer die Arbeit sobald man selber den Reset 
Pin runter zieht. Er sagt dann das er den Mikrocontroller nicht findet.

Habe gerade sogar einen kombinierten Befehl mit der atprogram.exe 
probiert:
1
atprogram -t EDBG -i SWD -cl 2MHz -d ATSAME54P20A program -fs --format hex -f Document.userpage chiperase
Zwische dem Ändern der Userpage und dem Chip-Erase startet er neu und 
hat dann den NVM Bootloader Size wieder auf 8 kByte gesetzt.

: Bearbeitet durch User
von Rudolph R. (rudolph)


Lesenswert?

Funktioniert der Bootloader denn?

The bootloader section starts at the beginning of the main address 
space; Its size is defined by the
BOOTPROT[3:0] fuse. It is protected against write or erase operations, 
except if STATUS.BPDIS is set.
Issuing a write or erase command at an address inside the BOOTPROT 
section sets STATUS.PROGE and
STATUS.LOCKE. STATUS.BPDIS can be set by issuing the Set BOOTPROT 
Disable command (SBPDIS). It
is cleared by issuing the Clear BOOTPROT Disable command (CBPDIS). This 
allows to program an new
bootloader without changing the user page and issuing a new NVMCTRL 
startup sequence to reload the user
configuration. The BOOTPROT section is not erased during a Chip-Erase 
operation even if STATUS.BPDIS is
high.

SPDIS ist ein Kommando für NVMCTRL->CTRLB.reg - NVMCTRL_CTRLB_CMD_SBPDIS
Wenn das klappt dann noch ein Erase Block auf Adresse 0 und der 
Bootloader sollte Geschichte sein.
Vielleicht auch gleich noch ein Chip-Erase hinterher. :-)
DSU.CTRL.reg = DSU_CTRL_CE;
Wobei ich das Chip Erase noch nie probiert habe - eigentlich hoffe ich, 
dass das nicht einfach so geht...

von Florian L. (muut) Benutzerseite


Lesenswert?

Der Same hat zwei flashbänke. Geschrieben werden kann nur in der Bank in 
der gerade kein Code ausgeführt wird.

von Rudolph R. (rudolph)


Lesenswert?

Florian L. schrieb:
> Der Same hat zwei flashbänke. Geschrieben werden kann nur in der Bank in
> der gerade kein Code ausgeführt wird.

Jain, der hat vor allem zwei Busse für den Speicher.
Man kann den Speicher zwar auf zwei Bänke aufteilen und die Bänke 
tauschen, das muss man aber nicht machen.

Und wenn man den Block-Erase für den Bootloader aus einem Programm 
heraus ausführt, dann liegt das Programm ja offensichtlich nicht im 
gleichen Block wie der Bootloader.

Für den E51 habe ich dem Bootloader irgendwann mal 16k spendiert, mein 
Bootloader braucht aber nur knapp über 2k - für den Speicher verwendete 
ich die E51 nicht, eine 128kiB Version würde ich auch nehmen wenn es die 
gäbe.
Die Anwendung habe ich bei 0x4000 liegen.
Wenn das mit den Bänken ganz strikt wäre, dann würde das gar nicht 
funktionieren.

von Mike (linne78)


Lesenswert?

Rudolph R. schrieb:
> Funktioniert der Bootloader denn?

Leider funktioniert er noch nicht richtig. Der Sprung vom Bootloader zum 
Hauptprogramm geht nicht.
Mir kommt aber die Idee, das ich vielleicht im Debug-Modus den Sprung 
durch manipulation der Register hinbekommen könnte. Als Änderung des 
Program Counter auf Adresse 0x2000. Das werde ich mir morgen noch Mal 
genauer anschauen.

von Mike (linne78)


Lesenswert?

Leider werde ich die Tests heute nicht mehr schaffen.

Aber wenn ich ein Programm schreibe das an Adresse 0x2000 anfängt und 
diesen Inhalt hat

Rudolph R. schrieb:
> SPDIS ist ein Kommando für NVMCTRL->CTRLB.reg - NVMCTRL_CTRLB_CMD_SBPDIS
> Wenn das klappt dann noch ein Erase Block auf Adresse 0 und der
> Bootloader sollte Geschichte sein.
> Vielleicht auch gleich noch ein Chip-Erase hinterher. :-)
> DSU.CTRL.reg = DSU_CTRL_CE;

Und dieses dann so im Debug-Modus starte:

https://microchip.my.site.com/s/article/Debugging-an-application-having-start-address-other-than-0x0000-in-Cortex-M-devices--Atmel-Studio

Habe ich große Hoffung das ich den Speicher wider gelöscht bekomme.

von Rudolph R. (rudolph)


Lesenswert?

Ich habe das gerade mal ausprobiert mit meinem Bootloader auf dem E51, 
nur läuft mein Bootloader eben und startet die Applikation.
1
void kill_bootloader()
2
{
3
    NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_SBPDIS; /* Execute Set BOOTPROT disable command */
4
    while((NVMCTRL->STATUS.reg & NVMCTRL_STATUS_READY) == 0);
5
6
    NVMCTRL->ADDR.reg = 0;
7
    NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_EB; /* Execute "EB" Erase Block */
8
    while((NVMCTRL->STATUS.reg & NVMCTRL_STATUS_READY) == 0);
9
   
10
//    DSU->CTRL.reg = DSU_CTRL_CE; // funktioniert nicht 
11
    
12
    for(;;);
13
}
14
15
16
17
int main(void)
18
{
19
  uint8_t led_delay = 0;
20
    
21
    kill_bootloader();
22
...

Die Anwendung flashe ich über das Studio und das funktioniert 
einwandfrei, trotz gesetztem Schutz ist der Bootloader so gelöscht.
Wenn ich die ersten beiden Zeilen der Funktion auskommentiere passiert 
wie erwartet gar nichts, das "Verify" für den Bootloader läuft immer 
noch durch.

Nur das Chip-Erase klappt nicht und ich finde das beruhigend, man kann 
also nicht einfach so mit dem Setzen von einem Bit alles löschen.

von Mike (linne78)


Lesenswert?

Es hat etwas gedauert, aber jetzt habe ich es Mal getestet. Dabei habe 
ich mich an das Beispiel von Rudolph gehalten. Danke dafür.

Zusätzlich füge ich unter Toolchain -> *ARM/GNU Linker* -> *Memory 
Settings* noch das Item *.text=0x2000* zu den FLASH Segmenten hinzu. 
Oder alternative ändere ich die Start-Adresse des ROM im Linkerskript.
1
  rom      (rx)  : ORIGIN = 0x00002000, LENGTH = 0x00100000
Eines von beiden muss gemacht werden, aber beides zusammen geht auch 
nicht.

Jetzt kann ich das Programm kompilieren und auf den Mikrocontroller 
flashen. Natürlich startet das Programm ab Adresse 0x2000 und da der 
Bootloader nicht ins Hauptprogramm springt komme ich hier auch nicht 
hin.

Das war alles erwartet. Was ich nicht erwartet hatte, waren die Probleme 
beim Debugger. Hier habe ich unter Tools die Programming settings auf 
Erase only program area gesetzt (Den gesamten Chip kann ich ja auch 
noch nicht löschen) und die Reset strategy auf Normal (Ich habe auch 
Mal andere Reset Strategien ausgetestet, was aber keine Änderung 
gebracht hat). Bei den Debug settings habe ich *Override Vector Table 
Offset Register* aktiviert und dort die Adresse 0x00002000 eingegeben. 
Cache all flash memory except war aktiviert und habe ich auch 
aktiviert gelassen (Ich habe es auch Mal deaktiviert hat aber keine 
Änderung gebracht). Ein Wert habe ich nicht in *Cache all flash memory 
except* geschrieben. Use flashloader applet war aktiviert und hatte 
den Wert 0x20000000, was ich auch so gelassen habe (Deaktivieren hat 
auch keine Änderung gebracht).

Sobald ich den Debug-Modus starte, bekomme ich aber immer den Fehler 
*Failed to launch program. Error: Failed to load ELF executable*. Was 
mich wundert, da das Override Vector Table Offset Register doch extra 
für solche Probleme da seien soll. Natürlich nicht für mein spezielles 
Problem, aber es soll doch das Debuggen eines Programms ermöglichen, 
ohne den Bootloader zu löschen oder diesen zu durchlaufen.

Hat jemand erfahrung mit diesen Debug settings und weiß vielleicht, was 
ich falsch eingestellt habe?

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.