Цитата(impatt @ Nov 8 2006, 12:09)

Боюсь, что нет, но позже погляжу: gcc не заточен на микроконтроллеры, он вообще ни на что не заточен. Потому там понятие FLASH вне закона вообще. Что можно сделать, так это, например, не копировать секцию .data в RAM, и как-то заставить линкер подставлять указатель нужным образом. Вообще-то я эту кухню не очень хорошо знаю.
GCC это компилятор стандартного языка C!!!
Первое: В стандартном C есть только ОДИН вид указателя, указатель на ячейку памяти. Нет указателя на флеш, на EEPROM на порты ввода/выводы..... только один указатель который должен ссылаться на все. НО: В стандартном C размер типа 'указателя' равен размеру типа 'int', для AVR-GCC - 16-бит.
И тут для AVR-GCC начинаться проблемы.
У AVR можно насчитать четыре адресных пространства:
1. RAM до 64KB;
2. EEPROM - обычно до несколько килобайт, но есть микросхемы с 144 КВ.
3. Байт адресуемая флеш (когда используется для хранения данных) до 256 КБ на ATmega2560.
4. Память программ до 128Кслов на ATmega2560.
Можно ко всей этой памяти обращаться с помощью одного 16-ти битного указателя? НЕТ НЕЛЬЗЯ!!! А ЕСТЬ ТОЛЬКО ОДИН! И НАДО!!!
Теоретически можно избежать всех проблем если сделать указатель 32-х битным... но представьте себе на сколько возрастет размер кода. А еще и int тоже будет 32-х битным.
Приходиться выкручиваться и применять разные нестандартные средства. В GCC это атрибуты. С помощью атрибутов компилятору указывается в какой памяти разместить переменную.
В RAM, без атрибутов. Во флеш:
char __attribute__((__progmem__)) str[] = "Строка";
или тоже самое:
prog_char str[] PROGMEM = "Строка";
Дальше, в GCC оператор присваивания не работает с переменными которые размещены во флеш (и EEPROM тоже). Например:
prog_char с1 = 'A';
char c2;
c2 = c1;
c2 не будет присвоено значение переменной с1 (А), а будет присвоено значение из адреса &с1, но не из флеш а из адресного пространства RAM. Надо писать:
c2 = pgm_read_byte(&c1);
И наконец ответ на ваш вопрос: разместить строку во флеш и передать в функцию указатель на нее, не объявляя переменную можно так:
puts_P (PSTR("test\n"));
Но внутри функции символы из этой строки вы должны получать используя макрос pgm_read_byte():
puts_P (PGM_P str)
{
char c;
....
c = pgm_read_byte(str);
....
}
Анатолий.
PS: Ответы на другие вопросы: "Что будет если стока не попадет в нижние 64К флеша?", "Почему для ATmega256 хватает 16-ти битноко указателя для 128 Кслов?" - дам если спросити.