Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Непонятный результат компиляция на IARe
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Dog Pawlowa
Смешно, что вчера все работало.

Подрабатывает обработка одновременного нажатия двух клавиш

Код
    if ((pressed_keys == kUp | kDn) && // now these two keys
      ~(kbd_status3 & (kUp | kDn))) //and before it wasn't so
    {
      found_events |= kUpDn; // set new bit
      found_events &= ~(kUp | kDn); //reset usual bits
    }


Откомпилировалось в это

Нажмите для просмотра прикрепленного файла

Я удручен, этот код работает годами на разных платформах. Что не так?
wodya
Код
    if ((pressed_keys == kUp | kDn) && // now these two keys
      ~(kbd_status3 & (kUp | kDn))) //and before it wasn't so
    {
      found_events |= kUpDn; // set new bit
      found_events &= ~(kUp | kDn); //reset usual bits
    }


Первое kUp | kDn тоже хорошо бы в скобки. Насколько я помню, сначала производится == а затем битовые операции
=AVR=
Похоже, что не обработался двухстрочный код (кстати, не вижу знака конкатенации). Попробуй так же, но в одной строке:

Код
    if ((pressed_keys == kUp | kDn) &&  ~(kbd_status3 & (kUp | kDn)))    {
      found_events |= kUpDn; // set new bit
      found_events &= ~(kUp | kDn); //reset usual bits
    }
IgorKossak
Двухстрочные коды, даже с комментариями, в ИАРе обрабатываются нормально.
Знак продолжения строки нужен только в макросах.
Похоже таки проблема с приоритетом операций. ИАР в этом плане довольно жёстко следует стандарту. Странно, что раньше и на других платформах работало.
=GM=
Цитата(Dog Pawlowa @ Apr 25 2007, 08:37) *
Подрабатывает обработка одновременного нажатия двух клавиш

Код
    if ((pressed_keys == kUp | kDn) && // now these two keys
      ~(kbd_status3 & (kUp | kDn))) //and before it wasn't so
    {
      found_events |= kUpDn; // set new bit
      found_events &= ~(kUp | kDn); //reset usual bits
    }

Я удручен, этот код работает годами на разных платформах. Что не так?


Мне кажется, у вас неправильное использование оператора if(условие). Условие должно быть логическим выражением. В первой строке у вас всё правильно, оператор == даёт логическое выражение (ЛВ), хотя как уже сказали, оператор == имеет приоритет перед оператором ИЛИ. Во второй строке, в скобках, у вас идёт побитовое сравнение, что не ЕСТЬ логическое выражение, а просто некое двоичное число. Затем с помощью оператора && (логическое И) вы пытаетесь обработать первое ЛВ и побитовую инверсию числа, как следствие, результат может быть непредсказуем.

Вторую строчку вам надо представить в виде логического выражения.
Dog Pawlowa
Борюсь пока.
Последовательность действительно неправильна, двухстрочный код не влияет.
Влияет сложная формула, от нее компилятор клинит - так что ищу путь попроще, разбивая формулу на части (помогая компилятору в стиле Князева).
Обычно я стараюсь реже смотреть ассемблерный код, но вот это удивило:

Код
     76              found_events |= kUpDn;                            // set new bit
   \   000000E0   ....               LDI     R30, LOW(found_events)
   \   000000E2   ....               LDI     R31, (found_events) >> 8
   \   000000E4   8100               LD      R16, Z
   \   000000E6   6100               ORI     R16, 0x10
   \   000000E8   8300               ST      Z, R16
     77              found_events &= ~(kUp | kDn);                     //reset usual bits
   \   000000EA   ....               LDI     R30, LOW(found_events)                     !!!!!!!!!!!!!!!!!!!!!!!!!
   \   000000EC   ....               LDI     R31, (found_events) >> 8                   !!!!!!!!!!!!!!!!!!!!!!!!
   \   000000EE   8100               LD      R16, Z                                             !!!!!!!!!!!!!!!!!!!!!!!
   \   000000F0   7F09               ANDI    R16, 0xF9
   \   000000F2   8300               ST      Z, R16
   \   000000F4   9508               RET


Из шести команд три тупо дублируются. Оптимизация включена LOW. Хороший маркетинговый ход - эти уровни оптимизации.
Igor26
Цитата
Знак продолжения строки

А как он указывается(записывается)? Правда не знаю. Подскажите пожалуйста.
zltigo
Цитата(Dog Pawlowa @ Apr 25 2007, 12:37) *
Я удручен, этот код работает годами на разных платформах. Что не так?

