Коллекция глюков Здесь публикуются все известные глюки, баги микроконтроллеров, памяти, АЦП и т.д. |
18.11.2010, 11:11
|
#1
|
Почётный гражданин KAZUS.RU
Регистрация: 01.05.2009
Адрес: Коптево
Сообщений: 2,849
Сказал спасибо: 276
Сказали Спасибо 427 раз(а) в 274 сообщении(ях)
|
Глюки WinAVR
Уважаемые постмодераторы! Я дико извиняюсь, как говорят в Одессе, но не нашёл на Вашем форуме темы про глюки WinAVR. И только поэтому завёл свою.
Итак, в 2 словах, глюк такой: компилятор WinAVR глотает строки исходника.
Смотрите сами, вот это исходник:
Код:
|
void KeyHandler(void) {
if (((Key & 0b0001) == 0) && ((PreviousKey & 0b0001) == 1)) { // key green
if (CntPause › 0) {
SpitefulBuyersGreen++;
IntervalsHandler(SptPollGreen);
}
else {
GreenIndicator++;
IntervalsHandler(PollGreen);
}
fUpdInd=1;
}
if (((Key & 0b0010) == 0) && ((PreviousKey & 0b0010) == 1)) { // key red
if (CntPause › 0) {
SpitefulBuyersRed++;
IntervalsHandler(SptPollRed);
}
else {
RedIndicator++;
IntervalsHandler(PollRed);
}
fUpdInd=1;
}
if (((Key & 0b0100) == 0) && ((PreviousKey & 0b0100) == 1)) BadLid(); // key micro
PreviousKey = Key;
fKeyHand = 0; // Сбрасываем флаг
} |
А вот что он накомпилил:
Код:
|
@000007E8: KeyHandler
370: void KeyHandler(void) {
+000007E8: 93DF PUSH R29 Push register on stack
+000007E9: 93CF PUSH R28 Push register on stack
+000007EA: B7CD IN R28,0x3D In from I/O location
+000007EB: B7DE IN R29,0x3E In from I/O location
371: if (((Key & 0b0001) == 0) && ((PreviousKey & 0b0001) == 1)) { // key green
+000007EC: 91800060 LDS R24,0x0060 Load direct from data space
+000007EE: 2F88 MOV R24,R24 Copy register
+000007EF: E090 LDI R25,0x00 Load immediate
+000007F0: 7081 ANDI R24,0x01 Logical AND with immediate
+000007F1: 7090 ANDI R25,0x00 Logical AND with immediate
+000007F2: 9700 SBIW R24,0x00 Subtract immediate from word
+000007F3: F541 BRNE PC+0x29 Branch if not equal
+000007F4: 91800061 LDS R24,0x0061 Load direct from data space
+000007F6: 2F88 MOV R24,R24 Copy register
+000007F7: E090 LDI R25,0x00 Load immediate
+000007F8: 7081 ANDI R24,0x01 Logical AND with immediate
+000007F9: 7090 ANDI R25,0x00 Logical AND with immediate
+000007FA: 2388 TST R24 Test for Zero or Minus
+000007FB: F101 BREQ PC+0x21 Branch if equal
372: if (CntPause › 0) {
+000007FC: 918000B0 LDS R24,0x00B0 Load direct from data space
+000007FE: 919000B1 LDS R25,0x00B1 Load direct from data space
+00000800: 9700 SBIW R24,0x00 Subtract immediate from word
+00000801: F061 BREQ PC+0x0D Branch if equal
373: SpitefulBuyersGreen++;
+00000802: 9180006B LDS R24,0x006B Load direct from data space
+00000804: 9190006C LDS R25,0x006C Load direct from data space
+00000806: 9601 ADIW R24,0x01 Add immediate to word
+00000807: 9390006C STS 0x006C,R25 Store direct to data space
+00000809: 9380006B STS 0x006B,R24 Store direct to data space
374: IntervalsHandler(SptPollGreen);
+0000080B: E084 LDI R24,0x04 Load immediate
+0000080C: DEFC RCALL PC-0x0103 Relative call subroutine
+0000080D: C00B RJMP PC+0x000C Relative jump
377: GreenIndicator++;
+0000080E: 91800067 LDS R24,0x0067 Load direct from data space
+00000810: 91900068 LDS R25,0x0068 Load direct from data space
+00000812: 9601 ADIW R24,0x01 Add immediate to word
+00000813: 93900068 STS 0x0068,R25 Store direct to data space
+00000815: 93800067 STS 0x0067,R24 Store direct to data space
378: IntervalsHandler(PollGreen);
+00000817: E082 LDI R24,0x02 Load immediate
+00000818: DEF0 RCALL PC-0x010F Relative call subroutine
380: fUpdInd=1;
+00000819: E081 LDI R24,0x01 Load immediate
+0000081A: 938000A6 STS 0x00A6,R24 Store direct to data space
394: PreviousKey = Key;
+0000081C: 91800060 LDS R24,0x0060 Load direct from data space
+0000081E: 93800061 STS 0x0061,R24 Store direct to data space
395: fKeyHand = 0; // Сбрасываем флаг
+00000820: 921000A7 STS 0x00A7,R1 Store direct to data space
396: }
+00000822: 91CF POP R28 Pop register from stack
+00000823: 91DF POP R29 Pop register from stack
+00000824: 9508 RET Subroutine return |
Имхо, не надо иметь 7 пядей во лбу, чтобы понять, что WinAVR скомпилил почему-то только одну ветку "if", а остальные - нет.
Если это не глюк компилятора, нажму "Спасибо" тому, кто найдёт ошибку в исходнике.
Честно говоря, ничего умнее "volatile" перед каждым "if" в голову не приходит, но:
1. это моветон,
2. теперь что, перед каждым оператором (на всякий случай) писать "volatile", что ли?
Да, чуть совсем не забыл:
AVRstudio - v4.18 SP3,
WinAVR - 20100110,
WinXP Home Edition SP2 на одном компе
и WinXP Professional SP3 на другом - реакция одинаковая. )
P.S. Действительно, куда пропали пробелы? Причём "." или "_" в начале строк не помогают.
Как приводить тексты программ? Тогда читайте сами, как сможете...
P.P.S. Тэги помогли?
Последний раз редактировалось KBH-I; 18.11.2010 в 12:13.
Причина: Куда делись пробелы и табы в начале строк?
|
|
|
|
18.11.2010, 11:32
|
#2
|
Супер-модератор
Регистрация: 13.03.2004
Адрес: Minsk
Сообщений: 2,378
Сказал спасибо: 1,956
Сказали Спасибо 1,328 раз(а) в 578 сообщении(ях)
|
Re: Глюки WinAVR
volatile относится только к переменным
И неплохо бы увидеть как объявлены переменные
Но, по моему, ошибка тут
Цитата:
|
((PreviousKey & 0b0010) == 1)
|
так как компилер видит, что такое никогда не истина, то и выкидывает нафиг.
надо бы написать
Цитата:
|
((PreviousKey & 0b0010) != 0)
|
А чтоб пробелы не пропадали, заключайте в тэги "code"
__________________
[ жизнь приятна и красива, если выпить литр пива ]
Последний раз редактировалось nml; 18.11.2010 в 11:46.
|
|
|
|
18.11.2010, 11:45
|
#3
|
Почётный гражданин KAZUS.RU
Регистрация: 19.02.2008
Сообщений: 1,809
Сказал спасибо: 124
Сказали Спасибо 604 раз(а) в 421 сообщении(ях)
|
Re: Глюки WinAVR
Видимо он решил, что в других if события не могут произойти.
|
|
|
|
18.11.2010, 11:50
|
#4
|
Почётный гражданин KAZUS.RU
Регистрация: 01.04.2009
Адрес: Рязань
Сообщений: 1,140
Сказал спасибо: 21
Сказали Спасибо 635 раз(а) в 344 сообщении(ях)
|
Re: Глюки WinAVR
Мда похоже nml прав. Если PreviousKey = 0b0010 то PreviousKey & 0b0010, т.е. 0b0010 & 0b0010 = 0b0010, а уж никак не 1, 0b0001 в двоичном.
|
|
|
|
18.11.2010, 11:58
|
#5
|
Почётный гражданин KAZUS.RU
Регистрация: 01.05.2009
Адрес: Коптево
Сообщений: 2,849
Сказал спасибо: 276
Сказали Спасибо 427 раз(а) в 274 сообщении(ях)
|
Re: Глюки WinAVR
Сообщение от nml
|
Но, по моему, ошибка тут
Цитата:
((PreviousKey & 0b0010) == 1)
|
1. Если ошибка тут, то как он берёт строку
" if (((Key & 0b0001) == 0) && ((PreviousKey & 0b0001) == 1)) { // key green"?
2. Объявление переменных (имхо, ничего особенного; кроме того, эти же переменные используются как в скомпилированной ветке, так и в выброшенных =› дело не в них):
Код:
|
unsigned char
fUpdInd = 0,
fKeyHand = 0,
Key = 0b0111,
PreviousKey = 0b0111;
unsigned int
CntPause = 0,
GreenIndicator = 0,
RedIndicator = 0,
SpitefulBuyersGreen = 0,
SpitefulBuyersRed = 0;
#define PollGreen 2
#define PollRed 3
#define SptPollGreen 4
#define SptPollRed 5 |
P.S. Не совсем уловил про тэги...
Последний раз редактировалось nml; 18.11.2010 в 12:06.
Причина: <code>
|
|
|
|
18.11.2010, 12:03
|
#6
|
Супер-модератор
Регистрация: 13.03.2004
Адрес: Minsk
Сообщений: 2,378
Сказал спасибо: 1,956
Сказали Спасибо 1,328 раз(а) в 578 сообщении(ях)
|
Re: Глюки WinAVR
Сообщение от KBH-I
|
1. Если ошибка тут, то как он берёт строку
" if (((Key & 0b0001) == 0) && ((PreviousKey & 0b0001) == 1)) { //
|
Потому что число по "И" с 0x01 может быть равно 1.
Да вы поправьте исходник и скомпилируйте.
И запомните - у компиляторов глюки таки есть.
Но встречаются на два порядка реже, чем наша невнимательность
Тэги поправил (надо [ ] скобки ставить )
__________________
[ жизнь приятна и красива, если выпить литр пива ]
Последний раз редактировалось nml; 18.11.2010 в 12:07.
|
|
|
|
18.11.2010, 12:03
|
#7
|
Почётный гражданин KAZUS.RU
Регистрация: 01.04.2009
Адрес: Рязань
Сообщений: 1,140
Сказал спасибо: 21
Сказали Спасибо 635 раз(а) в 344 сообщении(ях)
|
Re: Глюки WinAVR
Сообщение от KBH-I
|
1. Если ошибка тут, то как он берёт строку
" if (((Key & 0b0001) == 0) && ((PreviousKey & 0b0001) == 1)) { // key green"?
|
Если PreviousKey = 0b0001 то PreviousKey & 0b0001 = 1 и условие выполняется, при PreviousKey = 0b0010, PreviousKey & 0b0010 никогда не будет равно 1. И, как следствие, оптимизатор выбрасывает эту строку.
|
|
|
|
18.11.2010, 12:04
|
#8
|
Почётный гражданин KAZUS.RU
Регистрация: 01.05.2009
Адрес: Коптево
Сообщений: 2,849
Сказал спасибо: 276
Сказали Спасибо 427 раз(а) в 274 сообщении(ях)
|
Re: Глюки WinAVR
Сообщение от nml
|
Потому что число по "И" с 0x01 может быть равно 1.
|
Действительно!
P.S. Заодно не подскажете, нужно ли поверх AVRstudio 4.18 с установленным SP3 ставить ещё и SP2 и SP1?
P.P.S. Исправил "== 1" на "› 0" - заработало.
Последний раз редактировалось KBH-I; 18.11.2010 в 12:28.
Причина: P.S.
|
|
|
|
18.11.2010, 12:59
|
#9
|
Почётный гражданин KAZUS.RU
Регистрация: 01.04.2009
Адрес: Рязань
Сообщений: 1,140
Сказал спасибо: 21
Сказали Спасибо 635 раз(а) в 344 сообщении(ях)
|
Re: Глюки WinAVR
Сообщение от KBH-I
|
P.S. Заодно не подскажете, нужно ли поверх AVRstudio 4.18 с установленным SP3 ставить ещё и SP2 и SP1?
|
Нет. Не надо.
|
|
|
|
26.12.2010, 16:47
|
#10
|
Прописка
Регистрация: 17.02.2009
Сообщений: 154
Сказал спасибо: 14
Сказали Спасибо 6 раз(а) в 6 сообщении(ях)
|
Re: Глюки WinAVR
Доброе время суток. На WinAvr пытаюсь создать програмку к меге8.Проблемы с переменными после оператора замкнутого цикла while(1),переменные при проверке на протеусе выдаёт черточки и пишет всегда 0. Пробовал менять оптимезацию,результата нет.Пробовал внаглую записывать число в любом виде всё равно 0.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 01:19.
|
|