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

 
 
> Внедрение бинарных данных в код, Как прилинковать бинарник и обратиться к этим данным в AVR GCC
ARV
сообщение Nov 27 2008, 15:17
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Задумал разместить некие данные из внешнего файла внутри прошивки. Разобрался, как сгенерировать объектный файл, как его прилинковать. написано, что при этом "определяются 2 символа вида _binary_XXXX_bin_start и _binary_XXXX_bin_end" - ну, это, как я понимаю, все и так знают (кстати, оказалось, что написано неверно в доке! там говорится, что эти символы с подчеркиванием на конце, а на самом деле подчеркивания нет!). НО!
теперь вопрос: как правильно орагнизуется последующее обращение к этим внедренным данным?

допустим, я делаю так:
Код
#include <avr/pgmspace.h>
extern PROGMEM uint8_t _binary_XXXX_bin_start[];
extern PROGMEM uint8_t _binary_XXXX_bin_end[];

PGM_P ptr = (void*)&_binary_XXXX_bin_start;
while (ptr != (void*)&_binary_XXXX_bin_end){
   PORTB = pgm_read_byte(ptr);
   ptr++;
}

вроде бы работает (судя по листингу), но:
1. мне не нравится эта реализация (как-то криво все написано), да и ворнинги получаются... дескать, указатель сравнивается с целым...
2. не очень понятно, как правильно организовать указатель на внедренный блок, если его размер больше 64К (т.е. для pgm_read_byte_far)

попытки приводить типы (указатель к целому) для последующего сравнения получаются еще более кривыми... хочется красоты и правильности.

есть какие-то дельные советы по этой теме?

Сообщение отредактировал ARV - Nov 27 2008, 15:20


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
aesok
сообщение Nov 27 2008, 17:07
Сообщение #2


Знающий
****

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



Цитата(ARV @ Nov 27 2008, 18:17) *
дельные советы по этой теме?


Ипользуйте макрос GET_FAR_ADDRESS

Код
/* 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;                                              \
})


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



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

 


RSS Текстовая версия Сейчас: 26th July 2025 - 22:40
Рейтинг@Mail.ru


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