avr-libc-dev
[Top][All Lists]
Advanced

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

Re: [avr-libc-dev] Problem writing to flash - atmega644


From: Brian Sidebotham
Subject: Re: [avr-libc-dev] Problem writing to flash - atmega644
Date: Tue, 21 Aug 2007 16:39:46 +0100
User-agent: Thunderbird 2.0.0.6 (Windows/20070728)

Patrick Mahoney wrote:
Good morning Brian,

Thanks for getting back to me.

It is true that my code snippet was iterating over a page number whereas
the required parameter is the full address.

But still... Erasing the page containing address 0 should blank the
first 256 bytes in memory, which contain the reset vector and the
interrupt vector table. The processor should NOT be functional after
such an operation.

Also, I tried using your code snippet as is and didn't work either. I
even tried:
        for (i=0; i<FLASH_PROGRAM_SIZE; i++)
            boot_program_page(i);
... without anymore success.

Why try something you know to be wrong? (stepping over page number instead of page address)

Anyway, I successfully simulated the code pasted below in AVR Studio 4.13 build 528 on a mega644 and the the first page is erased and programmed with zero's correctly.

However, AVR Studio simulates this no matter where the bootloader section starts (i.e. irrelevant of where boot() or boot_program_page() is placed)

Which leads me on to your avr-nm output:
        (...)
        00007e00 T boot_program_page
        00007e76 T CopyMemory

These addresses are in bytes, but the avr uses word addresses. That is to say that the byte address 0x7e00 is in fact address 0x3F00 in the avr. See my nm output, vs the offset shown in the avr studio disassembler:

00007e00 T boot_program_page
00007f0c T boot

and

@00003F00: boot_program_page

So, looks like your linker options are wrong. To get the code in the correct place, you will need -Wl,--section-start,.bootloader=0xFC00

Which gives nm of:

0000fc00 T boot_program_page
0000fd0c T boot

and in avr studio:

@00007E00: boot_program_page

So, nothing to do with avr-libc! ;)

Best Regards,

Brian Sidebotham.

// test.c
#include <inttypes.h>
#include <avr/io.h>
#include <avr/boot.h>
#include <avr/interrupt.h>

void boot_program_page (uint32_t page, uint8_t *buf) BOOTLOADER_SECTION;
void boot_program_page (uint32_t page, uint8_t *buf)
{
    uint16_t i;
    uint8_t sreg;

    // Disable interrupts.

    sreg = SREG;
    cli();

    eeprom_busy_wait ();

    boot_page_erase (page);
    boot_spm_busy_wait ();      // Wait until the memory is erased.

    for (i=0; i<SPM_PAGESIZE; i+=2)
    {
        // Set up little-endian word.
        uint16_t w = *buf++;
        w += (*buf++) << 8;

        boot_page_fill (page + i, w);
    }

    boot_page_write (page);     // Store buffer in flash page.
    boot_spm_busy_wait();       // Wait until the memory is written.

    // Reenable RWW-section again. We need this if we want to jump back
    // to the application after bootloading.

    boot_rww_enable ();

    // Re-enable interrupts (if they were ever enabled).
    SREG = sreg;
}

void boot(void) BOOTLOADER_SECTION;
void boot(void)
{
    unsigned int i;
    unsigned char boot_page[256];

    for (i=0; i<256; i++)
        boot_page[i] = 0;

    for (i=0; i<32768; i+=SPM_PAGESIZE)
        boot_program_page(i, boot_page);

    while(1) ;
}


void main(void)
{
    boot();

    while(1) ;
}




reply via email to

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