avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Problems programming flash


From: Yannick PODGORSKI
Subject: Re: [avr-gcc-list] Problems programming flash
Date: Mon, 7 Feb 2005 11:50:18 +0100

gcc toolchain needs byte address here 0xF000*2 = 0x1E000.
I use :
MT_BOOT_LOADER_ADDRESS = 0x1E000
LDFLAGS += -Wl, --section-start=.text=$(MT_BOOT_LOADER_ADDRESS).

With AVRStudio, program the fuses :
BOOTRST = 0 (reset at @ 0x1E000)
BOOTSZ = 00 (4096 words for BLS)
All Boot Locks Bits to mode 1 (no lock at all)

At start of code, program :
MCUCR = (1<<IVCE);
MCUCR = (1<<IVSEL); to put interrupt vector in LBS

Hope that helps.
Don't give up...

Yannick Podgorski
www.kuantic.com

----- Original Message ----- From: "Martin Bammer" <address@hidden>
To: "Yannick PODGORSKI" <address@hidden>
Sent: Monday, February 07, 2005 11:51 AM
Subject: Re: [avr-gcc-list] Problems programming flash


Hi,

I tried the example in avr-libc docu -> DOESN'T WORK
I tried the example in boot.h -> DOESN'T WORK
I tried the example in ATMega.PDF -> DOESN'T WORK

I'm really out of ideas :-((((
Is maybe my makefile wrong??
Here the compile outputs:
avr-gcc -c -mmcu=atmega128 -I. -g -Os -funsigned-char -funsigned-bitfields
-fpack-struct -fshort-enums -Wall -Wstrict-prototypes
-Wa,-adhlns=bootloader.lst  -std=gnu99 bootloader.c -o bootloader.o

Linking: bootloader.elf
avr-gcc -mmcu=atmega128 -I. -g -Os -funsigned-char -funsigned-bitfields
-fpack-struct -fshort-enums -Wall -Wstrict-prototypes
-Wa,-adhlns=bootloader.o -std=gnu99 bootloader.o --output bootloader.elf
-Wl,-Map=bootloader.map,--cref -lm -Wl,--section-start=.text=F000

Creating load file for Flash: bootloader.hex
avr-objcopy -O ihex -R .eeprom bootloader.elf bootloader.hex

Creating load file for EEPROM: bootloader.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O ihex bootloader.elf bootloader.eep

Creating Extended Listing: bootloader.lss
avr-objdump -h -S bootloader.elf > bootloader.lss

Creating Symbol Table: bootloader.sym
avr-nm -n bootloader.elf > bootloader.sym

Hi,
in libc boot.h there is a very good example :

void writePageFlash(uint32_t address_toWrite, uint8_t *buffer_toWrite)
{
  uint16_t i, w;

  cli();

  // Erase page.
  boot_page_erase((uint32_t)address_toWrite);
  while(boot_rww_busy()){
    boot_rww_enable();
  }

  // Fill Temporary Buffer
  for(uint32_t i = address_toWrite; i < address_toWrite + SPM_PAGESIZE; i
+= 2){
    boot_page_fill(i, (i-address_toWrite) + ((i-address_toWrite) << 8));
  }

Yours :
  // Fill Temporary Buffer
for(i = 0; i < SPM_PAGESIZE; i += 2){
    // Set up little-endian word.
    w = (buf[i + 1] << 8)|buf[i] ;    // for me, it is better like this
boot_page_fill(page + (uint32_t) i, w); //put w in temporary buffer
not i
  }

  // Write page.
  boot_page_write((uint32_t)address_toWrite);
  while(boot_rww_busy()){
    boot_rww_enable();
  }

  sei();
}

To read :
In fact, you read a byte and not a word so you must make your "for" like
this :
for (i = 0; i < SPM_PAGESIZE; i ++)       // i++ and not i+=2
        if (pgm_read_byte_far(page + i) != buf[i]) {
            ret = 1;
            break;
      }
You can read your flash and put in a hex file to compare to what you want
to write and
what you really write.
Hope that helps.

