Hallo zusammen,
hoffe mal wieder auf das Schwarmwissen hier... Und zwar versuche ich an
einem PIC32CZ8110CA... µC eine Updatefunktion für das Program zu
implementieren.
Folgendes Problem:
- Ich nutze den µC ohne dass ich einen eigenen Bootloader geschrieben
hätte.
- Ich würde gerne im normalen Programablauf den neuen Programcode
empfangen und diese in die zweite Application-Flash-Bank schreiben. Das
funktioniert auch soweit.
- Nun wird das neue Program verifiziert und dann wäre der µC bereit für
den Bank-Swap und einen Restart.
- Nach dem Restart sollte nun das neue Program laufen.
Aber genau an der Stelle mit dem Bank-Swap komme ich nicht weiter.
Vermeintlich setze ich das passende Bit, es wird aber nach einem
Neustart das alte Program weiter ausgeführt, als wäre nichts gewesen.
Ein ähnliches Problem hatte ich schonmal an einem ATSAMD51, da wurde mir
hier damals gesagt, dass die Funktion für den Bank-Swap eine RAMFUNC
sein müsse. Klingt im nachhinein logisch, hat dann dort auch
funktioniert. Beim PIC32CZ scheint das nicht das Problem zu sein.
Hier noch die relevanten Bereicht vom Code:
1 | else if(rx_cfg_buffer[rx_cfg_gi].DATA[3] == 0x0F) // Firmwareupdate
|
2 | {
|
3 | if(rx_cfg_buffer[rx_cfg_gi].DATA[2] == 0x01)
|
4 | {
|
5 | firmware_msg_cnt = (uint32_t)((rxTestbuffer_8Bit[7+8]<<24) | (rxTestbuffer_8Bit[6+8]<<16) | (rxTestbuffer_8Bit[5+8]<<8) | rxTestbuffer_8Bit[4+8]);
|
6 | clean_rx_cfg_reply_data();
|
7 | rx_cfg_reply.ID = rx_cfg_buffer[rx_cfg_gi].ID+1;
|
8 | rx_cfg_reply.DATA[2] = 0x00;
|
9 | rx_cfg_reply.DATA[3] = 0x0F;
|
10 | rx_cfg_reply.DATA[4] = FIRMWAREUPDATE_MSG_LIMIT;
|
11 | send_cfg_reply();
|
12 | // Flashbereich löschen
|
13 | panel2_firmware_erase(firmware_msg_cnt);
|
14 | // Neue Firmware abholen
|
15 | get_firmware(firmware_msg_cnt);
|
16 | // Prüfen neue Firmware
|
17 | verify_firmware(firmware_msg_cnt);
|
18 | // Bank-Swap
|
19 | volatile uint32_t current_panel = ((FCW_REGS->FCW_SWAP & FCW_SWAP_PFSWAP_Msk) >> FCW_SWAP_PFSWAP_Pos);
|
20 | if(current_panel == 1)
|
21 | FCW_ProgramFlashBankSelect(0);
|
22 | else
|
23 | FCW_ProgramFlashBankSelect(1);
|
24 | }
|
25 | }
|
1 | #define PROGRAM_FLASH_BANK_1 (0U)
|
2 | #define PROGRAM_FLASH_BANK_2 (1U)
|
3 | #define __ramfunc__ __attribute__ ((section(".ramfunc"), unique_section, noinline))
|
4 |
|
5 | typedef uint32_t PROGRAM_FLASH_BANK;
|
6 | typedef enum
|
7 | {
|
8 | FCW_UNLOCK_WRKEY = 0x91C32C01,
|
9 | FCW_UNLOCK_SWAPKEY = 0x91C32C02,
|
10 | FCW_UNLOCK_CFGKEY = 0x91C32C04
|
11 | } FCW_UNLOCK_KEY;
|
12 |
|
13 | static void FCW_UnlockSequence(FCW_UNLOCK_KEY key)
|
14 | {
|
15 | FCW_REGS->FCW_KEY = (uint32_t)key;
|
16 | }
|
17 |
|
18 | __ramfunc__ void FCW_ProgramFlashBankSelect(PROGRAM_FLASH_BANK pfmBank)
|
19 | {
|
20 | while(((FCW_REGS->FCW_STATUS & FCW_STATUS_BUSY_Msk)) != 0U)
|
21 | {
|
22 | /* Do Nothing */
|
23 | }
|
24 |
|
25 | FCW_UnlockSequence(FCW_UNLOCK_SWAPKEY);
|
26 |
|
27 | if (pfmBank == PROGRAM_FLASH_BANK_1)
|
28 | {
|
29 | FCW_REGS->FCW_SWAP &= (~FCW_SWAP_PFSWAP_Msk);
|
30 | }
|
31 | else
|
32 | {
|
33 | FCW_REGS->FCW_SWAP |= (FCW_SWAP_PFSWAP_Msk);
|
34 | }
|
35 | }
|
Hier noch der Link zum Datenblatt:
https://onlinedocs.microchip.com/oxy/GUID-A52628F4-6F6F-4C77-80CB-113A0C62DB75-en-US-9/GUID-C2C1D64B-5CB2-490B-AFC0-EB77229549A4.html
Beste Grüße und vielen Dank,
Fabian