реклама на сайте
подробности

 
 
> Указатели в PROGMEM
demiurg_spb
сообщение Jul 7 2008, 08:18
Сообщение #1


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Народ! Есть вопрос по поводу указателей хранящихся в памяти данных.

Сейчас я использую макрос такого плана:

Код
#define pgm_read_ptr(address)           ((void*)pgm_read_word(address))


Но программа переваливает за 64К и гипотетически возможны проблемы.
Т.к. указатели на данные могут быть 3-х байтными.

Может кто-нибудь написал универсальный макрос - поделитесь информацией...

Ну или чтобы хоть warning или error на этапе компиляции выскакивал когда ptr>65535.
Предупрежден - значит вооружён!

Сообщение отредактировал demiurg_spb - Jul 7 2008, 08:49


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
demiurg_spb
сообщение Jul 7 2008, 10:31
Сообщение #2


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Спасибо за укрепление духа!
О компоновке данных в flash я знаю.
Хотелось на будущее соломки подстелитьwink.gif
Вдруг в будущем незаметно для себя данные перевалят границу 64К.

А как обстоят дела с указателями на процедуры?
Ведь они могут быть где угодно...

Сообщение отредактировал demiurg_spb - Jul 7 2008, 10:35


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
aesok
сообщение Jul 7 2008, 10:44
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(demiurg_spb @ Jul 7 2008, 14:31) *
Спасибо за укрепление духа!
О компоновке данных в flash я знаю.
Хотелось на будущее соломки подстелитьwink.gif
Вдруг в будущем незаметно для себя данные перевалят границу 64К.


Тогда вы заментите что ваша программа перестала работать.
Если вам действительно нужно больше 63КБ констант, можете постотреть патч для avr-libc здесь
http://savannah.nongnu.org/patch/?6352

Цитата(demiurg_spb @ Jul 7 2008, 14:31) *
А как обстоят дела с указателями на процедуры?
Ведь они могут быть где угодно...


С указателями на функции проблем нет, даже для 256КБ контроллеров.

Анатолий.

Сообщение отредактировал aesok - Jul 7 2008, 10:46
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 8 2008, 06:58
Сообщение #4


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(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().


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
aesok
сообщение Jul 8 2008, 14:18
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(ReAl @ Jul 8 2008, 10:58) *
в результате чего при росте массивов констант трамплины вылетауют сверх 64 раньше и "указатель на функцию" в виде указателя на jmp тоже становится 3-байтовым. Т.е. при таких объёмах констант становится невозможным использовать указатели на функции.


Нет проблем если секции .trampolines и .lowtext* окажутся во вторых 64КБ,
указатели на код это указатели на слово, нужно чтобы они были в нижних 128КБ.
А вот секция .progmem*, для того чтобы работали функции *_p, должна быть в
нижних 64КБ. Проблемы с .trampolines и .lowtext* возникнут когда размер
секции .progmem* приблизиться к 128 КБ.

Цитата(ReAl @ Jul 8 2008, 10:58) *
Может, лучше сразу секции .trampolines и .lowtext* поместить перед .progmem*? "им нужнее"

Нет .progmem* должна быть в нижних 64КБ, а .trampolines и .lowtext* в нижних 128КБ тоесть .trampolines и .lowtext* должны быть после .progmem*.

Цитата(ReAl @ Jul 8 2008, 10:58) *
К этому просится какой-то PROGMEM_FAR и секция .progmem_far, ...


Тут наши мнения совпадают, я с месяц назад в avr-libc-dev предлагал добавить
.progmem_far, принципе с этим согласились, но пока нет времени заняться этим
патчем.

Анатолий.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 21:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01401 секунд с 7
ELECTRONIX ©2004-2016