Forum: Mikrocontroller und Digitale Elektronik XMega User Signature Row


von XMega Fan (Gast)


Lesenswert?

Hallo,

hat es schon mal jemand geschafft diese User Row zur Laufzeit zu 
schreiben bzw. zu ändern?

Fan

von Michael W. (mic123)


Lesenswert?

Hi Leute,

ich schiebe den Beitrag mal hoch, weil ich ebenfalls Probleme habe die 
User Signature Row zu beschreiben.

Ich verwende die Dateien sp_driver.h bzw. sp_driver.s aus dem "AVR1316 - 
XMEGA Self-programming" Paket.

void GLOBALS_Write_User_Sig (void) {
SP_EraseFlashBuffer();    //Flash Puffer löschen
SP_WaitForSPM();    //Wait for NVM to finish

SP_EraseUserSignatureRow();  //Erase the user signature row
SP_WaitForSPM();    //Wait for NVM to finish

SP_LoadFlashWord(0, 0x1234);  //load one word into page buffer
SP_WaitForSPM();    //Wait for NVM to finish

SP_WriteUserSignatureRow();  //Write to the user signature row
SP_WaitForSPM();    //Wait for NVM to finish
}

Leider ohne Erfolg.

Wenn ich

const char userdata[] _attribute_ ((section (".user_signatures"))) 
="Hello User Signatures";

in mein Programm einfüge, werden die entspr. Daten in der User Sig. 
abgelegt. Sie lassen sich auch auslesen.

result=SP_ReadUserSignatureByte(0);  //Read byte from user signature
NVM_CMD=NVM_CMD_NO_OPERATION_gc;  //Noop/Ordinary LPM

Wobei beim Lesen LPM statt SPM verwendet wird.

Hat jemand eine Idee wo der Fehler liegt?

Gruß Micha

von matrixstorm (Gast)


Lesenswert?

Also ich hatte das damals als ich den bootloader fuer 
http://matrixstorm.com/avr/avrstick/ programmierte hingekommen.

Ich sehe mal im source nach und poste dann gl. wieder.

MfG

von Stephan B. (matrixstorm)


Lesenswert?

Okay ganze "gleich wieder" 2 Tage spaeter:


Das folgende wird sehr technisch, eine bessere Nutzersichtbeschreibung 
gibt es hier: http://matrixstorm.com/avr/avrstick/#msdbootloader

Zum Ausprobieren der API gibt es code hier: 
http://matrixstorm.com/avr/avrstick/#msdbootloader_api


Die eigentliche Schreibfunktion fuer die User Signature Row sieht so 
aus:
(Die Funktion habe ich der Uebersicht halber aufgeraeumt und einige 
Makros fuer bedingtes Uebersetzten entfernt.)
1
int16_t usermap_write(const uint8_t in_blockBuffer[BLOCKVMA_BLOCKSIZE], const uint32_t in_BlockAddress) {
2
  if (in_BlockAddress==0) {
3
    __do_spm(0, NVM_CMD_ERASE_USER_SIG_ROW_gc, 0xff);
4
    return flash_updatepage_Ex(&spmfunc, in_blockBuffer, 0, NVM_CMD_READ_USER_SIG_ROW_gc, NVM_CMD_WRITE_USER_SIG_ROW_gc);
5
  }
6
  return 0;
7
}

"__do_spm" verannlast dabei eine universelle Schreibfunktion innerhalb 
der apipage des bootloaders.
"__do_spm" ist eine Api-funktion, welche die register dafuer mappt:
1
void __do_spm(const uint_farptr_t flashword_ptr, const uint8_t nvmCommand, const uint16_t dataWord) {
2
  uint8_t sreg_backup = CPU_SREG;
3
  cli();
4
#if (USE_SPMINTEREFACE_MAGICVALUE != 0)
5
  __do_spm_complex(((uint32_t)APIPAGE__bootloader__do_spm_magicblock)>>1, flashword_ptr, nvmCommand, dataWord, (uint32_t)USE_SPMINTEREFACE_MAGICVALUE);
6
#else
7
  /* DANGER: ignores platform protection by magical value */
8
#       warning USE_SPMINTEREFACE_MAGICVALUE is zero - platform protection deactivated!
9
  __do_spm_complex(((uint32_t)APIPAGE__bootloader__do_spm)>>1           , flashword_ptr, nvmCommand, dataWord, (uint32_t)USE_SPMINTEREFACE_MAGICVALUE);
10
#endif
11
  CPU_SREG=sreg_backup;
12
}



