Der Murks hat einen Namen "Arduino" hier ein MKR1000 Wie auch bei dem M0 Modellen fällt einen der Bootloader auf die Füße da dieser nicht mehr in einen ROM sondern im Flash liegt. Das Flashen aus der Arduino Umgebung ging auch mal gleich schief in der Art das der Bootloader nicht mehr startete. Nun habe ich versucht verzweifelt diesen per SWD (Jlink) wieder aufzuspielen. Das funktioniert auch der Haken ist aber der Inhalt des NVM RAM der vom Bootloader Code nicht mehr rekonstruiert wird. Der Code wird geladen -> Watchdoog löst den Reset aus. Auch wenn man code an der Stelle packt die der bootloader dann anspringt würgt der Watchdoog das ganze zurück. Wie gesagt das gleich Problem hatte ich mit dem M0. Ich hatte damals den NVM mit korrekten Inhalt beim Programmstart beschrieben -> Power Down/Up und die Sache lief. Jemanden eine Einfache Idee als den Bootlader umzubauen das dieser den Inhalt des NVM beschreibt wenn dieser leer ist ?
Hmm mit den neuest Bootloader klappt es allerdings erfolgt das flashen aus der Arduino Umgebung heraus gibt es beim schreiben der letzten Pages ein Problem. Womit dieser im defekten Code landet. Wo dieses Problem bestand wohl schon vorher.... Siehe Anhang. Die Ursache bin ich noch bei zu finden
Der Inhalt des NVM wurde erfolgreich wieder hergestellt. Womit das Board wiederbelebt wurde. Allerdings gibt es einen Haken. Den ich schon mal in einen anderen Thread ansprach. Beim config der Clocks gibt es ein Problem da diese verriegelt sind. Das ASF bleibt an dieser Stelle in einer while() hängen. Der Code ist ohne die Clocks zur konfigurieren auszuführen und auf das Gerät zu schieben. Power down/up und danach den Bootloader flashen. Beim flashen kein löschen des gesamten flashes ! Sonst macht man die gleiche Bauchlandung wieder. Ab Adresse 0x804000 ist das löschen zu vermeiden! Danach sollte der Arduino sich wieder aus der Umgebung flashen lassen. Es gibt auch ein sketch mit ähnlichen Code leider bleibt das aus der oben genannten Problematik hängen. Da in der Arduino SDK die Clock verstellt werden. Das gleiche funktioniert auch mit dem M0 .
1 | void fix_fuses(void) { |
2 | |
3 | |
4 | uint32_t new_fusebits[2]; |
5 | new_fusebits[0] = 0xD8E0C7FF; // Default values |
6 | new_fusebits[1] = 0xFFFFFC5D; // |
7 | |
8 | /* Auxiliary space cannot be accessed if the security bit is set */
|
9 | if (NVMCTRL->STATUS.reg & NVMCTRL_STATUS_SB) { |
10 | return; |
11 | }
|
12 | |
13 | /* Disable Cache */
|
14 | uint32_t temp = NVMCTRL->CTRLB.reg; |
15 | NVMCTRL->CTRLB.reg = temp | NVMCTRL_CTRLB_CACHEDIS; |
16 | |
17 | /* Clear error flags */
|
18 | NVMCTRL->STATUS.reg |= NVMCTRL_STATUS_MASK; |
19 | |
20 | /* Set address, command will be issued elsewhere */
|
21 | NVMCTRL->ADDR.reg = NVMCTRL_AUX0_ADDRESS / 2; |
22 | |
23 | /* Erase the user page */
|
24 | NVMCTRL->CTRLA.reg = 0x05| NVMCTRL_CTRLA_CMDEX_KEY; |
25 | |
26 | /* Wait for NVM command to complete */
|
27 | while (!(NVMCTRL->INTFLAG.reg & NVMCTRL_INTFLAG_READY)); |
28 | |
29 | /* Clear error flags */
|
30 | NVMCTRL->STATUS.reg |= NVMCTRL_STATUS_MASK; |
31 | |
32 | /* Set address, command will be issued elsewhere */
|
33 | NVMCTRL->ADDR.reg = NVMCTRL_AUX0_ADDRESS / 2; |
34 | |
35 | /* Erase the page buffer before buffering new data */
|
36 | NVMCTRL->CTRLA.reg = 0x44 | NVMCTRL_CTRLA_CMDEX_KEY; |
37 | |
38 | /* Wait for NVM command to complete */
|
39 | while (!(NVMCTRL->INTFLAG.reg & NVMCTRL_INTFLAG_READY)); |
40 | |
41 | /* Clear error flags */
|
42 | NVMCTRL->STATUS.reg |= NVMCTRL_STATUS_MASK; |
43 | |
44 | /* Set address, command will be issued elsewhere */
|
45 | NVMCTRL->ADDR.reg = NVMCTRL_AUX0_ADDRESS / 2; |
46 | |
47 | *((uint32_t *)NVMCTRL_AUX0_ADDRESS) = new_fusebits[0]; |
48 | *(((uint32_t *)NVMCTRL_AUX0_ADDRESS) + 1) = new_fusebits[1]; |
49 | |
50 | /* Write the user page */
|
51 | NVMCTRL->CTRLA.reg = 0x06 | NVMCTRL_CTRLA_CMDEX_KEY; |
52 | |
53 | /* Restore the settings */
|
54 | NVMCTRL->CTRLB.reg = temp; |
55 | }
|
Anbei der Code der das Problem behebt. Um nicht immer in den Flash nach jeden Start zu schreiben wird die Adresse getestet und bei bedarf der Bereich gesetzt. Man sollte auch das linker Skript anpassen ! Somit ist sichergestellt das nicht wieder in den Sektor des bootloaders geschrieben wird. Noch ein Tip: In den bootloader kommt man durch zweimaliges drücken der Reset Taste. Bei eigenen Code ab Adresse 0x2000 fehlt dann natürlich die Serienelle USB um durch öffnen und schließen mit 1200 BAUD dies zu erzwingen. Um Code aus der Arduino Umgebung aufzuspielen muss dann durch drücken des Resets der Start des Bootloaders ausgelöst werden. Diese Com ist dann auszuwählen und nach dem hochladen des Sketches ist die serial Com wieder vorhanden und die Sache funktioniert wieder wie gewohnt.
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.