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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Указатели на функции
ArtemKAD
сообщение Jun 26 2006, 10:18
Сообщение #1


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

Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364



Может кто подскажет как бороться с зависанием полученного кода если в нем использованы указатели на функцию. help.gif
Бо шаманить с лишними nop-ами уже порядком надоело... angry.gif
Go to the top of the page
 
+Quote Post
_Bill
сообщение Jun 26 2006, 10:26
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



Цитата(ArtemKAD @ Jun 26 2006, 13:18) *
Может кто подскажет как бороться с зависанием полученного кода если в нем использованы указатели на функцию. help.gif
Бо шаманить с лишними nop-ами уже порядком надоело... angry.gif

А в чем, собственно, проблема?
Go to the top of the page
 
+Quote Post
vet
сообщение Jun 26 2006, 11:25
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



...и при чём тут nop'ы ?


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
ArtemKAD
сообщение Jun 26 2006, 14:27
Сообщение #4


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

Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364



Цитата(vet @ Jun 26 2006, 14:25) *
...и при чём тут nop'ы ?

Да я ж говорю - код зависает. Насколько я понял зависит от адреса вызываемой функции. Если по четному, то вызывается нормально, а если по нечетному - то ИНОГДА зависает.
Вот лишними nop-ами и приходится ровнять код вызываемых процедур (меняю одни, а подвисают другие....) - иначе не работает...


А если учесть, что эта зараза константы втыкает перед кодом, то по мере развития проекта перетыкивать nop-ы приходится регулярно :-(

Сообщение отредактировал ArtemKAD - Jun 26 2006, 14:30
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 26 2006, 15:28
Сообщение #5


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Крутой наверное компилятор. У меня-то неопытного всегда код ложился с чётного адреса. Причём даже все переходы в командах переходят только на чётный адрес. Но это... просто нечто. Может речь не об AVR?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
ArtemKAD
сообщение Jun 26 2006, 16:03
Сообщение #6


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

Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364



А шут его знает, вроде АВР :-) ... Адрес естественно в словах.
Собственно патч по этому поводу у них на -про версию ВРОДИ-бы здесь:
ftp://ftp.iar.se/WWWfiles/avr/PatchReadme_412b.html
Так, что читайте "описание от производителей". Лично мне поймать условие когда 100% код виснет так и не удалось (не помог и асм полученного кода sad.gif ).

А вот что делать с -евал версией?
Кстати, в 4,20 -евал этот баг все еще присутствует....

Да, и еще любопытный вопрос - если в 4.20 EV баг все еще есть, где гарантия, что тот патч решает проблему в полной версии?
Go to the top of the page
 
+Quote Post
vet
сообщение Jun 26 2006, 16:05
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



Вы случаем не абсолютные ли адреса присваиваете указателям?
Если так, то нужно учитывать, что IAR все адреса меряет в байтах.


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 26 2006, 16:15
Сообщение #8


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



А на самом деле, дайте зыркнуть на кусок кода, который Вас смущает. И желательно на его же листинг.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
ArtemKAD
сообщение Jun 26 2006, 16:37
Сообщение #9


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

Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364



Примерно так:
// Структура таблицы ключевых слов
struct token
{
const char __flash *str;
void (*fun)(void);
};

// Таблица ключевых слов и их обработчиков
__root __flash const struct token token_table[] =
{CR_LF,fun_VOID,
OK, fun_OK,

..............................................................

}

void fun_VOID(void)
{
asm("nop"); // Лекарство от зависания sad.gif !!!
return;
}

/* Обработчик "OK" */
void fun_OK(void)
{
if(error_cnt)

error_cnt --;
(*fun_OK_addr)(); // Запуск обработчика по указателю
asm("nop"); // Лекарство от зависания sad.gif !!!
return;
}


..........................................
// а вот так вызывается в коде из таблицы....
void (*p)(void);
Response--;
p = token_table[Response].fun;
(*p)();
// token_table[Response].fun(); - тоже самое, но так вроде стабильнее ;(


.............................................

К сожалению с кодом проблемы - надо перекомпилировать и много кода сюда писать....
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 26 2006, 17:01
Сообщение #10


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



1. Попробуйте перед созданием таблицы костант описать прототипы функций, которые потом в таблицу положите. Чтобы компилер сразу въехал, что это адрес функции, а не переменной.

2. Не понимаю, почему компилер разрешает указывать в этой структуре имя функции без префикса адреса. Вроде бы нужно типа такого: CR_LF,&fun_VOID, ...

Вспомнил ещё кое-что.
3. Когда процедуру/функцию предполагается вызывать через переменную/константу, то перед ней нужно писать: static void ... (...)
Во всяком случае на АРМе так. Может здеся тоже.

Сообщение отредактировал GetSmart - Jun 26 2006, 17:09


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
vet
сообщение Jun 26 2006, 17:15
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



Скомпилировал код версией 4.11А. NOP'ы повыкидывал.
Как и ожидалось, структуры инициализируются правильно, указатели указывают, куда нужно.
Код
void (*fun_OK_addr)();

__root __flash const struct token token_table[] =
{"\r\n",fun_VOID,
"OK", fun_OK
};
  0000000A: 0004
  0000000C: 0009; верно, байтовый адрес fun_VOID - 18
  0000000E: 0007
  00000010: 000A; верно, байтовый адрес fun_OK - 20


fun_OK_addr = fun_VOID;
  00000018: E009                ldi     r16,#9
  0000001A: E010                ldi     r17,#0
  0000001C: EAE0                ldi     r30,#160
  0000001E: E0F0                ldi     r31,#0
  00000020: 8300                st      z,r16
  00000022: 8311                std     z+1,r17