In der apipage passiert dann das eigentliche schreiben:
1
/*
2
bootloader__do_spm: (currently within last page: 0x21e00)
3
 
4
;disable interrupts (if enabled) before calling!
5
;you may also want to disable wdt, since this routine may busy-loop
6
;==================================================================
7
;-->INPUT:
8
;#if HAVE_SPMINTEREFACE_MAGICVALUE
9
;magicvalue in                                    r23:r22:r21:r20
10
;#endif
11
;NVM.CMD (command code) will be (was spmcr on ATmega) register: r18
12
;MCU dependend RA(MPZ should be transfered within register:     r11
13
;lo8(Z) should be transfered within register:                   r12
14
;hi8(Z) should be transfered within register:                   r13
15
;( as definition of SPM low8bit of dataword are stored within   r0 )
16
;( as definition of SPM hi8bit  of dataword are stored within   r1 )
17
 
18
;<-->USED/CHANGED:
19
;temp0 will be register:                                        r11
20
;temp1 will be register:                                        r12
21
;temp2 will be register:                                        r13
22
;command code (r18) will change during CCP and status           r18
23
;Z (r31:r30) (and RAMPZ) wil be changed during operation
24
;NVM.CMD will become changed during operation
25
 
26
;<--OUT:
27
;<magicvalue specific code (not depicted here)>
28
;load pageaddress (Z) from (r11:)r13:12 since it may was used for icall
29
 */
30
void __bootloader__do_spm(void) {
31
  asm volatile (
32
    /* MAGIC NOT IMPLEMENTED YET */
33
    "sts        %[rampz]        ,       r11                     \n\t"
34
    "movw       r30             ,       r12                     \n\t"
35
   
36
    /* save the nvm command to temp0 sice we need an upper register */
37
    "mov        r11             ,       r18                     \n\t"
38
   
39
    /* wait the flash to unblock */
40
    "rcall      __do_spm__flash_block_spinwait%=                \n\t"
41
   
42
 
43
    /* do the mystic stuff */
44
    "ldi        r18             ,       %[spmmagic]             \n\t"
45
    "sts        %[cmdreg]       ,       r11                     \n\t"
46
    "sts        %[ccpreg]       ,       r18                     \n\t"
47
    "spm                                                        \n\t"
48
   
49
   
50
    /* again wait the flash to unblock */
51
    "__do_spm__flash_block_spinwait%=:                          \n\t"
52
    "lds        r18             ,       %[status]               \n\t"
53
    "andi       r18             ,       %[stat_block]           \n\t"
54
    "brne       __do_spm__flash_block_spinwait%=                \n\t"
55
    "ret                                                        \n\t"
56
    :
57
    :   [ccpreg]        "i"     (_SFR_MEM_ADDR(CCP)),
58
        [rampz]         "i"     (_SFR_MEM_ADDR(RAMPZ)),
59
        [cmdreg]        "i"     (_SFR_MEM_ADDR(NVM.CMD)),
60
        [status]        "i"     (_SFR_MEM_ADDR(NVM.STATUS)),
61
 
62
        [stat_block]    "M"     (NVM_NVMBUSY_bm | NVM_FBUSY_bm),
63
 
64
        [spmmagic]      "M"     (CCP_SPM_gc),
65
 
66
        [eol]           "M"     (0)
67
      );
68
}

