Forum: Mikrocontroller und Digitale Elektronik Bootloader ATmega32 Problem


von Sebastian Z. (sz1985)


Lesenswert?

Hallo zusammen,

ich bin gerade dabei einen Bootloader für den ATmega32 zu schreiben. 
Aktuell habe ich das Problem, dass er mir den Flash Speicher weder 
löscht noch mit Daten beschreibt.


Einstellungen:
Lockbits: 0xFF
Fuses:    0xDAFF

Linker:   -Ttext=0x7000
1
#include <string.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <avr/boot.h>
5
#include <util/delay.h>
6
#include "uart1.h"
7
#include <avr/pgmspace.h>
8
9
#define UART_BAUD 103
10
11
12
unsigned char c;
13
unsigned char temp;
14
15
16
void program_page (uint32_t page, uint8_t *buf)
17
{
18
    uint16_t i;
19
    uint8_t sreg;
20
 
21
    /* Disable interrupts */
22
    sreg = SREG;
23
    cli();
24
 
25
    eeprom_busy_wait ();
26
   uart_putc(page);
27
    boot_page_erase (page);
28
    boot_spm_busy_wait ();      /* Wait until the memory is erased. */
29
   uart_puts("e");
30
    for (i=0; i<SPM_PAGESIZE; i+=2)
31
    {
32
        /* Set up little-endian word. */
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
    boot_rww_enable ();
45
 
46
    /* Re-enable interrupts (if they were ever enabled). */
47
    SREG = sreg;
48
}
49
50
51
int main()
52
{
53
uint16_t flash_page = 0;
54
55
uint8_t flash_data[SPM_PAGESIZE];
56
uint8_t c;
57
uint8_t temp;
58
59
    temp = MCUCR;
60
    GICR = temp | (1<<IVCE);
61
    GICR = temp | (1<<IVSEL);
62
63
//Befüllen des Buffers mit Testdaten für eine Page
64
memset(flash_data, 0x1F, sizeof(flash_data));
65
66
    uart_init(UART_BAUD); 
67
    sei();
68
69
uart_puts("Hier ist das Testprogramm zum löschen einer page\n");
70
_delay_ms(2000);
71
72
do
73
{
74
c = uart_getc();
75
76
if(c='d')
77
{
78
program_page((uint16_t)flash_page, flash_data);
79
}
80
81
}
82
while(c!='d');
83
uart_puts("Ende");
84
85
return 0;
86
}

Wenn ich mir das Flashabbild (als iHex) nach dem Ausführen des 
Schreibvorganges anschaue, habe ich im Flashbereich 0x0000 bis 0x6FFF 
den Wert 0xFF stehen. Ab 0x7000 steht der Code des Bootlaoders.

Hoffe es kann mir jemand von euch weiterhelfen.

Vielen Dank!

Gruss

Sebastian

von Sebastian Z. (sz1985)


Lesenswert?

Hat keiner von euch eine Idee, wo der Fehler liegen könnte?

von Peter D. (pdiener) Benutzerseite


Lesenswert?

Zumindest das Löschen hat doch funktioniert, wenn überall 0xff steht.

Grüße,

Peter

von Neubi (Gast)


Lesenswert?

meine funktionierende version sieht folgendermassen aus ...

c-file:
1
MEMSEG_BOOTLOADER BYTE LoaderStartDownload(void)
2
{
3
  BYTE i,x;
4
  WORD page, data;
5
6
  for(x=0; x<MAX_FLASH_PAGES; x++)
7
  {
8
    //------------------ get program-page from USB-Stick --------------//
9
    if(!LoaderGetNextProgramPage(&page))    // get next program-page from usb-stick
10
    {
11
      LoaderUsbTxStr("C 0");                // pagewrite failed -> close file
12
      return FALSE;
13
    }
14
15
    //----------------------- erase flash-page ------------------------//
16
    eeprom_busy_wait();
17
    boot_page_erase(page);
18
    boot_spm_busy_wait();                   // wait until the memory is erased
19
  
20
    //----------------- fill data to internal page-buffer -------------//
21
    for(i=0; i<SPM_PAGESIZE; i+=2)
22
    {
23
      data  = USB.Tx.data[i];               // little endian
24
      data += ((USB.Tx.data[i+1]) << 8);
25
      boot_page_fill(page + i, data);
26
    }
27
28
    //------------------------ burn page to flash ---------------------//
29
    boot_page_write(page);
30
    boot_spm_busy_wait();                   // wait until the memory is written.
31
    boot_rww_enable();
32
  }
33
34
  LoaderUsbTxStr("C 0");                    // close file
35
36
  return TRUE;
37
}


header-file:
1
#define  __BOOT_PAGE_ERASE            0x03
2
#define  __BOOT_PAGE_WRITE            0x05
3
#define  __BOOT_PAGE_FILL             0x01
4
#define  __BOOT_RWW_ENABLE            0x11
5
6
7
8
#define  eeprom_busy_wait()       while(EECR & 0x02)
9
10
#define  boot_spm_busy_wait()     while(SPMCR & 0x01) 
11
12
#define  boot_page_erase(page)                   \
13
({                                               \
14
    __asm__ __volatile__                         \
15
    (                                            \
16
        "movw r30, %2\n\t"                       \
17
        "sts %0, %1\n\t"                         \
18
        "spm\n\t"                                \
19
        : "=m" (SPMCR)                           \
20
        : "r" ((BYTE)__BOOT_PAGE_ERASE),         \
21
          "r" ((WORD)page)                       \
22
        : "r30", "r31"                           \
23
    );                                           \
24
})
25
26
#define boot_page_fill(address, data)            \
27
({                                               \
28
    __asm__ __volatile__                         \
29
    (                                            \
30
        "movw  r0, %3\n\t"                       \
31
        "movw r30, %2\n\t"                       \
32
        "sts %0, %1\n\t"                         \
33
        "spm\n\t"                                \
34
        "clr  r1\n\t"                            \
35
        : "=m" (SPMCR)                           \
36
        : "r" ((BYTE)__BOOT_PAGE_FILL),          \
37
          "r" ((WORD)address),                   \
38
          "r" ((WORD)data)                       \
39
        : "r0", "r30", "r31"                     \
40
    );                                           \
41
})
42
43
#define boot_page_write(address)                 \
44
({                                               \
45
    __asm__ __volatile__                         \
46
    (                                            \
47
        "movw r30, %2\n\t"                       \
48
        "sts %0, %1\n\t"                         \
49
        "spm\n\t"                                \
50
        :                                        \
51
        : "i" (&SPMCR),                          \
52
          "r" ((BYTE)__BOOT_PAGE_WRITE),         \
53
          "r" ((WORD)address)                    \
54
        : "r30", "r31"                           \
55
    );                                           \
56
})
57
58
#define boot_rww_enable()                        \
59
({                                               \
60
    __asm__ __volatile__                         \
61
    (                                            \
62
        "sts %0, %1\n\t"                         \
63
        "spm\n\t"                                \
64
        :                                        \
65
        : "i" (&SPMCR),                          \
66
          "r" ((BYTE)__BOOT_RWW_ENABLE)          \
67
    );                                           \
68
})


gruss,
neubi

von Neubi (Gast)


Lesenswert?

#define SPM_PAGESIZE 128

von Sebastian Z. (sz1985)


Lesenswert?

Zum einen löscht er den Speicher nicht, da er in diesem Bereich bereits 
auf 0xFF steht.

@Neubi:
Ich habe deinen Code mit minimalen Anpassungen bei mir getestet und habe 
leider immernoch das Problem, dass er keine Daten schreibt. Hast du noch 
eine Idee, woran das liegen kannß

von Sascha W. (sascha-w)


Lesenswert?

SELFPRGEN Fuse gesetzt ?

Sascha

von Sebastian Z. (sz1985)


Lesenswert?

Sascha Weber schrieb:
< SELFPRGEN Fuse gesetzt ?

SPIEN ist laut den Werten der FUSES gestzt, aber AVR zeigt mir im Reiter 
FUSES unter dem Punkt SPIEN ein Häckchen mit kleinem roten Fragezeichen 
an.

von Sascha W. (sascha-w)


Lesenswert?

SELFPRGEN nicht SPIEN, aber uups die gibt's beim m32 gar nicht. Schau 
dir mal deine BLB_Fuses an.

Sascha

von Sebastian Z. (sz1985)


Lesenswert?

Die Lockbits sind alle auf 1 (0xFF).
BLB0  No lock on SPM and LPM in Application Section
BLB1  No lock on SPM and LPM in Bootloader Section

von Stefan E. (sternst)


Lesenswert?

Sebastian Z. schrieb:
> Fuses:    0xDAFF
>
> Linker:   -Ttext=0x7000

Da dein Flash-Write-Code nicht im Bootloader-Bereich liegt (sondern 
etwas unterhalb), kann er das Flash auch nicht beschreiben.

von Sebastian Z. (sz1985)


Lesenswert?

Vielen Dank. Habe den Wert jetzt auf 0x7800 geändert und es 
funktioniert.
Habe damals die Startadresse für 2048 words errechnet, warum auch immer.

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.