|
ARM gcc, вызвать THUMB функцию из ROM |
|
|
|
Aug 27 2014, 17:02
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Я что-то запутался... Как мне объявить внешнюю thumb функцию, расположенную по заданному статическому адресу? Я сделал вот так: 1) arm-rom.h Код int rom_func (void* dev_descr, int data); 2) скрипт для линкера Код .... SECTIONS { .... rom_func = 0x123456; } Все тут хорошо, но линкер думает, что rom_func следует исполнять как ARM, а не как THUMB, и генерирует соотв. BLX инстукцию (при вызове из THUMB кода). А как мне указать, что он THUMB?
|
|
|
|
|
Aug 27 2014, 18:23
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Проблему сам решил, через ж. автогеном. Сделал ассемблерный файл rom_funcs.S, внутри которого написал: Код .globl rom_func .thumb_set rom_func, 0x123456 Ну и прилинковал получившийся объектный модуль в общую кучу. А из скрипта линкера убрал указание адреса. В результате вызов из THUMB-кода по BL, что и требовалось. ----- Но вопрос остался - а не через зад, можно? Прямо линкеру указать, что этот символ thumb и имеет такое-то значение?
|
|
|
|
|
Aug 28 2014, 05:58
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(jcxz @ Aug 28 2014, 06:02)  for IAR Спасибо, конечно, но в теме было про gcc. Никаких IAR там быть не может. Это около-линуксовая тема. Обхожу баг ROM-загрузчика AM3517, который не может загрузить из NAND больше 2К кода, если NAND имеет размер страницы больше, чем 2К. Цитата(den_po @ Aug 28 2014, 02:17)  а в качестве адреса указывать адрес функции +1 Проверено, при этом линкер при оптимизации накладывает маску на адрес 0xFFFFFFF8, чем убивает и +1, и если код находится на смещениях +2 (если gcc понимает, что указатель можно соптимизировать в прямой вызов). И генерирует команды перехода BLX... В общем, мимо. Можно, конечно, volatile указатель объявить, но не хочется указатели, хочется прямой вызов сделать корректно (без asm).
|
|
|
|
|
Aug 28 2014, 10:20
|
Частый гость
 
Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315

|
Цитата(SM @ Aug 28 2014, 09:58)  Проверено, при этом линкер при оптимизации накладывает маску на адрес 0xFFFFFFF8, чем убивает и +1 И с какой, интересно, стати? Или речь о непосредственном операнде? Тут такое дело, если из арм кода вызывается BLX 0x123456 (обратите внимание - чётно), то оно переключает в тумбу. Может лажанул с кратностью 2, но сути не меняет, чётный адрес в непосредственном операнде BLX переключит режим.
Сообщение отредактировал den_po - Aug 28 2014, 10:32
|
|
|
|
|
Aug 28 2014, 10:36
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(SM @ Aug 27 2014, 21:02)  Я сделал вот так: 1) arm-rom.h Код int rom_func (void* dev_descr, int data); А если так: Код int __attribute__((interfacethumb)) rom_func (void* dev_descr, int data);
|
|
|
|
|
Aug 28 2014, 10:41
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(den_po @ Aug 28 2014, 14:20)  И с какой, интересно, стати? Или речь о непосредственном операнде? О непосредственном. То есть, когда gcc понимает, что указатель можно заоптимизировать до его смерти. При этом линкер, не видя какого-то атрибута, что адрес, куда перейти, относится к thumb режиму, обнуляет ему младшие два бита принудительно, причем без всяких варнингов. Да и ручное прибавление единицы к адресу в указателе, это еще более мощный автоген в ж., чем ассемблерный .thumb_set Цитата(scifi @ Aug 28 2014, 14:36)  А если так: То так: warning: 'interfacethumb' attribute directive ignored [-Wattributes] gcc 4.7.2 PS И, все наоборот - в тумбу переключает нечетный адрес, и при этом в тумбе адресация кратна двум. А четный адрес переключает в ARM, и там кратность уже равна четырем.
|
|
|
|
|
Aug 28 2014, 12:44
|
Частый гость
 
Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315

