[Top][All Lists]

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

RE: [avr-gcc-list] String in flash access in Boot Loader Atmega1280

From: Yannick PODGORSKI
Subject: RE: [avr-gcc-list] String in flash access in Boot Loader Atmega1280
Date: Tue, 25 Sep 2007 12:36:43 +0200

Thanks for your answer but I worked like this before.
In fact, I used :
const char GSM_MODULE_SEND_GETNETSTATE[] PROGMEM = "\rat+creg\r";
void main (void)
void CSendCmdGsmModule(PGM_P chaine) {
  char c;
  while((c=PgmReadByte(chaine++))){   // with #define PgmReadByte(x)   pgm_read_byte_far((uint32_t)x)
and LDFLAGS += -Wl,-Ttext=0x1E000
But it doesn't work. The pgm_read_byte_far seems not work.
Maybe I forget something...

De : Martin Fárek [mailto:address@hidden
Envoyé : lundi 24 septembre 2007 18:51
À : address@hidden
Cc : address@hidden
Objet : Re: [avr-gcc-list] String in flash access in Boot Loader Atmega1280

Yannick PODGORSKI wrote:
I try to program a boot loader on Atmega1280.
My configuration :
 - linux Fedora Core 7,
 - avr libc 1.4.6,
 - avrdude 5.3.1,
 - avrgcc 4.2.0.
I use the program in application section and there is no problem.
When I try to use it in boot loader section, the program starts but I can't access to string in flash.
I use pgm_read_byte_far().
I read in file pgmspace.h :
    \note If possible, put your constant tables in the lower 64 KB and use
    pgm_read_byte_near() or pgm_read_word_near() instead of
    pgm_read_byte_far() or pgm_read_word_far() since it is more efficient that
    way, and you can still use the upper 64K for executable code.
    All functions that are suffixed with a \c _P \e require their
    arguments to be in the lower 64 KB of the flash ROM, as they do
    not use ELPM instructions.  This is normally not a big concern as
    the linker setup arranges any program space constants declared
    using the macros from this header file so they are placed right after
    the interrupt vectors, and in front of any executable code.  However,
    it can become a problem if there are too many of these constants, or
    for bootloaders on devices with more than 64 KB of ROM.
    <em>All these functions will not work in that situation.</em>
Does that really mean that I can't use Boot loader in Atmega1280 ?
How can I access to string in flash ?
If someone can help.
Thanks for answers.

The problem is that you cannot use avr-libc functions (strcpy_P, ...);
You have to write your own functions with direct acces to flash (PGM_READ_BYTE, ...).
This small example works for me (RH9, gcc 3.4.5, libc 1.4.5):

CPU = atmega1280

ifeq ($(TARGET), BOOT)

  CFLAGS        = -pipe -mmcu=${CPU} -Wall -Wextra ${OPTIMIZE} -DBOOT -DROM_START=$(ROM_START) -I$(PWD)/include

endif #ifeq (($TARGET), "BOOT")

c code:
#if ROM_START < 0x10000        // < 64KB
    #define    PGM_READ_BYTE    pgm_read_byte_near
    #define    PGM_READ_WORD    pgm_read_word_near
    #define    PGM_READ_DWORD    pgm_read_dword_near

#if ROM_START >= 0x10000    // > 64KB
    #define    PGM_READ_BYTE    pgm_read_byte_far
    #define    PGM_READ_WORD    pgm_read_word_far
    #define    PGM_READ_DWORD    pgm_read_dword_far

typedef unsigned char BYTE;

// aktion names
const BYTE fu_txt_aktion_00[] PROGMEM = "XRAM hardware test      ";        // TXT_FU_PTR
const BYTE fu_txt_aktion_01[] PROGMEM = "Update table check      ";
const BYTE fu_txt_aktion_02[] PROGMEM = "Service key enabled     ";

// aktion names locations
const BYTE *fu_txt[] PROGMEM = {

void term_write_str_P (const BYTE *s)
    BYTE c;
    while(1) {
        c = PGM_READ_BYTE(s++);
        if (!c) {

void main (void)
    for (i = 0; i < 3; i++) {
        term_write_str_P( (PGM_P) PGM_READ_WORD(&fu_txt[i]) );

reply via email to

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