(*fun_OK_addr)();
  00000024: EAA0                ldi     r26,#160
  00000026: E0B0                ldi     r27,#0
  00000028: 91ED                ld      r30,x+
  0000002A: 91FC                ld      r31,x
  0000002C: 9509                icall


fun_OK_addr = token_table[0].fun;
  0000002E: E0EC                ldi     r30,#12
  00000030: E0F0                ldi     r31,#0
  00000032: 9105                lpm     r16,z+
  00000034: 9114                lpm     r17,z
  00000036: EAE0                ldi     r30,#160
  00000038: E0F0                ldi     r31,#0
  0000003A: 8300                st      z,r16
  0000003C: 8311                std     z+1,r17
(*fun_OK_addr)();
  0000003E: EAA0                ldi     r26,#160
  00000040: E0B0                ldi     r27,#0
  00000042: 91ED                ld      r30,x+
  00000044: 91FC                ld      r31,x
  00000046: 9509                icall



(*token_table[0].fun)();
  00000048: E0EC                ldi     r30,#12
  0000004A: E0F0                ldi     r31,#0
  0000004C: 9105                lpm     r16,z+
  0000004E: 9114                lpm     r17,z
  00000050: 01F8                movw    r30,r16
  00000052: 9509                icall


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
ArtemKAD
сообщение Jun 26 2006, 17:29
Сообщение #12


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

Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364



Естественно есть прототипы описаные до констант - иначе компилятор выругается....

По поводу & - .........


Кстати, обращу внимание - это рабочий вариант. А вот если убрать nop из первой функции (длина которой станет 1 слово), то при вызове второй МК отправляется в "спячку" sad.gif ...
Собственно так и "спасаюсь" - все адреса функций в таблице нопами делаю четными. Но иногда ( когда IAR "с оптимизирует" очередную константу перед этим кодом) приходится увеличивать константы "загоняя" адрес первой функции в нужный диапазон....

Естественно с оптимизацией тут уже почти никак sad.gif .
Вот если-бы можно было указать выравнивание кода процедур или явно указать их адреса....
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 26 2006, 17:33
Сообщение #13


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Кого будем бить за дезинформацию?

{"\r\n",fun_VOID,
"OK", fun_OK
};
Это же вроде отличается от оригинала?

И напоследок вопрос, который интересует меня:
__root __flash const struct token token_table[]
зачем в этой строке стоит "struct" ?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
vet
сообщение Jun 26 2006, 17:34
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



Ну, не придирайтесь smile.gif в условии задачи эти строки не были определены. Да и не важны они.
Главное - адресации корректны, как адреса 9 (байтовый 18), так и адреса 10 (20).


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
ArtemKAD
сообщение Jun 26 2006, 17:59
Сообщение #15


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

Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364



Цитата(vet @ Jun 26 2006, 20:15) *
Скомпилировал код версией 4.11А. NOP'ы повыкидывал.
Как и ожидалось, структуры инициализируются правильно, указатели указывают, куда нужно.


Наблюдая как этот код зависает в МК мне от его правильности как-то не легче sad.gif ...

Цитата
Код
void (*fun_OK_addr)();

__root __flash const struct token token_table[] =
{"\r\n",fun_VOID,
"OK", fun_OK
};
  0000000A: 0004
  0000000C: 0009; верно, байтовый адрес fun_VOID - 18
  0000000E: 0007
  00000010: 000A; верно, байтовый адрес fun_OK - 20


fun_OK_addr = fun_VOID;
  00000018: E009                ldi     r16,#9
  0000001A: E010                ldi     r17,#0
  0000001C: EAE0                ldi     r30,#160
  0000001E: E0F0                ldi     r31,#0
  00000020: 8300                st      z,r16
  00000022: 8311                std     z+1,r17
(*fun_OK_addr)();
  00000024: EAA0                ldi     r26,#160
  00000026: E0B0                ldi     r27,#0
  00000028: 91ED                ld      r30,x+
  0000002A: 91FC                ld      r31,x
  0000002C: 9509                icall


fun_OK_addr = token_table[0].fun;
  0000002E: E0EC                ldi     r30,#12
  00000030: E0F0                ldi     r31,#0
  00000032: 9105                lpm     r16,z+
  00000034: 9114                lpm     r17,z
  00000036: EAE0                ldi     r30,#160
  00000038: E0F0                ldi     r31,#0
  0000003A: 8300                st      z,r16
  0000003C: 8311                std     z+1,r17
(*fun_OK_addr)();
  0000003E: EAA0                ldi     r26,#160
  00000040: E0B0                ldi     r27,#0
  00000042: 91ED                ld      r30,x+
  00000044: 91FC                ld      r31,x
  00000046: 9509                icall



(*token_table[0].fun)();
  00000048: E0EC                ldi     r30,#12
  0000004A: E0F0                ldi     r31,#0
  0000004C: 9105                lpm     r16,z+
  0000004E: 9114                lpm     r17,z
  00000050: 01F8                movw    r30,r16
  00000052: 9509                icall

Ну предположим там был (*token_table[Response].fun)()
Поэтому в настоящем коде вместо
ldi константа
было
Код
ldi r30, 0x02
ldi r31, 0x02
mov r16, r24
ldi r17, 0
lsl r16
rol r17
lsl r16
rol r17
add r30,r16
adc r31,r17
и далее те самые
lpm     r16,z+
lpm     r17,z
movw r26,r16
movw r30,r26
icall


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

Лучший критерий - программа в МК это очень ярко показывает....
Go to the top of the page
 
+Quote Post

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

 


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


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