|
|
  |
Компилятор ICC AVR, Помогите разобраться |
|
|
|
Sep 16 2008, 05:56
|
Частый гость
 
Группа: Свой
Сообщений: 106
Регистрация: 27-11-07
Из: Пермь
Пользователь №: 32 732

|
Логка программы. В определенном месте кода ждать пока функция не вернет "1". Пишу: Код while(!URXFind_("OK", 2)); И что же происходит? Функция возвращает "1" в тот момент, когда не должна. Сейчас поясню. Далее исправляю эту сточку на: Код while(!(temp = URXFind_("OK", 2))); ...и все начинает работать так, как надо. Когда надо функция возвращает "1", когда надо - "0". Что это за подводный камень? Ума не приложу как такое имеет место быть...
|
|
|
|
|
Sep 16 2008, 06:23
|
Частый гость
 
Группа: Свой
Сообщений: 106
Регистрация: 27-11-07
Из: Пермь
Пользователь №: 32 732

|
Код unsigned char URXFind_(unsigned char* buf, unsigned char len, unsigned char* pos); В первом посте намеренно упустил 3й параметр. В коде он присутствует. Функция возвращает 1 или 0. Код while(!URXFind_("OK", 2, &temp));
0240 L51: 0240 .dbline 125 0240 L52: 0240 .dbline 125 0240 22E0 ldi R18,2 0242 30E0 ldi R19,0 0244 00E0 ldi R16,<L54 0246 10E0 ldi R17,>L54 0248 0E940000 xcall _URXFind_ 024C 402F mov R20,R16 024E 4423 tst R20 0250 B9F3 breq L51 0252 .dbline 126 0252 88E0 ldi R24,8 0254 28B0 in R2,0x8 0256 2826 eor R2,R24 0258 28B8 out 0x8,R2 025A .dbline 127 025A 01E0 ldi R16,1 Код while(!(temp = URXFind_("OK", 2, &temp)));
0240 L51: 0240 .dbline 125 0240 L52: 0240 .dbline 125 0240 22E0 ldi R18,2 0242 30E0 ldi R19,0 0244 00E0 ldi R16,<L54 0246 10E0 ldi R17,>L54 0248 0E940000 xcall _URXFind_ 024C 0030 cpi R16,0 024E 0107 cpc R16,R17 0250 B9F3 breq L51 0252 X5: 0252 .dbline 126 0252 88E0 ldi R24,8 0254 28B0 in R2,0x8 0256 2826 eor R2,R24 0258 28B8 out 0x8,R2 025A .dbline 127 025A 01E0 ldi R16,1
|
|
|
|
|
Sep 16 2008, 07:21
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Здесь вопросов не возникает. Возвращаемый байт четко определяется на ноль в последовательности mov-tst-breq. Может быть Вы возвращаете не 0x00, а символ нуля '0' ? Код while(!URXFind_("OK", 2, &temp));
0240 L51: 0240 .dbline 125 ... 0248 0E940000 xcall _URXFind_ 024C 402F mov R20,R16 024E 4423 tst R20 0250 B9F3 breq L51 Таким образом, прога бегает по кругу до тех пор, пока функция возвращает ноль (0x00). Все в полном соответствии с си-шным текстом. А вот здесь лежат грабли. На сколько я понял, у Вас temp -- это двубайтовая переменная, хотя функция возвращает байт. Ну это Ваше дело. А вот далее становится еще интереснее. Начинаются фокусы оптимизатора, логичность которых я не доконца понимаю. Код while(!(temp = URXFind_("OK", 2, &temp)));
0240 L51: 0240 .dbline 125 0248 0E940000 xcall _URXFind_ 024C 0030 cpi R16,0 024E 0107 cpc R16,R17 0250 B9F3 breq L51 Скорее всего, Вы что-то не то возвращаете из функции URXFind_(). Либо сами далее разбирайтесь, либо аоказывайте ее сишный код.
Сообщение отредактировал zhevak - Sep 16 2008, 07:22
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Sep 16 2008, 07:36
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(zhevak @ Sep 16 2008, 10:21)  Скорее всего, Вы что-то не то возвращаете из функции URXFind_(). Наверное, так и есть. Поскольку ассемблерные коды отличаются только числом регистров, проверяемых на ноль: в первом случае - один регистр (R16, байт), во втором - два (R16 и R17, слово). Поскольку функция URXFind_() возвращает байт, то проверки R16 должно было бы хватать. Поскольку проверки одного байта не хватает, то с функцией URXFind_() что-то не в порядке...
|
|
|
|
|
Sep 16 2008, 07:42
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(lolful @ Sep 16 2008, 13:32)  temp - это unsigned char. Функция возвращает именно число 0 или 1, а не их ASCII-код. Обратите внимание, во втором случае ветвление зависит от двубайтовой переменной Код 024C 0030 cpi R16,0 024E 0107 cpc R16,R17 Компилятор пытается оценить двухбайтовую переменную. Но еще раз скажу, эту логику оптимизатора я не догоняю, чего это он тут пытался изобразить? Удачи! ЗЫ. Отключите всю оптимизацию нафиг, на данном этапе она только вредит.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Sep 16 2008, 07:46
|
Частый гость
 
Группа: Свой
Сообщений: 106
Регистрация: 27-11-07
Из: Пермь
Пользователь №: 32 732

|
Бррр...Я перепутал местами ассемблерный код, когда писал 2й пост... Вобщем вот к чему я пришел. Если написать Код while(!(unsigned char)(URXFind_("OK\r\n", 2, &temp))); ...то все работает. Видать компилятор думает, что функция возвратит не unsigned char, а нечто вроде int и лезет в регистр, который занят чем-то. Таким образом в обоих регистрах почти 100% вероятность того, что там будет не 0. Ошибка банальна - я не прописал прототип в заголовочном файле. Дурак.
|
|
|
|
|
Sep 16 2008, 07:50
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(lolful @ Sep 16 2008, 13:46)  Бррр...Я перепутал местами ассемблерный код, когда писал 2й пост... .... вероятность того, что там будет не 0. Ошибка банальна - я не прописал прототип в заголовочном Бывает.  Цитата Дурак.  эт-лишнее.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Sep 16 2008, 07:52
|
Частый гость
 
Группа: Свой
Сообщений: 106
Регистрация: 27-11-07
Из: Пермь
Пользователь №: 32 732

|
Цитата(zhevak @ Sep 16 2008, 13:50)  эт-лишнее. Не-не. Я не отчаиваюсь.  В следующий раз буду умнее. Спасибо всем за помощь.
Сообщение отредактировал lolful - Sep 16 2008, 07:55
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|