Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AVRGCC+длинные (>64k) байтовые адреса в флеши
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
LordVader
Вводные:
есть атмега128, в ней, в флеше хранятся данные размером больше, чем 64килобайта.

Данные берутся из бинарей и конвертятся в .o по факу.

По факу же и используются:

Код
...
extern const char fpga[] PROGMEM;
extern const char fpga_end[] PROGMEM; // эти символы создаёт avr-objcopy в своём .o, так на них ссылаемся из сорца
...
uint32_t ptr;
...
ptr = fpga_end; // тут _end, чтобы продемонстрировать проблему
...
a=pgm_read_byte_far(ptr++); // этот фрагмент работает как надо, генерит elpm, ставит ROMPZ


Блок данных пихается в начало флешки, а конец уезжает за 64к (*.lss, дизасм)
Код
0000008c <fpga>:
      8c:    ff ff           .word    0xffff; начало
...
...
   17f72:    ff 00           .word    0x00ff; конец

00017f73 <fpga_end>:
    ...


Проблема заключается вот в чём: грузим ptr нужным адресом
Код
   1803a:    83 e7           ldi    r24, 0x73; 115
   1803c:    9f e7           ldi    r25, 0x7F; 127
   1803e:    aa 27           eor    r26, r26
   18040:    97 fd           sbrc    r25, 7
   18042:    a0 95           com    r26
   18044:    ba 2f           mov    r27, r26


Видно, что берутся ТОЛЬКО младшие 16 бит байтового адреса (0x17f73) и расширяются до 32 знаково.

Если брать начало блока, то все как бы хорошо. А если 2 таких блока, и начало 2ого вылезет за пределы 64к? Как правильно ссылаться за пределами 64к байт в флешку?

ps: avr-gcc (GCC) 4.2.2 (WinAVR 20071221)
aesok
Код
/* GET_FAR_ADDRESS() macro

   This macro facilitates the obtention of a 32 bit "far" pointer (only 24 bits
   used) to data even passed the 64KB limit for the 16 bit ordinary pointer. It
   is similar to the '&' operator, with some limitations.

   Comments:

   - The overhead is minimal and it's mainly due to the 32 bit size operation.

   - 24 bit sizes guarantees the code compatibility for use in future devices.

   - hh8() is an undocumented feature but seems to give the third significant byte
     of a 32 bit data and accepts symbols, complementing the functionality of hi8()
     and lo8(). There is not an equivalent assembler function to get the high
     significant byte.

   - 'var' has to be resolved at linking time as an existing symbol, i.e, a simple
     type variable name, an array name (not an indexed element of the array, if the
     index is a constant the compiler does not complain but fails to get the address
     if optimization is enabled), a struct name or a struct field name, a function
     identifier, a linker defined identifier,...

   - The natural place for this macro should be the header avr/pgmspace.h and the
     name... pgm_get_far_address?

   - The returned value is the identifier's VMA (virtual memory address) determined
     by the linker and falls in the corresponding memory region. The AVR Harvard
     architecture requires non overlapping VMA areas for the multiple address spaces
     in the processor: Flash ROM, RAM, and EEPROM. Typical offset for this are
     0x00000000, 0x00800xx0, and 0x00810000 respectively, derived from the linker
     script used and linker options. The value returned can be seen then as a
     universal pointer.

*/

#define GET_FAR_ADDRESS(var)                          \
({                                                    \
    uint_farptr_t tmp;                                \
                                                      \
    __asm__ __volatile__(                             \
                                                      \
            "ldi    %A0, lo8(%1)"           "\n\t"    \
            "ldi    %B0, hi8(%1)"           "\n\t"    \
            "ldi    %C0, hh8(%1)"           "\n\t"    \
            "clr    %D0"                    "\n\t"    \
        :                                             \
            "=d" (tmp)                                \
        :                                             \
            "p"  (&(var))                             \
    );                                                \
    tmp;                                              \
})

Анатолий.
LordVader
Спасибо, aesok, то, что надо! Теперь правильно компилит.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.