|
Цитата(SM @ Aug 28 2014, 14:41)  О непосредственном. То есть, когда gcc понимает, что указатель можно заоптимизировать до его смерти. При этом линкер, не видя какого-то атрибута, что адрес, куда перейти, относится к thumb режиму, обнуляет ему младшие два бита принудительно, причем без всяких варнингов. Кто-то из нас что-то недопонимает. Если адрес thumb функции N*4, на выходе из предложенного мной кода получается обычно один из двух вариантов: 1) BLX (N*4) 2) LDR Rx, =N*4+1 BLX Rx Если адрес thumb функции N*4+2, на выходе получается один вариант: LRD Rx, =N*4+2+1 BLX Rx У вас какой-то другой результат получается? Цитата(SM @ Aug 28 2014, 14:41)  Да и ручное прибавление единицы к адресу в указателе, это еще более мощный автоген в ж., чем ассемблерный .thumb_set Чем это хуже использования заданного статического адреса?
Сообщение отредактировал den_po - Aug 28 2014, 12:47
|
|
|
|
|
Aug 28 2014, 13:09
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(den_po @ Aug 28 2014, 16:44)  У вас какой-то другой результат получается? Естественно, другой. - Если я делаю вызов ф-ции, описанной по .thumb_set из THUMB-кода, то я получаю BL N*2 ; thumb -> thumb - Если я делаю вызов ф-ции, описанной по .set из THUMB-кода, то я получаю BLX N*4 ; thumb -> arm - Если я делаю вызов ф-ции, описанной по .thumb_set из ARM-кода, то я получаю (должен получить, не пробовал, не надо) BLX N*2+1 ; arm -> thumb - Если я делаю вызов ф-ции, описанной по .set из ARM-кода, то я получаю BL N*4 ; arm -> arm ну, естественно, линкеру дана опция ком. строки --use-blx, иначе она всякий там гемор с регистрами генерирует Цитата(den_po @ Aug 28 2014, 16:44)  Чем это хуже использования заданного статического адреса? Тем, что линкер/компилятор разбираются сами, где там +1 сделать, где не сделать, где BL поставить, где BLX. (тем более, докучи, откуда компилятор узнает, что при переходе по указателю нужен будет BLX, а не BL). Собственно, вопрос то не в этом. Вопрос - как уйти от .thumb_set и ассемблера, по аналогии с IAR-овским __thumb
|
|
|
|
|
Aug 29 2014, 03:53
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Сергей Борщ @ Aug 28 2014, 18:02)  Там есть еще одна фигня - линкер может вставлять BX просто потому, что для B не хватает дальности "прыжка". Линкёр команды не генерит. Максимум, что он может - вставить врапперы (или как оно там называется), когда видит, что цель перехода - вне пределов досягаемости. Когда компилятор генерит выходные секции из исходника, то внутри секции он может вычислить расстояния переходов, и соответственно - использовать команду перехода с непосредственным смещением в теле. Если же переход идёт в другую секцию, то расстояние станет известно только на этапе компоновки, а значит при компиляции оно не известно. Тогда линкёр может вставить враппер с косвенным переходом внутри для увеличения длины перехода. А в данном случае переход идёт из перемещаемой области (для компилятора её адрес не известен) в константный адрес. Тут само собой нужен BX сразу без всяких доп. врапперов.
|
|
|
|
|
Aug 29 2014, 05:33
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(jcxz @ Aug 29 2014, 06:41)  если BX Не BX, а BLX, речь только о BLX с непосредственной адресацией. Ее отличие от BL (тоже с непосредственной адресацией) только в том, что она переключает режим ARM/THUMB, а BL - нет. Собственно, первоисточник - http://infocenter.arm.com/help/index.jsp?t...c/Cihfddaf.htmlBLX Label, как и BL Label, имеют зону досягаемости +-32 Мбайт. И, вообще, повторю в стодвадцатый раз уже. Генерация кода происходит так, как мне надо, если для задания адреса ф-ции я использую ассемблерный .thumb_set (собственно, все уже работает, красоты не хватает). Вопрос в том, как сделать без ассемблера так, чтобы вызовы были при помощи непосредственной адресации и корректными (иначе чутка не влезаю в нужный мне размер кода), то есть я хочу описать средствами С и/или линкера THUMB-функцию, расположенную вне моего кода в ROM, так, чтобы при генерации кода она вызывалась через BL/BLX с непосредственной адресацией.
|
|
|
|
|
Aug 29 2014, 06:40
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(Golikov A. @ Aug 29 2014, 10:31)  А у меня есть другое предложение, а что если вам сделать переход все равно какой, а переключиться на thumb режим уже внутри вашей функции? У меня задача обратная  Мне надо НЕ переключаться в ARM, при вызове ROM-функций (они находятся по фиксированным адресам в ROM (в бутлоадере) в процессоре, и все имеют thumb-код), из моего кода, который тоже THUMB. А по умолчанию gcc считает, что такая функция, объявленная заданием адреса через скрипт линкера, она ARM. При этом без излишеств, так как у меня всего 500 байт есть на весь мой код... С .thumb_set я уложился в 480 байт, но хочу сделать без него, и чтобы с тем же результатом.
|
|
|
|
|
Aug 29 2014, 06:45
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
да пофиг, пусть переключается, вы в функции насильно переключите обратно и дальше поехали, ну потеряете немного тактов, но как я понимаю если пошли по пути экономии памяти, с тактами уже можно прощаться  . В thumb режиме если я не ошибаюсь команда перехода уже не +-32MB, а всего то +-2MB если мы про 16 битный режим, может это как-то влияет на попытки переключится? Еще следить надо что команда перехода с переключением а не выбором режима, то есть надо еще считать число переходов  Цитата При этом без излишеств, так как у меня всего 500 байт есть на весь мой код... С .thumb_set я уложился в 480 байт, да пипец какой-то.... Ваша жизнь создана из ограничений, я ваще не понимаю как вы так существуете  В ПЛИС вы себя ужимаете все до единиц флипфлопов подсчитываете, в процах тоже... Как же вы машину заправляете  ..... Ну если уж так жметесь, то даже не знаю что предложить...
|
|
|
|
|
Aug 29 2014, 06:55
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(Golikov A. @ Aug 29 2014, 10:45)  В thumb режиме если я не ошибаюсь команда перехода уже не +-32MB, а всего то +-2MB В thumb допустимы и 32-битные команды, с ".W" - в общем, блин, нету проблем с этим. Ведь !!!! с .thumb_set все происходит как надо, и проблем нет. Но он мне просто не нравится. Красоты хочется, чтобы без ассемблерной добавки. Цитата(jcxz @ Aug 29 2014, 10:47)  Да, непонятно мне тоже. Почему-бы SM не сделать просто функцию-обёртку этого ROM-вызова, переключаясь внутри этой обёртки в thumb, а вызывая её обычным образом? Вылезаю за допустимый размер. Код + три слова данных (два на хидер и одно в конце моё) должны влезть в один ECC-сектор NAND памяти (512 байт). Цитата(Golikov A. @ Aug 29 2014, 10:45)  Как же вы машину заправляете  ..... Вот тут я отрываюсь по полной!  UPD Я бы, конечно, как это вообще люблю делать (на других процах), написал бы все от начала и до конца на асме... Но дюже неудобный он у ARM-а для писания на нем... Вот и извращаюсь с С.
|
|
|
|
|
Aug 29 2014, 06:59
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(SM @ Aug 29 2014, 12:40)  При этом без излишеств, так как у меня всего 500 байт есть на весь мой код... С .thumb_set я уложился в 480 байт, но хочу сделать без него, и чтобы с тем же результатом. Если вопрос в размере и известно, что расстояние до этих ROM-функций позволяет использовать BL (с его укороченной досягаемостью) и известен стартовый адрес образа вашего кода в памяти, то можно в асм-файле определить команды перехода на ROM-функции как обычные константы (не знаю как в gcc, но в IAR): wrap_funcX: DC16 XXXX ;здесь код команды безусловный B с непосредственным 11-битным смещением описать wrap_funcX как функцию, прилинковать в известное место (по известному смещению) своего выходного исполняемого образа и вызывать как обычную функцию.
|
|
|
|
|
Aug 29 2014, 07:03
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(jcxz @ Aug 29 2014, 10:59)  то можно в асм-файле определить Ну елки-палки. С asm-файлом у меня все и без таких извратов работает! Хочется средствами С обойтись. rom_func.h: Код int rom_func (void* dev_descr, int data); rom_func.S: Код .globl rom_func .thumb_set rom_func, 0x123456 и в результате в thumb-коде получается обычный BL 0x123456, что и требуется.
|
|
|
|
|
Aug 29 2014, 07:18
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(SM @ Aug 29 2014, 13:07)  Не хочется вставок и лишнего асма. Это опенсурс проект... Выкладывать его буду в виде патча к x-loader-у для работы с AM3517 с NAND-ами с 4К-страницами, как обход бага его ROM-бутлоадера, связанного с такими NAND. Вряд-ли без асм или intrinsic-функций или без какой другой привязки к компилятору обойдётесь. По-моему это всё ерунда. Лучше-бы тогда уж ROM-бутлоадер OMAP L-137 поправили.  Чтобы он грузился с SPI-флеши находящейся в Sleep-mode. Это, имхо, полезнее.
|
|
|
|
|
Aug 29 2014, 07:35
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(jcxz @ Aug 29 2014, 11:18)  Это, имхо, полезнее. У каждого свое IMHO. Мы купили 1000 NAND-ов с 4К страницами, из них половину запаяли  Не выкидывать же и перепаивать... Об этом баге и в TI не знали... Короче, как я понял, нет другого способа объявить функцию как thumb, кроме как: 1) скомпилировать ее (она должна быть в файле определена вместе с ее телом, то есть не быть внешней) вместе с файлом с указанием ключа -mthumb 2) ассемблерный .thumb_set 3) ассемблерный .thumb_func А чего-то типа __attribute__ ((thumb)) или __thumb в арсенале gcc нет. Итого, объявить внешнюю функцию по заданному адресу можно только методом 2) - .thumb_set. это верные выводы? PS о том, как вызвать некий адрес как thumb или ARM речь не ведется, и не велась. Речь именно про объявление функции средствами C или линкера по заранее заданному адресу.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|