Я удручен не меньше вашего, за Вас и за все "платформы" на которых НЕ СОБЛЮДАЕТСЯ приоритет операции равно (==) перед поразрядным логическим или (|).
Код
    if ((pressed_keys == (kUp | kDn)) && // now these two keys
      ~(kbd_status3 & (kUp | kDn))) //and before it wasn't so
=GM=
[DELETED]
Совсем не по теме.
IgorKossak
Цитата(Dog Pawlowa @ Apr 25 2007, 13:48) *
Из шести команд три тупо дублируются. Оптимизация включена LOW. Хороший маркетинговый ход - эти уровни оптимизации.

А что Вы хотели? При оптимизации LOW никакие обращения к переменным не оптимизируются.
Откуда производителям ПО знать, может Вам так надо. Поставьте хотябы MEDIUM и посмотрите.
Я, например, всегда ставлю максимум.
Dog Pawlowa
Цитата(=GM= @ Apr 25 2007, 13:45) *
Мне кажется, у вас неправильное использование оператора if(условие). Условие должно быть логическим выражением...

Да, уже вижу, что что-то не так. Разделил проверку условий, вернут прибор и проверю.
Всем спасибо, с вашими подсказками добью. smile.gif
Но странно. Вчера по одновременному нажатию этих клавиш запускал тест, а сегодня событие генерируется постоянно cranky.gif
Пятна на Солнце.
IgorKossak
Цитата(Igor26 @ Apr 25 2007, 13:51) *
А как он указывается(записывается)? Правда не знаю. Подскажите пожалуйста.

Например так:
Код
#define SOMETHING (THIS |        \
                               OR_THIS)
Dog Pawlowa
Цитата(zltigo @ Apr 25 2007, 13:51) *
Я удручен не меньше вашего, за Вас и за все "платформы" на которых НЕ СОБЛЮДАЕТСЯ приоритет операции равно (==) перед поразрядным логическим или (|)...

Принимаю соболезнования. sad.gif
Ошибка в приоритетах влияла, видимо, на незначительные свойства - неподавленный дребезг комбинации клавиш, который не влиял на пользовательские свойства.

Перепроверил.
Это тот же код для MSP430. Тоже IAR.
kDn=2, kUp=8.
А теперь расскажите мне про последовательность операций... smile.gif

Код
    72                      if ((pressed_keys==kUp+kDn)&&  // now this two keys
     73                          ((~kbd_status3)&(kUp+kDn)))//and before it wasn't so
   \   00008E   F2900A00....         CMP.B   #0xa, &pressed_keys
   \   000094   0D20                 JNE     ??KbdService_6
   \   000096   5E42....             MOV.B   &kbd_status3, R14
   \   00009A   7EE3                 XOR.B   #0xff, R14
   \   00009C   7EB00A00             BIT.B   #0xa, R14
   \   0000A0   0724                 JEQ     ??KbdService_6
     74                          {found_events|=kUpDn;    // set new bit
   \   0000A2   F2D01000....         BIS.B   #0x10, &found_events
     75                          found_events&=~(kUp+kDn);    break; } //reset usual bits
   \   0000A8   F2F0F500....         AND.B   #0xf5, &found_events
   \   0000AE   3041                 RET
Сергей Борщ
Цитата(Dog Pawlowa @ Apr 25 2007, 13:04) *
А теперь расскажите мне про последовательность операций... smile.gif
Ищите 10 отличий: kUp+kDn и kUp | kDn
Dog Pawlowa
Цитата(Сергей Борщ @ Apr 25 2007, 14:59) *
Ищите 10 отличий: kUp+kDn и kUp | kDn

Спасибо. Интересно, коллективный разум знает, зачем я поменял ? sad.gif

И все это не объясняет почему работало вчера на AVR в уже неправильном виде.
Впрочем, нужно идти вперед.
defunct
Сравните также

( (~kbd_status3) & (kUp+kDn) )

с

~(kbd_status3 & (kUp | kDn) )
Сергей Борщ
Цитата(Dog Pawlowa @ Apr 25 2007, 14:02) *
Спасибо. Интересно, коллективный разум знает, зачем я поменял ? sad.gif
Видимо чтобы выработать в себе хорошую привычку. Ведь если эти константы будут иметь более одного единичного бита и какие-то из битов совпадут, то результат | будет более правильный:
Код
enum {keyRepeat = (1<<7), kUp = (1<<0), kDn = (1<<1), kRUp = KeyRepeat | kUp, kRDn = KeyRepeat | kDn };
if(kbd_status3 & (kRUp | kRDn)) // ok
if(kbd_status3 & (kRUp + kRDn)) // oops
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.