Yannick Podgorski
www.kuantic.com

----- Original Message -----
From: "Martin Bammer" <address@hidden>
To: "andi" <address@hidden>
Cc: <address@hidden>
Sent: Monday, February 07, 2005 9:31 AM
Subject: Re: [avr-gcc-list] Problems programming flash

> Hi!
>
> I've put all code into the bootloader section. Fuses are correctly set > (I
> hope). I can't see the bug :-(
>
> bootloader.elf  :
> section      size       addr
> .data        0xb0   0x800100
> .text       0xefe     0xf000
> .bss        0x208   0x8001b0
> .noinit       0x0   0x8003b8
> .eeprom       0x0   0x810000
> .stab      0x1d40        0x0
> .stabstr    0xc0f        0x0
> Total      0x3b05
>
>
> Disassembled C-function:
>
> uint8_t flash_wr_page(uint32_t page, uint8_t *buf)
> {
>    f3f2:       bf 92           push    r11
>    f3f4:       cf 92           push    r12
>    f3f6:       df 92           push    r13
>    f3f8:       ef 92           push    r14
>    f3fa:       ff 92           push    r15
>    f3fc:       0f 93           push    r16
>    f3fe:       1f 93           push    r17
>    f400:       cf 93           push    r28
>    f402:       df 93           push    r29
>    f404:       8b 01           movw    r16, r22
>    f406:       9c 01           movw    r18, r24
>    f408:       6a 01           movw    r12, r20
>    uint16_t i, w;
>    uint8_t  sreg, ret = 0;
>    f40a:       bb 24           eor     r11, r11
>
>    sreg = SREG;
>    f40c:       ef b6           in      r14, 0x3f       ; 63
>    cli();
>    f40e:       f8 94           cli
>    eeprom_busy_wait();
>    f410:       e1 99           sbic    0x1c, 1 ; 28
>    f412:       fe cf           rjmp    .-4             ; 0xf410
>    boot_page_erase(page);
>    f414:       80 91 68 00     lds     r24, 0x0068
>    f418:       80 fd           sbrc    r24, 0
>    f41a:       fc cf           rjmp    .-8             ; 0xf414
>    f41c:       e1 99           sbic    0x1c, 1 ; 28
>    f41e:       fe cf           rjmp    .-4             ; 0xf41c
>    f420:       83 e0           ldi     r24, 0x03       ; 3
>    f422:       f8 01           movw    r30, r16
>    f424:       20 93 5b 00     sts     0x005B, r18
>    f428:       80 93 68 00     sts     0x0068, r24
>    f42c:       e8 95           spm
>    boot_spm_busy_wait();
>    f42e:       80 91 68 00     lds     r24, 0x0068
>    f432:       99 27           eor     r25, r25
>    f434:       bc 01           movw    r22, r24
>    f436:       61 70           andi    r22, 0x01       ; 1
>    f438:       70 70           andi    r23, 0x00       ; 0
>    f43a:       80 fd           sbrc    r24, 0
>    f43c:       f8 cf           rjmp    .-16            ; 0xf42e
>    for (i = 0; i < SPM_PAGESIZE; i += 2) {
>    f43e:       ab 01           movw    r20, r22
>    f440:       f1 e0           ldi     r31, 0x01       ; 1
>    f442:       ff 2e           mov     r15, r31
>    f444:       e6 01           movw    r28, r12
>        // Set up little-endian word.
>        w = buf[i] | (buf[i + 1] << 8);
>    f446:       88 81           ld      r24, Y
>    f448:       68 2f           mov     r22, r24
>    f44a:       77 27           eor     r23, r23
>    f44c:       89 81           ldd     r24, Y+1        ; 0x01
>    f44e:       99 27           eor     r25, r25
>    f450:       98 2f           mov     r25, r24
>    f452:       88 27           eor     r24, r24
>    f454:       68 2b           or      r22, r24
>    f456:       79 2b           or      r23, r25
>        boot_page_fill(page + i, w);
>    f458:       80 91 68 00     lds     r24, 0x0068
>    f45c:       80 fd           sbrc    r24, 0
>    f45e:       fc cf           rjmp    .-8             ; 0xf458
>    f460:       e1 99           sbic    0x1c, 1 ; 28
>    f462:       fe cf           rjmp    .-4             ; 0xf460
>    f464:       ca 01           movw    r24, r20
>    f466:       aa 27           eor     r26, r26
>    f468:       bb 27           eor     r27, r27
>    f46a:       80 0f           add     r24, r16
>    f46c:       91 1f           adc     r25, r17
>    f46e:       a2 1f           adc     r26, r18
>    f470:       b3 1f           adc     r27, r19
>    f472:       0b 01           movw    r0, r22
>    f474:       fc 01           movw    r30, r24
>    f476:       a0 93 5b 00     sts     0x005B, r26
>    f47a:       f0 92 68 00     sts     0x0068, r15
>    f47e:       e8 95           spm
>    f480:       11 24           eor     r1, r1
>    f482:       4e 5f           subi    r20, 0xFE       ; 254
>    f484:       5f 4f           sbci    r21, 0xFF       ; 255
>    f486:       22 96           adiw    r28, 0x02       ; 2
>    f488:       4f 3f           cpi     r20, 0xFF       ; 255
>    f48a:       51 05           cpc     r21, r1
>    f48c:       e1 f2           breq    .-72            ; 0xf446
>    f48e:       d8 f2           brcs    .-74            ; 0xf446
>    }
>    boot_page_write(page);     // Store buffer in flash page.
>    f490:       80 91 68 00     lds     r24, 0x0068
>    f494:       80 fd           sbrc    r24, 0
>    f496:       fc cf           rjmp    .-8             ; 0xf490
>    f498:       e1 99           sbic    0x1c, 1 ; 28
>    f49a:       fe cf           rjmp    .-4             ; 0xf498
>    f49c:       85 e0           ldi     r24, 0x05       ; 5
>    f49e:       f8 01           movw    r30, r16
>    f4a0:       20 93 5b 00     sts     0x005B, r18
>    f4a4:       80 93 68 00     sts     0x0068, r24
>    f4a8:       e8 95           spm
>    boot_spm_busy_wait();
>    f4aa:       80 91 68 00     lds     r24, 0x0068
>    f4ae:       80 fd           sbrc    r24, 0
>    f4b0:       fc cf           rjmp    .-8             ; 0xf4aa
>
>    // Reenable RWW-section again. We need this if we want to jump back
>    // to the application after bootloading.
>    boot_rww_enable();
>    f4b2:       80 91 68 00     lds     r24, 0x0068
>    f4b6:       80 fd           sbrc    r24, 0
>    f4b8:       fc cf           rjmp    .-8             ; 0xf4b2
>    f4ba:       e1 99           sbic    0x1c, 1 ; 28
>    f4bc:       fe cf           rjmp    .-4             ; 0xf4ba
>    f4be:       81 e1           ldi     r24, 0x11       ; 17
>    f4c0:       80 93 68 00     sts     0x0068, r24
>    f4c4:       e8 95           spm
>    f4c6:       d6 01           movw    r26, r12
>    f4c8:       a9 01           movw    r20, r18
>    f4ca:       98 01           movw    r18, r16
>    f4cc:       b6 01           movw    r22, r12
>    f4ce:       61 50           subi    r22, 0x01       ; 1
>    f4d0:       7f 4f           sbci    r23, 0xFF       ; 255
>
>    for (i = 0; i < SPM_PAGESIZE; i += 2)
>        if (pgm_read_byte_far(page + i) != buf[i]) {
>    f4d2:       4b bf           out     0x3b, r20       ; 59
>    f4d4:       f9 01           movw    r30, r18
>    f4d6:       97 91           elpm    r25, Z+
>    f4d8:       8c 91           ld      r24, X
>    f4da:       12 96           adiw    r26, 0x02       ; 2
>    f4dc:       98 17           cp      r25, r24
>    f4de:       19 f0           breq    .+6             ; 0xf4e6
>            ret = 1;
>    f4e0:       11 e0           ldi     r17, 0x01       ; 1
>    f4e2:       b1 2e           mov     r11, r17
>            break;
>    f4e4:       07 c0           rjmp    .+14            ; 0xf4f4
>    f4e6:       2e 5f           subi    r18, 0xFE       ; 254
>    f4e8:       3f 4f           sbci    r19, 0xFF       ; 255
>    f4ea:       4f 4f           sbci    r20, 0xFF       ; 255
>    f4ec:       5f 4f           sbci    r21, 0xFF       ; 255
>    f4ee:       6a 17           cp      r22, r26
>    f4f0:       7b 07           cpc     r23, r27
>    f4f2:       78 f7           brcc    .-34            ; 0xf4d2
>        }
>
>    // Re-enable interrupts (if they were ever enabled).
>    SREG = sreg;
>    f4f4:       ef be           out     0x3f, r14       ; 63
>    return ret;
> }
>
>
> Fuses:
> Atmel AVR ATmega128 is found.
> Firmware Version: 1.14
>
> Fuse Low Byte      = 0x33
> Fuse High Byte     = 0xd0
> Fuse Extended Byte = 0xff
> Calibration Byte   = 0xa7  --  Read Only
> Lock Bits          = 0xff
>    BLB12 -> 1
>    BLB11 -> 1
>    BLB02 -> 1
>    BLB01 -> 1
>      LB2 -> 1
>      LB1 -> 1
>
>> Hi, Martin
>>
>> If you want to program flash, you have to put the procedure in boot
>> loader
>> section. The way to put the procedure to bootloader is :
>>
>> uint8_t BOOTLOADER_SECTION flash_wr_page(uint32_t page, uint8_t *buf)
>> {
>> //.....routine
>> }
>>
>> Regards,
>>
>> Andi
>>
>>
>> uint8_t flash_wr_page(uint32_t page, uint8_t *buf)
>>
>> ------------------------------------------------------------------------
>>--- ----------- Hi list!
>>
>> I'm trying to write a bootloader for the ATMega128 in C.
>> Everything works fine, but the programming of the flash.
>> I've taken the subroutine from the avr-libc page which is listed >> below.
>> The version of the avr-libc I'm using is 1.0.5 (Debian Package).
>> What is wrong with the subroutine below?
>>
>> uint8_t flash_wr_page(uint32_t page, uint8_t *buf)
>> {
>>     uint16_t i, w;
>>     uint8_t  sreg, ret = 0;
>>
>>     sreg = SREG;
>>     cli();
>>     eeprom_busy_wait();
>>     boot_page_erase(page);
>>     boot_spm_busy_wait();
>>     for (i = 0; i < SPM_PAGESIZE; i += 2) {
>>         // Set up little-endian word.
>>         w = buf[i] | (buf[i + 1] << 8);
>>         boot_page_fill(page + i, i);
>>     }
>>     boot_page_write(page);     // Store buffer in flash page.
>>     boot_spm_busy_wait();
>>
>> // Reenable RWW-section again. We need this if we want to jump >> back
>>     // to the application after bootloading.
>>     boot_rww_enable();
>>
>>     for (i = 0; i < SPM_PAGESIZE; i += 2)
>>         if (pgm_read_byte_far(page + i) != buf[i]) {
>>             ret = 1;
>>             break;
>>         }
>>
>>     // Re-enable interrupts (if they were ever enabled).
>>     SREG = sreg;
>>     return ret;
>> }
>>
>> Cheers, Martin
>
> _______________________________________________
> avr-gcc-list mailing list
> address@hidden
> http://www.avr1.org/mailman/listinfo/avr-gcc-list

_______________________________________________
avr-gcc-list mailing list
address@hidden
http://www.avr1.org/mailman/listinfo/avr-gcc-list


reply via email to

[Prev in Thread] Current Thread [Next in Thread]