Guten Tag!
Ich arbeite hier gerade mit einem Bootloader auf einem Automotive
Atmega64C1. Leider konnte ich bisher beim Schreiben in den Flash keine
Erfolge verzeichnen. Da der ursprüngliche Code eher komplex ist, habe
ich ein einfaches Projekt aufgesetzt, das einfach nur eine Seite des
Flashspeichers mit einem Text beschreiben soll. Auch da zeigt sich
leider kein Erfolg.
Den Code der Funktion boot_program_page habe ich direkt dem Beispiel in
der boot.h entnommen. Eigentlich hätte ich angenommen, dass dieser
Beispielcode anstandslos das tut, was er verspricht. Aber wenn ich den
Flash nach Durchlaufen des Codes auslese, findet sich von den zu
schreibenden Daten keine Spur.
Die Fuses sollten korrekt gesetzt sein. Das Textsegment habe ich in den
Linkereinstellungen an die Adresse 0x3800 verschoben, wo der Bootloader
entprechend der Fuses (Byteadresse 0x7000) liegen sollte.
Als Entwicklungsumgebung nutze ich Atmel Studio 7 mit GCC.
Hier der Code:
1 | #include <stdint.h>
|
2 | #include <inttypes.h>
|
3 | #include <avr/io.h>
|
4 | #include <avr/wdt.h>
|
5 | #include <avr/interrupt.h>
|
6 | #include <avr/boot.h>
|
7 | #include <avr/pgmspace.h>
|
8 |
|
9 | #include "typedefs.h"
|
10 | #include "driver/can/can_drv.h"
|
11 | #include "driver/can/reduced_can_lib.h"
|
12 |
|
13 |
|
14 | void boot_program_page (uint32_t page, uint8_t *buf)
|
15 | {
|
16 | uint16_t i;
|
17 | uint8_t sreg;
|
18 |
|
19 | // Disable interrupts.
|
20 |
|
21 | sreg = SREG;
|
22 | cli();
|
23 |
|
24 | eeprom_busy_wait ();
|
25 |
|
26 | boot_page_erase (page);
|
27 | boot_spm_busy_wait (); // Wait until the memory is erased.
|
28 |
|
29 | for (i=0; i<SPM_PAGESIZE; i+=2)
|
30 | {
|
31 | // Set up little-endian word.
|
32 |
|
33 | uint16_t w = *buf++;
|
34 | w += (*buf++) << 8;
|
35 |
|
36 | boot_page_fill (page + i, w);
|
37 | }
|
38 |
|
39 | boot_page_write (page); // Store buffer in flash page.
|
40 | boot_spm_busy_wait(); // Wait until the memory is written.
|
41 |
|
42 | // Reenable RWW-section again. We need this if we want to jump back
|
43 | // to the application after bootloading.
|
44 |
|
45 | boot_rww_enable ();
|
46 |
|
47 | // Re-enable interrupts (if they were ever enabled).
|
48 |
|
49 | SREG = sreg;
|
50 | }
|
51 |
|
52 | int main(void)
|
53 | {
|
54 | uint8_t TextToPage[] = {"It is a period of civil war. Rebel spaceships, striking from a hidden base, have won their first victory against the evil Galactic Empire. ..."}; //Text zum Posten hier gekürzt
|
55 |
|
56 | cli();
|
57 | wdt_disable();
|
58 |
|
59 |
|
60 | boot_program_page (1, TextToPage);
|
61 |
|
62 | while (1)
|
63 | {
|
64 | }
|
65 | }
|
Angehängt habe ich einen Screenshot der Einstellungen der Fuse Bits und
einen Screenshot eines Disassemblys, das zeigt, dass der Code
tatsächlich im angestrebten Adressbereich ausgeführt wird.
Für kompetente Hilfe wäre ich gerade sehr dankbar :)