Fuer Fragen, Anregungen, Ideen oder einfach nur fuer ein Schwaetzchen 
stehe ich gern zur Verfuegung.

MfG Stephan

: Bearbeitet durch User
von Michael W. (mic123)


Lesenswert?

Danke Stephan,

danke für Deine Mühe. Ich werde es mir am Dienstag, wenn ich wieder auf 
Arbeit bin, genauer ansehen. Ich wollte allerdings in diese Funktion 
nicht so viel Arbeit reinstecken und hatte gehofft, mit den 
Atmel-Treibern die Sache schnell "abfrühstücken" zu können.

Gruß Micha

von Stephan B. (matrixstorm)


Lesenswert?

Hallo

Michael W. schrieb:
> nicht so viel Arbeit reinstecken und hatte gehofft, mit den
> Atmel-Treibern die Sache schnell "abfrühstücken" zu können.

Das wirst du mit "normalen" application-section firmwares vergessen 
koennen.
Den Flash schreiben darf nur Code aus der bootloader-section (a.k.a. 
bootloader). Diese Hardwarebeschraenkung zu umgehen ist moeglich, aber 
sicher nicht innerhalb der Atmel libs.

Weclhen XMega verwendest du genau?

Fuer den XMega128A3U (und aufgrund von Anfragen auch schon diverse 
andere) kann man meine apipage im BLS installieren und dann meine 
apipage library nutzen. Flash schreiben ist dann so einfach wie eeprom - 
einfach per C funktionen.

MfG Stephan

von Michael W. (mic123)


Lesenswert?

Stephan B. schrieb:
> Den Flash schreiben darf nur Code aus der bootloader-section (a.k.a.
> bootloader).

Damit hat sich das Thema erledigt. Dann nehme ich halt den EEPROM. Danke 
für die Info.

Das ist mein erstes Xmega Projekt. Ich hatte im Datenblatt nur folgendes 
gelesen:

"The user signature row is a separate memory section that is fully 
accessible (read and write) from application software and external 
programmers."

Den Abschnitt habe ich überlesen:

"A boot loader (application code located in the boot loader section of 
the flash) can both read and write the flash program memory, user 
signature row, and EEPROM, and write the lock bits to a more secure 
setting. Application code in the application section can read from the 
flash, user signature row, production signature (calibration) row, and 
fuses, and read and write the EEPROM."

Gruß Micha

von Claus (Gast)


Lesenswert?

Stephan B. schrieb:
> Zum Ausprobieren der API gibt es code hier:
> http://matrixstorm.com/avr/avrstick/#msdbootloader_api

Hallo Stephan, ich ab gerade mal versucht deine API-Page -Exmaple zu 
übersetzen, bin ab leider gescheitert.

