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
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.
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.
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.
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
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...
Der Same hat zwei flashbänke. Geschrieben werden kann nur in der Bank in der gerade kein Code ausgeführt wird.
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.
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.