Блок с абсолютным адресом в ARM-GCC

Feb 06, 2006 6 Replies

Здравствуйте!



В LPC2106 хочу отвести 3 сектора в старших адресах флешки для хранения:



1 сектор - индентификационная информация (меняется при изгот. девайса или смене версии ПО)
2 --//-- - параметры устройства (могут изменятся юзером по uart`у)
3 --//-- - резервный сектор параметров

Как я понимаю, нужно в линкер срипте разбить флэшку на нужные мне части MEMORY { flash : ORIGIN = 0x00000000, LENGTH = 125K /*FLASH ROM*/ flash_ID : ORIGIN = 0x0001F400, LENGTH = 1K /*идентификатор*/ flash_DP : ORIGIN = 0x0001F800, LENGTH = 1K /*параметры устройства*/ flash_BU : ORIGIN = 0x0001FC00, LENGTH = 1K /*backup sector*/ .... } затем в показать какого типа данные там будут хранится SECTIONS { { *(.text) ........... } >flash /* put all the above into FLASH */



{ *(.rodata) ........... } >flash_ID



{ *(.rodata) ........... } >flash_DP



{ *(.rodata) ........... } >flash_BU



Допустим линкер переварил такой скрипт, а как теперь компилятору показать, что например константа char DeviceID[]="xxxxxxxx LPC2106 v0.00 06.02.2006" должна распологаться в секции flash_ID



Далее, внутри секции flash_DP (это должна быть неиничиализируемая секция) мне нужно, чтобы компилер не оптимизировал расположение переменных, чтобы их положение было каким я его задам, (чтобы потом легко было менять их по последовательному интерфейсу). Например для моторолы на CodeWarrior мне пришлось писать ассемблерный файл с переменными только тогда они перестали "перемешиваться" при компиляции.



В общем какую часть мануалов курить более целенаправленно?



С уважением, Герасимов!



Замути хитовый расколбас


Привет Gerasimov!

06 Feb 06 12:47, Gerasimov Gerasim писал All:

GG> SECTIONS GG> { GG> { GG> *(.rodata) GG> ........... } >> flash_ID

GG> { GG> *(.rodata) GG> ........... } >> flash_DP

Это не будет иметь эффекта, т.к. секция .rodata уже помещена в flash_ID. Ты должен либо указывать конкретные имена модулей:

{ id(.rodata) } >flash_ID { dp(.rodata) } >flash_DP

либо сделать разные имена секций:

{ *(.rodata.id) } >flash_ID { *(.rodata.dp) } >flash_DP

GG> Допустим линкер переварил такой скрипт, а как теперь компилятору GG> показать, что например константа char DeviceID[]="xxxxxxxx LPC2106 GG> v0.00 06.02.2006" должна распологаться в секции flash_ID

Атрибут section.

GG> Далее, внутри секции flash_DP

Путаешься в терминах. Разберись, что называется секцией, а что - регионом памяти.

GG> (это должна быть неиничиализируемая секция)

Для справки: в .rodata как раз размещаются инициализированные объекты.

GG> мне нужно, чтобы компилер не оптимизировал расположение GG> переменных, чтобы их положение было каким я его задам,

Hикак. Hасколько я помню, язык C не позволяет задавать расположение переменных в памяти. Hо ты можешь вместо нескольких переменных разместить данные в полях структуры.

GG> В общем какую часть мануалов курить более целенаправленно?

Cкрипты линкера, атрибуты компилятора, структуры языка C.

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Я удалю твою жажду. Без возможности восстановления.

Спасибо. Покурив "Using ld, the GNU linker"(1994 год) и "Using GNU C __attribute__" сделал так: в скрипте линкера: MEMORY { flash : org = 0, LENGTH = 128K /*FLASH ROM*/ flash_ID : org = 0x00018000, LENGTH = 8K /*12 sector FLASH ROM*/ ........... SECTIONS { .............. ID : { *(.rodata) } >flash_ID ..............

В программе определил соответствующий идентификатор: char DeviceID[] __attribute__ ((section ("ID"))) ="xxxxxxxx LPC2106 v0.00

06.02.2006 Software (C) Gerasimov G.V";

После линковки посмотрел, dmp, map и даже hex, всё на месте, строка DeviceID началась с адреса 0x00018000 как и было задумано.

Но, выяснился отрицательный побочный эффект: загрузчик (которым я пользуюсь) lpc21isp (Copyright (c) by Martin Maurer) не воспинимает,что между последним байтом программы и началом строки DeviceID пропасть из 10 секторов, он пишет все с 0 по 12 сектор,в результате загрузка проги длится ~40 секунд.

Кто с подобным сталкивался? Какой выход? Может линкеру надо сказать, чтоб он в hex`е как-то по другому этот разрыв обозначил?

Я, для начала, сектора с моими данными поближе к коду подтащу.

С уважением, Герасимов.

Замути хитовый расколбас

Вроде с флэшкой определился, но вылез косяк с размещением данных в RAM: пишу в линкер скрипте: MEMORY { ........... ram_usr_struc : org = 0x40008000, LENGTH = 1K /*для доступа ч/з интерфейс*/ ........... }

SECTIONS { ........... usr_struc : { *(.data) } > ram_usr_struc ........... } по идее надо bss задействовать.

в программе определяю структуру которая будет начинаться с адреса 0x40008000: typedef struct { dword P0; dword P1; dword P2; } ram_data;

ram_data ram_view __attribute__ ((section ("usr_struc")));

компилится нормально, в dmp, lst вижу что размещение данных происходит как надо, далее пытаюсь грузить полученный hex, при этом загрузчик вылетает с ошибкой: lpc21isp version 1.28 File main.hex: loaded... Use of multiple Extended linear address records [05] not supported

Прошу помощи клуба.

Замути хитовый расколбас

Привет Gerasimov!

07 Feb 06 08:30, Gerasimov Gerasim писал Alex Mogilnikov:

GG> Покурив "Using ld, the GNU linker"(1994 год) и "Using GNU C GG> __attribute__"

А это что? ИМХО лучше курить мануал от используемой версии программы, чем какой-то документ 12-летней давности.

GG> .............. GG> ID : GG> { *(.rodata) } >flash_ID GG> ..............

В переводе на русский, ты попросил линкер создать секцию ID и поместить туда все секции .rodata

GG> В программе определил соответствующий идентификатор: GG> char DeviceID[] __attribute__ ((section ("ID"))) ="xxxxxxxx LPC2106 GG> v0.00 06.02.2006 Software (C) Gerasimov G.V";

А здесь компилятор поместит DeviceID в секцию ID. Куда линкер поместит секцию ID, из приведенного тобой фрагмента скрипта неясно, но ясно, что в секцию ID он ее не поместит.

GG> После линковки посмотрел, dmp, map и даже hex, всё на месте, строка GG> DeviceID началась с адреса 0x00018000 как и было задумано.

Странно. Или ты не все рассказал, или я чего-то не понимаю...

GG> Hо, выяснился отрицательный побочный эффект: загрузчик (которым я GG> пользуюсь) lpc21isp (Copyright (c) by Martin Maurer) не GG> воспинимает,что между последним байтом программы и началом строки GG> DeviceID пропасть из 10 секторов, он пишет все с 0 по 12 сектор,в GG> результате загрузка проги длится ~40 секунд.

GG> Кто с подобным сталкивался? Какой выход?

Если под загрузчиком подразумевается стартап-код, то модифицировать существующий под свои нужны или вообще написать свой.

GG> Может линкеру надо сказать, чтоб он в hex`е как-то по другому этот GG> разрыв обозначил?

hex тут ни при чем. Загрузчик же не hex загружает, а просто перемещает одни области памяти в другие, типа из ПЗУ в ОЗУ. Опционально выполняет распаковку (часто для экономии места в ПЗУ в него записывают сжатые имиджи).

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Крыскас. Потому что крыса вам доверяет.

Привет Gerasimov!

07 Feb 06 14:49, Alex Mogilnikov писал Gerasimov Gerasim:

GG>> Покурив "Using ld, the GNU linker"(1994 год) и "Using GNU C GG>> __attribute__"

AM> А это что? ИМХО лучше курить мануал от используемой версии AM> программы, чем какой-то документ 12-летней давности.

Уже понял. Это они просто год забывают исправить. :)))

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Программисты и программистки! Выше флаг промежуточного переноса!

Привет!

Естественно я привел не весь скрипт для линкера. Так что как оно работает осталось загадкой. Я начал бится с размещением структур по абсолютным адресам RAM и попал в тот же капкан, документации много, ярких примеров нет. В итоге выбрал самый неказистый путь typedef struct { dword P0; dword P1; dword P2; } ram_data;

#define RAM_DATA_BASE 0x40008000 ram_data *ram_view = (ram_data *) (RAM_DATA_BASE);

Но это ведь неверное решение, лучше же линкером разместить эту структуру в нужной мне области памяти, линкер хоть ошибку выдаст если она с чем нибудь пересечётся, а так навострённые грабли...

Замути хитовый расколбас

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required