Hallo allerseits, habe nach längerer Zeit wieder mit C Programmieren angefangen und mich gleichzeitig für einen XMega entschieden. Meine bisherigen Erfahrungen beschränken sich auf die mega Serie. Nun habe ich auch schon das erste Problem (zumindest das erste über das ich schreibe ;) ), ich möchte für meine Anwendung ein Array welches im Flash angesiedelt ist und 7200byte groß ist auf einem port ausgeben, das sollte mit pgm_read_byte kein problem sein. Jetzt kommts aber, das Array soll über USART zu ändern gehen, also alle 7200 byte über die serielle Schnittstelle empfangen und nach eventueller Checksummen Prüfung in den Flash Speicher schreiben. Geht das aus der Anwendung? Gibt es eine Alternative? Mir ist schon eingefallen den Bootloader code zu erweitern denn der macht ja prinzipiell genau das was ich will, jedoch müsste ich dann meine Kommunikation umbauen (ich verwende ein Matlab Frontend) da die ja dannn lernen müsste mit dem BL zu kommunizieren. Bin für Vorschläge und Codeschnipsel dankbar. mfg. Robert
Xmega Flash beschreiben geht grundsätzlich nur mit Code in der Boot-Section.
Mit entsprechender API im BLS geht sowas schon. Man muss aber ein paar Dinge beachten, sonst crasht der AVR. http://matrixstorm.com/avr/avrstick/#msdbootloader_api MfG
Habe mir die Seite matrixstorm einmal angesehen. Ich verwende jedoch einen 128A1 ohne USB, müsste also den Bootloader reverse-engineeren und die relevanten Stellen auf einen "normalen" Bootloader umschreiben damit ich die API verwenden kann, das ist jedoch außerhalb meiner Möglichkeiten.
Hallo. API ist nur eine Flashseite, mehr oder weniger unabhaengig vom Bootloader. Hab das ganze sogar ins FLIP reingepatch, ohne FLIP jemals neu zu compilen. Ich haenge dir mal die API Seite an. Bei Fragen helfe ich gern. MfG
Ich denke ich bekomme eine Ahnung wie das funkt. In der letzten flash page in der BL Section steht deine API page (compilierte __bootloader__**** files) Am Beginn der API Page ist eine Sprungtabelle die unter anderem do_spm (Offset 2) anspringt. In der Applikation wird wird apipage.h inkludiert, dort wird mit extern definierten funktionen auf die Sprungtabelle verwiesen. (#define APIPAGE__bootloader__do_spm (APIPAGE_PAGEBYTEADDRESS+0x08)) Es wird also gar kein code aus dem BL verwendet, somit patcht man die apipage anstelle der letzten flash page in den Bootloader. Einiges ist jedoch noch unklar: .) APIPAGEAUXSECTION ist nirgendwo definiert oder ist das nicht notwendig? .) section (".apipage") müsste im Makefile def. sein. Kannst Du mir das auch zeigen? .) was ist apipage.a? .) Kannst Du mir die compilierte APIPage schicken damit ich den BL patchen kann? Ich plane avr-xboot (https://code.google.com/p/avr-xboot/) zu verwenden. Danke für die Hilfe. mfg. Robert
Hallo Robert Offner schrieb: > APIPAGEAUXSECTION ist nirgendwo definiert oder ist das nicht > notwendig? Das ist ein Makro welches von meinem internen AUXSECTION System definiert wird. Du kannst es aber auch leer lassen, dann lander der entpsrechende Code eben in .text. Der Grund fuer diese allgmeinere Programmierung: Manchmal passt (bei der Bootloaderprogrammierung) nicht alles in die BLS. Das AUXSECTION Level entscheidet dann per Makro, was statt in .text/.boot in einer Pseudo-BLS landet. Robert Offner schrieb: > section (".apipage") müsste im Makefile def. sein. Kannst Du mir das > auch zeigen? Das wird einfach als Linkeranweisung an den Anfang der letzten Seite des Flash positioniert. "-Wl,--section-start=.apipage=0x21e00" (im Falle von ATxmega128A3U) Robert Offner schrieb: > Kannst Du mir die compilierte APIPage schicken damit ich den BL > patchen kann? Ich plane avr-xboot (https://code.google.com/p/avr-xboot/) > zu verwenden. Kann ich machen - aber schwatzen wir mal bei Tageslicht dueber. Bin schon ziemlich KO jetzt um diese Zeit. Fuer meine http://www.ebay.de/itm/231298084713?ssPageName=STRK:MESELX:IT&_trksid=p3984.m1555.l2649 habe ich aber auch einen Bootloader nach AVR1605 direkt mit APIPage vorhanden. (Ist das nicht sogar die Refernezimplementierung von XBoot?) Robert Offner schrieb: > was ist apipage.a? Eine vorkompilierte Bibliothek fuers statische Linken (eingentlich object archive), welches das minimale __do_spm auf bequemere Funktionen umsetzt - siehe apipage.h . Beispielsweise musst du nur noch "flash_writepage" aufrufen, waehrend ansonsten das alles gemacht werden muesste:
1 | /*
|
2 | * __do_spm:
|
3 | *
|
4 | * Call the "bootloader__do_spm"-function, located within the BLS via comfortable C-interface
|
5 | * During operation code will block - disable or reset watchdog before call.
|
6 | *
|
7 | * REMEMBER: interrupts have to be disabled! (otherwise code may crash non-deterministic)
|
8 | */
|
9 | |
10 | |
11 | #if ((APIPAGE_TOTALADDRESSSPACEBYTESIZE_EXEC) >= 131071)
|
12 | # define __do_spm_complex__PROCESSEIND \
|
13 | /* prepare the EIND for following (e)icall */ \ |
14 | "lds r18 , %[eind] \n\t" \
|
15 | "push r18 \n\t" \
|
16 | "ldi r18 , %[spmfuncaddrEIND] \n\t" \
|
17 | "sts %[eind] , r18 \n\t"
|
18 | # define __do_spm_complex__RESTOREEIND \
|
19 | "pop __tmp_reg__ \n\t" \
|
20 | "sts %[eind] , __tmp_reg__ \n\t"
|
21 | # define __do_spm_complex__CALLOPCODE "eicall\n\t"
|
22 | #else
|
23 | # define __do_spm_complex__PROCESSEIND
|
24 | # define __do_spm_complex__RESTOREEIND
|
25 | # define __do_spm_complex__CALLOPCODE "icall\n\t"
|
26 | #endif
|
27 | |
28 | /* WARNING: "___bootloader__do_spm__ptr" is a functionptr in flash.
|
29 | * Using "APIPAGE__bootloader__do_spm*" (flash location) without conversion will break code!
|
30 | *
|
31 | * "__do_spm_complex" is based on spminterface of USBaspLoader, by Stephan Baerwolf
|
32 | */
|
33 | #define __do_spm_complex(___bootloader__do_spm__ptr, flashword_ptr, nvmcommand, dataword, MagicValue) \
|
34 | ({ \
|
35 | asm volatile ( \
|
36 | "push r0 \n\t" \
|
37 | "push r1 \n\t" \
|
38 | \
|
39 | /* load the magic value (MagicValue) */ \ |
40 | "ldi r23 , %[magicD] \n\t" \
|
41 | "ldi r22 , %[magicC] \n\t" \
|
42 | "ldi r21 , %[magicB] \n\t" \
|
43 | "ldi r20 , %[magicA] \n\t" \
|
44 | \
|
45 | /* load the address (flashword_ptr) */ \ |
46 | "mov r13 , %B[flashptr] \n\t" \
|
47 | "mov r12 , %A[flashptr] \n\t" \
|
48 | "mov r11 , %C[flashptr] \n\t" \
|
49 | \
|
50 | __do_spm_complex__PROCESSEIND \
|
51 | \
|
52 | /* also load the nvm command */ \ |
53 | "mov r18 , %[nvmcmd] \n\t" \
|
54 | \
|
55 | /* load the data (dataword) */ \ |
56 | "mov r1 , %B[data] \n\t" \
|
57 | "mov r0 , %A[data] \n\t" \
|
58 | \
|
59 | /* finally call the bootloader-function */ \ |
60 | __do_spm_complex__CALLOPCODE \
|
61 | __do_spm_complex__RESTOREEIND \
|
62 | \
|
63 | "pop r1 \n\t" \
|
64 | "pop r0 \n\t" \
|
65 | \
|
66 | /* stop further execution in case of unexpected error */ \ |
67 | "cpi r18 , 0xff \n\t" \
|
68 | "errorloop%=: \n\t" \
|
69 | "breq errorloop%= \n\t" \
|
70 | : \
|
71 | : [flashptr] "r" (flashword_ptr), \
|
72 | [spmfunctionaddress] "z" ((uint16_t)((uint32_t)___bootloader__do_spm__ptr)), \
|
73 | [spmfuncaddrEIND] "M" ((uint8_t)(((uint32_t)___bootloader__do_spm__ptr)>>16)), \
|
74 | [eind] "i" (_SFR_MEM_ADDR(EIND)), \
|
75 | [data] "r" (dataword), \
|
76 | [magicD] "M" (((MagicValue)>>24)&0xff), \
|
77 | [magicC] "M" (((MagicValue)>>16)&0xff), \
|
78 | [magicB] "M" (((MagicValue)>> 8)&0xff), \
|
79 | [magicA] "M" (((MagicValue)>> 0)&0xff), \
|
80 | [nvmcmd] "r" (nvmcommand) \
|
81 | : "r0","r1","r11","r12","r13","r18","r20","r21","r22","r23" \
|
82 | ); \
|
83 | })
|
84 | |
85 | |
86 | [...]
|
87 | |
88 | /* write operations using __bootloader_do_spm driver */
|
89 | |
90 | void __do_spm(const uint_farptr_t flashword_ptr, const uint8_t nvmCommand, const uint16_t dataWord) { |
91 | uint8_t sreg_backup = CPU_SREG; |
92 | cli(); |
93 | #if (USE_SPMINTEREFACE_MAGICVALUE != 0)
|
94 | __do_spm_complex(((uint32_t)APIPAGE__bootloader__do_spm_magicblock)>>1, flashword_ptr, nvmCommand, dataWord, (uint32_t)USE_SPMINTEREFACE_MAGICVALUE); |
95 | #else
|
96 | /* DANGER: ignores platform protection by magical value */
|
97 | # warning USE_SPMINTEREFACE_MAGICVALUE is zero - platform protection deactivated!
|
98 | __do_spm_complex(((uint32_t)APIPAGE__bootloader__do_spm)>>1 , flashword_ptr, nvmCommand, dataWord, (uint32_t)USE_SPMINTEREFACE_MAGICVALUE); |
99 | #endif
|
100 | CPU_SREG=sreg_backup; |
101 | }
|
102 | |
103 | [...]
|
104 | |
105 | size_t flash_writepage_Ex(__extfuncptr_type(apipage__do_spm_t) *spmfunc, const uint8_t in_pageBuffer[SPM_PAGESIZE], const uint_farptr_t in_pageNr, const uint8_t nvmCommand) { |
106 | uint_farptr_t flashAddress = in_pageNr*((uint_farptr_t)SPM_PAGESIZE); |
107 | |
108 | flash_eraseflashbuffer_Ex(spmfunc, in_pageBuffer, flashAddress); |
109 | flash_loadflashbuffer_Ex(spmfunc, in_pageBuffer, flashAddress); |
110 | __extfuncptr_function(apipage__do_spm_t, spmfunc, flashAddress, nvmCommand, 0); |
111 | |
112 | return SPM_PAGESIZE; |
113 | }
|
114 | |
115 | [...]
|
116 | |
117 | #if (!(defined(APIPAGE_OLDFLASHWRITE)))
|
118 | size_t flash_writepage(const uint8_t in_pageBuffer[SPM_PAGESIZE], const uint_farptr_t in_pageNr) { |
119 | __extfuncptr_type(apipage__do_spm_t) spmfunc = __extfuncptr_getPtr(apipage__do_spm_t, __do_spm); |
120 | return flash_writepage_Ex(&spmfunc, in_pageBuffer, in_pageNr, NVM_CMD_ERASE_WRITE_FLASH_PAGE_gc); |
121 | }
|
122 | #else
|
123 | /* very poor: old ATxmegas don't support some types of erasing/wrting - working around */
|
124 | size_t flash_writepage(const uint8_t in_pageBuffer[SPM_PAGESIZE], const uint_farptr_t in_pageNr) { |
125 | __extfuncptr_type(apipage__do_spm_t) spmfunc = __extfuncptr_getPtr(apipage__do_spm_t, __do_spm); |
126 | #if (APIPAGE_OLDFLASHWRITE)
|
127 | return flash_writepage_Ex(&spmfunc, in_pageBuffer, in_pageNr, APIPAGE_OLDFLASHWRITE); |
128 | #else
|
129 | return flash_writepage_Ex(&spmfunc, in_pageBuffer, in_pageNr, (in_pageNr<(BOOT_SECTION_START/SPM_PAGESIZE))?NVM_CMD_ERASE_WRITE_APP_PAGE_gc:NVM_CMD_ERASE_WRITE_BOOT_PAGE_gc); |
130 | #endif
|
131 | }
|
132 | #endif
|
Bis nachher/morgen. MfG Stephan p.s.: Nur zur Erwaehnung die ganzen Codeauszuege sind Bestandteil meines AVR Stick Projektes: http://matrixstorm.com/avr/avrstick/
:
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.