|
|
  |
Доступ к полям структуры С из ASM, AVR studio, WinAVR |
|
|
|
Mar 6 2008, 09:42
|

Местный
  
Группа: Свой
Сообщений: 272
Регистрация: 17-01-05
Из: Ростов-на-Дону
Пользователь №: 2 018

|
В основном теле программы, написанной на С, используется экземпляр структуры, примерно так: Код // описание структуры struct TStored { .... volatile unsigned short var_1; .... };
// экземпляр struct TStored strd; // .... strd.var_1 = 0x1234; И есть процедура обработки прерывания, написанная на АСМе (файл типа *.s), откуда необходимо получить доступ к полю var_1 структуры strd. Я безуспешно пытался сделать это несколькими способами, насколько хватило фантазии. Сейчас пребываю в тупике. Подскажите, можно ли это сделать, и если да, то как?
--------------------
/* Всё хорошо в меру. */
|
|
|
|
|
Mar 6 2008, 10:09
|

Местный
  
Группа: Свой
Сообщений: 272
Регистрация: 17-01-05
Из: Ростов-на-Дону
Пользователь №: 2 018

|
Цитата(GDI @ Mar 6 2008, 12:52)  Вы бы рассказали о том что пытались сделать и как чтобы пройденные варианты вам не предлагали или чтоб указали на ошибки, если они есть Вот что я пытался сделать: Собственно, нужно написать что-то вроде такого: Код lds r16, var Пока var не была полем структуры, всё работало хорошо. После этого я поместил её в структуру, как указано 1-м посту, и пытался сделать следующее: Код .extern strd.var_1 #define var strd.var_1 и Код .extern strd.var_1 .equ var, strd.var_1 Результаты были одинаковы: (.text+0x6): undefined reference to `strd.var_1'Правда, каюсь, описание структуры не включал в .s файл, сейчас попробую. ============= Попробовал. Ассемблерный компилятор не хочет понимать С-шные описания структур.
--------------------
/* Всё хорошо в меру. */
|
|
|
|
|
Mar 6 2008, 12:02
|

Местный
  
Группа: Свой
Сообщений: 272
Регистрация: 17-01-05
Из: Ростов-на-Дону
Пользователь №: 2 018

|
Решил проблему, относительно красиво. 1. Поместил интересующие поля в самом начале структуры. 2. Окаймил описание структуры с помощью #pragma pack(push, 1) и #pragma pack(pop) (т.к. было неоднократно замечено, что поля в структуре могут физически располагаться не в том порядке, в каком они описаны): Код #pragma pack(push, 1) struct TStored { volatile unsigned short var_1; volatile unsigned short second_var; //...... все остальные поля } #pragma pack(pop) 3. И, наконец, досткп к ним сделал следующим образом: Код .extern strd; .equ var_1, (strd + 0) .equ second_var, (strd + 2) //....... lds r25, var_1 + 1 // High lds r24, var_1 // Low Работает нормально. Если кто найдёт недостатки данного решения, или знает, как сделать лучше - пожалуйста, не стесняйтесь, буду благодарен за советы.
--------------------
/* Всё хорошо в меру. */
|
|
|
|
|
Mar 6 2008, 22:27
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Vitёk @ Mar 6 2008, 16:02)  Решил проблему, относительно красиво. 1. Поместил интересующие поля в самом начале структуры. Честно говоря не совсем понимаю какие проблемы. Для работы на ассемблере как раз удобно использовать структуры. Я так и делаю. Дело в том, что порядок следования переменных для структур гарантирован. Что и даёт право их использовать. Ну а пользоваться лучше так, как это делает компилятор, то есть с помощью STD/LDD относительно начала Ну например. Код struct // Всего 40 байт (8*5) зарезарвировано и передаётся от мастера к слэйву { // Длина структуры должна быть обязательно кратна 5 !!!!! uint8_t Year; // Год uint8_t Month; // Месяц uint8_t Day; // День uint8_t Hour; // Часы uint8_t Minute; // Минуты uint8_t Seconds; // Секунды } Status; В ассемблере Код EXTERN Status
#define Year 0 // +0 #define Month 1 // +1 #define Day 2 // +2 #define Hour 3 // +3 #define Minute 4 // +4 #define Seconds 5 // +5
... ldi Xl,low(Status) ldi Xh,high(Status) ....
ldd wl,X+Minute ; загрузить минуты .... std X+Hour,wh ; сохранить часы .... ; или так .... ldi Xl,low(Status+Seconds) ldi Xh,high(Status+Seconds) lds wl,X+ ; загрузить секунды
|
|
|
|
|
Mar 6 2008, 23:00
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Vitёk @ Mar 6 2008, 15:02)  2. Окаймил описание структуры с помощью #pragma pack(push, 1) и #pragma pack(pop) (т.к. было неоднократно замечено, что поля в структуре могут физически располагаться не в том порядке, в каком они описаны):[code] Порядок гарантирован, а pack, конечно, безвреден для 8bit, но и одновремено совершенно для них бесполезен.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 7 2008, 08:41
|

