Brian, You were right. I had avr's word-addressing confused with gcc's byte-addressing. I upgraded the AVR Studio to the latest version (same as yours: 4.13 build 528) and 100% correctly simulated & emulated my flash programming routine.
The problem is that the actual execution doesn't yield the same results. In fact, the problem isnt flash-programming-related at all... I am having unexpected resets when executing code located outside of the .text section. When it's a plain 'while(1);', which gets translated into a 'rjmp .-2', its fine. But as soon as theres some kind of logic (write access to global variables, call to libc routine, etc...), the processor resets very shortly after the execution of the 'call' instruction. And this happens whether I put the .bootloader section at byte-address 0xfc00 or 0xa000 or anywhere else i tried. So it happens whether or not the code is located in the BLS or the Application memory region. Again, theres no call to SPM or LPM. It might not be an actual reset because all bits in the MCUSR register are cleared. So it could be a jmp to address 0, but it doesn't make more sense... Again, the sims run perfectly... Anyone experienced similar behaviour on the mega644? Thanks. Pat Mahoney -----Original Message----- From: Brian Sidebotham [mailto:[EMAIL PROTECTED] Sent: August 21, 2007 11:40 AM To: Patrick Mahoney Cc: [email protected] Subject: Re: [avr-libc-dev] Problem writing to flash - atmega644 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) ; } _______________________________________________ AVR-libc-dev mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
