Цитата(demiurg_spb @ Jul 7 2008, 11:18)

Сейчас я использую макрос такого плана:
Код
#define pgm_read_ptr(address) ((void*)pgm_read_word(address))
Но программа переваливает за 64К и гипотетически возможны проблемы.
Т.к. указатели на данные могут быть 3-х байтными.
Может кто-нибудь написал универсальный макрос - поделитесь информацией...
pgmspace.h имеет и макросы pgm_read_word_far() и т.п. - для доступа через ELPM ко всей памяти кода.
Но в простом применении
Код
int PROGMEM fi =1;
int i;
i = pgm_read_word_far( &fi);
Указатель усекается до 16 бит и потом знаково расширяется до 32 бит, т.е. выходит кака. По ссылке от Анатолия лежит дополнение - функции str*_PF для работы с данными во всей флеш-памяти и макрос GET_FAR_ADDRESS(var)
Это работает корректно:
Код
i = pgm_read_word_far( GET_FAR_ADDRESS(fi) ); // без '&' !!!
Одна беда - секция трамплинов (находящаяся в нижней памяти таблица jmp на те функции в верхней памяти, от которых брался адрес), о которой говорил Анатолий, в линкерном скрипте находится после секции констант.
Код
*(.vectors)
KEEP(*(.vectors))
/* For data that needs to reside in the lower 64k of progmem. */
*(.progmem.gcc*)
*(.progmem*)
__trampolines_start = .;
/* The jump trampolines for the 16-bit limited relocs will reside here. */
*(.trampolines)
*(.trampolines*)
__trampolines_end = .;
/* For future tablejump instruction arrays for 3 byte pc devices.
We don't relax jump/call instructions within these sections. */
*(.jumptables)
*(.jumptables*)
/* For code that needs to reside in the lower 128k progmem. */
*(.lowtext)
*(.lowtext*)
__ctors_start = .;
*(.ctors)
__ctors_end = .;
в результате чего при росте массивов констант трамплины вылетауют сверх 64 раньше и "указатель на функцию" в виде указателя на jmp тоже становится 3-байтовым. Т.е. при таких объёмах констант становится невозможным использовать указатели на функции.
Цитата(aesok @ Jul 7 2008, 13:44)

С указателями на функции проблем нет, даже для 256КБ контроллеров.
Пока константы не вытолкают трамплины слишком высоко (впрочем, при этом будет сообщение об ошибке на взятие адреса функции).
Может, лучше сразу секции .trampolines и .lowtext* поместить перед .progmem*? "им нужнее"
К этому просится какой-то PROGMEM_FAR и секция .progmem_far, которая в линкерном скрипте сразу расположена после всего кода. Таким образом можно будет сразу выделять константные данные, обращение к которым через длинные указатели uint_farptr_t и функции _PF устраивает, а в PROGMEM размещать только то, к чему хочется обеспечить более быстрый доступ более короткими макросами pgm_read_*_near().