Местный
  
Группа: Свой
Сообщений: 272
Регистрация: 17-01-05
Из: Ростов-на-Дону
Пользователь №: 2 018

|
SasaVitebsk: Да, примерно так так в конце концов у меня и получилось. С той разницей, что я использовал не указатель, а напрямую адресовал конкретное поле в конкретном экземпляре структуры. И проблемы по большому счёту тоже нет, как Вы правильно заметили. Есть только один момент: при внесении изменений в структуру (а такое иногда бывает), приходится заново вычислять смещение для некоторых её полей (вручную), и менять соотв. дефайны. При создании темы у меня была надежда, что описание структуры (в .h-файле) можно скормить компилятору, что бы он сам проделывал эту работу. Сбыться ей, судя по всему, не судьба. Цитата(zltigo) Порядок гарантирован, а pack, конечно, безвреден для 8bit, но и одновремено совершенно для них бесполезен. У меня были проблемы с порядком размещения полей в структуре, от которых удалось избавиться при помощи #pragma pack. Может я чего не так делал, или настройки проекта неправильные, но победить удалось после её добавления. Вот сама структура: Код union TDate { unsigned char date[3]; struct { union { unsigned short mmdd; struct { unsigned char dd, mm; }; }; unsigned char yy; // }; }; Если есть желание, попробуйте, может у вас будет нормально без прагмы... Если да, дайте знать.
--------------------
/* Всё хорошо в меру. */
|
|
|
|
|
Mar 7 2008, 08:56
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Vitёk @ Mar 7 2008, 12:41)  Есть только один момент: при внесении изменений в структуру (а такое иногда бывает), приходится заново вычислять смещение для некоторых её полей (вручную), и менять соотв. дефайны. При создании темы у меня была надежда, что описание структуры (в .h-файле) можно скормить компилятору, что бы он сам проделывал эту работу. При моём варианте, если добавлять новые поля в конец записи, то ничего делать не надо. Я, думаю, сто % есть способ автоматически генерить поля. Я просто практически отказался от асма в си проектах, ввиду высокой эффективности самого компилятора. Лучше поколдовать с текстом Си, и подсказать компилятору как правильно сделать. Зато сохраняется переносимость. Я вам рекомендую перенести вопрос в раздел по IAR компилятору. Там такие зубры, которые наверняка вам подскажут.
|
|
|
|
|
Mar 7 2008, 09:36
|

Местный
  
Группа: Свой
Сообщений: 272
Регистрация: 17-01-05
Из: Ростов-на-Дону
Пользователь №: 2 018

|
Компилятор у меня WinAVR (указано в комментарии к названию темы). Некоторые вещи он компилит совершенно безобразно, поэтому приходится делать на асме. Способ генерить поля может и есть, но чутьё подсказывает, что это маловероятно. Такое ощущение, что компиляторы для С и для АСМ сделаны независимо, и пересекаются слабо. В любом случае, спасибо.  ЗЫ: попрошу модераторов перенести тему в раздел с соотв. компилятором.
--------------------
/* Всё хорошо в меру. */
|
|
|
|
|
Mar 7 2008, 11:43
|