Wenn ich Dein makefile verwende läßt es sich Übersetzen, wenn ich dann 
aber den xmega128a3u gegen meinen a4u austausche, dann bekomme ich 
folgende Fehlermeldung:
avr:106 architecture of input file `apipage.a(apipage.o)' is 
incompatible with avr:107 Output

kannst Du oder jemand anders mir da weiterhelfen?

Ich möchte mit Hilfe der API-Page ein Programm schreiben was mir einen 
vorhandenen Bootloader ersetzt. Sollte doch damit gehen oder??

Gruß Claus

von Stephan B. (matrixstorm)


Lesenswert?

Hallo Claus

Der Bootloader laesst sich nur dann austauschen, wenn bereits eine 
API-page vorhanden ist.
Die Updater-Firmware nutzt diese dann um den neuen Bootloader in die BLS 
zu Flashen.

Bei nicht vorgesehenen, nachtraeglichen Nachbesserungen an existierenden 
Bootloadern koennten auch gesetzte Lockbits oder geaenderte 
Systemregister ein Problem darstellen.

Ggf. kannst du deine Situation naeher darstellen - gern auch auf einen 
Schwatz. (Ich bin z.B. heute (nachmittag?) auf meinen Teamspeak Server 
anzutreffen.)
Gerne compiliere ich die auch ATxMegaA4u objects (auch wenn ich dachte 
das schoneinmal getan zu haben...)

MfG Stephan

von Claus (Gast)


Lesenswert?

Hallo Stephan,

danke dass Du Dich so schnell gemeldet hast.

Leider hast Du mir damit auch jede Hoffnung geraubt:-(

Denn als ich Dir gerade beschreiben wollte wie ich es machen wollte, 
viel mir ein, dass der alte Bootloader blöderweise nur in App-Section 
schreiben kann. Denn in dessen Source steht sinngemäß:
1
for(...)
2
{
3
  ...
4
  nvm_wait_until_ready();
5
  nvm_flash_load_word_to_buffer(address, word);
6
}
7
nvm_flash_atomic_write_app_page(address);
... ist eine Anpassung der AVR1605.

Denn ich dachte ich könne eine Firmware schreiben, die sowohl in der 
App-Section als auch in der Boot-Section steht (nämlich Deine API) und 
dann den Bootloader ersetzt.

Jetzt muss ich die Geräte leider auseinander bauen und leider hab ich 
nicht auf alle physikalischen Zugriff.

Teamspeak hab ich leider nicht.
Gruß Claus

von Stephan B. (matrixstorm)


Lesenswert?

Noch ist nicht alles verloren.

Bevor du auseinander baust:
Hast du den Quellcode des Bootloader? (oder/und:)
Kannst du den Binaercode ruecklesen?

Ich hatte mal ein aehnliches Problem mit Atmels DFU.
Ich habe dann gezielt den vorliegenden ASM Code angesehen, und mir einen 
Codeblock ausgesucht der das SPM ausfuehrt.
Damit konnte ich dann was minimales druberschreiben und letztendlich den 
Bootloader auf etwas mit API tauschen...

(Das geht aber nur mit Versionen, die nicht den Bootloader 
schreibschützen)

MfG

: Bearbeitet durch User
von Claus E. (claus_e)


Lesenswert?

Ja ich hab alles Quellcode, .o .lss ..., da ich den Bootloader damals 
selbst angepasst habe (musste schnell gehen und nun ist ein Bug darin, 
wie nicht anders zu erwarten:-( ).
Du meinst die Einsprungadrssee für das spm im alten Bootloader suchen 
und
aus der Application heraus nutzen um Deine Api-Page zu installieren?

klingt nach einer Hoffnung.

Claus

von Claus E. (claus_e)


Lesenswert?

In der alten Bootloader .lss seht:
1
  nvm_wait_until_ready();
2
  nvm_common_spm(page_addr, NVM_CMD_ERASE_APP_PAGE_gc);
3
   20342:  42 e2         ldi  r20, 0x22  ; 34
4
   20344:  0f 94 bf 0b   call  0x2177e  ; 0x2177e <_etext>

dann ist 0x2177e die Einsprungadresse für nvm_common_spm? und in r20 
könnte ich dann NVM_CMD_ERASE_WRITE_BOOT_PAGE_gc übergeben?

: Bearbeitet durch User
von Stephan B. (matrixstorm)


Lesenswert?

Hallo Claus

Ich werfe gerne mal einen Blick rein.
Aber wenn moeglich (gern auch nur "privat" per mail), stelle mir die 
vollen Dateien zur Verfuegung. (Insbesondere den konkreten BinaryDump.)

Bitte nenne mir auch den konkreten Typ des verwendeten AVRs.
(Seitengroessen und Adressen variieren ja moeglicherweise innerhalb der 
Familie)

Meine mail: matrixstorm@gmx.de


MfG Stephan

p.s.: Ggf. ist noch etwas Platz in der BLS uebrig, sodass man die 
API-page zunaechst per HACK nachruestet.
Wichtig ist halt das BLS weiterhin schreibbar ist und man einen SPM 
findet mit nahem RET. (Sodass man den quasi als Unterprogramm 
missbrauchen kann.)

: Bearbeitet durch User
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.