Частый гость
 
Группа: Новичок
Сообщений: 111
Регистрация: 10-02-07
Из: St.Petersburg, Russia
Пользователь №: 25 241

|
Цитата(Vitёk @ Mar 6 2008, 12:42)  Код // описание структуры struct TStored { .... volatile unsigned short var_1; .... };
// экземпляр struct TStored strd; // .... strd.var_1 = 0x1234; И есть процедура обработки прерывания, написанная на АСМе (файл типа *.s), откуда необходимо получить доступ к полю var_1 структуры strd. Надо знать все sizeof на целевой платформе, так и правила выравниания. Вобщем чаще -- это фантастика. Разве что НА C где-то предварительно посчитать что-то вроде (uintptr_t)&(((struct s*)0)->v) и передать каким-то образом в ассемблер. Цитата(Vitёk @ Mar 7 2008, 12:36)  Компилятор у меня WinAVR (указано в комментарии к названию темы). Компилятор у тебю -- GCC. Афтар не в теме. Цитата(Vitёk @ Mar 7 2008, 11:41)  Есть только один момент: при внесении изменений в структуру (а такое иногда бывает), приходится заново вычислять смещение для некоторых её полей (вручную), и менять соотв. дефайны. При создании темы у меня была надежда, что описание структуры (в .h-файле) можно скормить компилятору, что бы он сам проделывал эту работу. Сбыться ей, судя по всему, не судьба. Ну для тех у кого WinAVR -- не судьба. А так вообще любой вменяемый компилятор (из всех перевиданных мною) заставить при желании вполне возможно. Я выше -- написал как. Вначале генерируется *.inc для ассемблера на основе выше приведённых конструкций с приведением NULL к типу структуры. Потом ассемблируется с полученным *.inc. Написать Makefile соответствующий не сложно. Цитата У меня были проблемы с порядком размещения полей в структуре, от которых удалось избавиться при помощи #pragma pack. Вместо которых в GCC атрибуты...
Сообщение отредактировал Kirill Frolov - Mar 7 2008, 11:37
--------------------
[ZX]
|
|
|
|
|
Mar 7 2008, 12:59
|

Местный
  
Группа: Свой
Сообщений: 272
Регистрация: 17-01-05
Из: Ростов-на-Дону
Пользователь №: 2 018

|
Цитата У меня были проблемы с порядком размещения полей в структуре, от которых удалось избавиться при помощи #pragma pack. Повторить ситуацию не удалось. Получается, что ввел всех в заблуждение, прошу меня извинить. Цитата Ну для тех у кого WinAVR -- не судьба. В двух словах, почему?
--------------------
/* Всё хорошо в меру. */
|
|
|
|
|
Mar 11 2008, 08:19
|

Частый гость
 
Группа: Новичок
Сообщений: 111
Регистрация: 10-02-07
Из: St.Petersburg, Russia
Пользователь №: 25 241

|
Цитата(Vitёk @ Mar 7 2008, 15:59)  Цитата Ну для тех у кого WinAVR -- не судьба. В двух словах, почему? Потому, что ко времени освоения компилятора на нужном уровне уже известно как он называется. Документацию на WinAVR в частности просто не найти, нет её, потому как и нет такого компилятора. Есть info gcc на сайте FSF (gnu.org), но там про WinAVR ни слова...
--------------------
[ZX]
|
|
|
|
|
Mar 11 2008, 09:20
|

Начинающий профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648

|
Цитата(Kirill Frolov @ Mar 11 2008, 11:19)  Документацию на WinAVR в частности просто не найти, нет её, потому как и нет такого компилятора. Есть info gcc на сайте FSF (gnu.org), но там про WinAVR ни слова... К Winavr идет документация, например, avr-libc-user-manual.pdf или в html, или в .PS Католог Х:\WinAVR-20071221\doc неплохо бы посмотреть Компилятор, конечно, не WinAvr(скорее это пакет разработчика), а avr-gcc. Это порт gcc для ядра AVR. На http://gcc.gnu.org/install/specific.html список поддерживаемых платформ.
--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|