Форум разработчиков электроники ELECTRONIX.ru: Странная проблема при оптимизации - Форум разработчиков электроники ELECTRONIX.ru

Jump to content

  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

Странная проблема при оптимизации Rate Topic: -----

#1 User is offline   Jenya7 Icon

  • Профессионал
  • PipPipPipPipPip
  • Group: Участник
  • Posts: 1 778
  • Joined: 29 марта 12

Posted 28 сентября 2018 - 12:29

Есть такой код
Код
uint32_t master_ack;  //global
master_ack = CAN_RX_Master();      
if (master_ack == 1)
{
      //пришел сюда если optimization = Low
}
else //no response
{    //пришел сюда если optimization = High
}
master_ack равен 1. при optimization = High я попадаю в else. при optimization = Low я попадаю в if.
Все? Сливаем IAR?

This post has been edited by Jenya7: 28 сентября 2018 - 12:31

0

#2 User is offline   scifi Icon

  • Гуру
  • PipPipPipPipPipPip
  • Group: Свой
  • Posts: 3 020
  • Joined: 07 февраля 07

Posted 28 сентября 2018 - 12:50

Грабли обычно одни и те же: volatile и гонки.

Цитата(Jenya7 @ Sep 28 2018, 12:29) <{POST_SNAPBACK}>
Все? Сливаем IAR?

Есть и другие варианты. 1) Найти косяк в своём коде. 2) Не включать оптимизацию.
0

#3 User is offline   Jenya7 Icon

  • Профессионал
  • PipPipPipPipPip
  • Group: Участник
  • Posts: 1 778
  • Joined: 29 марта 12

Posted 28 сентября 2018 - 12:55

Цитата(scifi @ Sep 28 2018, 15:50) <{POST_SNAPBACK}>
Грабли обычно одни и те же: volatile и гонки.


Есть и другие варианты. 1) Найти косяк в своём коде. 2) Не включать оптимизацию.


volatile? а с чего он оптимизирует обычную глобальную переменную?
Не включать оптимизацию? оптимизация - это единственное наиболее сильное преимущество IAR. Без оптимизации и в Атолике можно кропать.

определил как volatile - то же самое - заходит в else.

This post has been edited by Jenya7: 28 сентября 2018 - 13:00

0

#4 User is offline   Сергей Борщ Icon

  • Гуру
  • PipPipPipPipPipPip
  • Group: Модераторы
  • Posts: 8 455
  • Joined: 15 мая 06

Posted 28 сентября 2018 - 13:05

CAN_RX_Master() покажите. Предполагаю, что оптимизатор видит ее тело, находит в нем только один возможный результат и выкидывает все условие.
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
0

#5 User is offline   scifi Icon

  • Гуру
  • PipPipPipPipPipPip
  • Group: Свой
  • Posts: 3 020
  • Joined: 07 февраля 07

Posted 28 сентября 2018 - 13:08

Цитата(Jenya7 @ Sep 28 2018, 12:55) <{POST_SNAPBACK}>
volatile? а с чего он оптимизирует обычную глобальную переменную?

Мы же не видим ваш код и настройки сборки. Компилятор даже умеет собирать программы, смешивая код и переменные из разных файлов. Если увидит, что переменная не нужна (да хотя бы и глобальная) - может выкинуть её. Ну а volatile - это в качестве примера, и скорее всего в каком-то другом месте. Кстати, из очевидных кандидатов - переменные, через которые передаются сигналы из обработчиков прерываний.
0

#6 User is offline   Jenya7 Icon

  • Профессионал
  • PipPipPipPipPip
  • Group: Участник
  • Posts: 1 778
  • Joined: 29 марта 12

Posted 28 сентября 2018 - 13:18

Цитата(Сергей Борщ @ Sep 28 2018, 16:05) <{POST_SNAPBACK}>
CAN_RX_Master() покажите. Предполагаю, что оптимизатор видит ее тело, находит в нем только один возможный результат и выкидывает все условие.


CODE
uint32_t CAN_RX_Master(void){
uint32_t mot_num;
uint32_t opcode;
uint32_t pos;
uint32_t ack = 0;

if (can_params.message_received)
{
can_params.message_received = 0;

mot_num = (RxMessage.ExtId & 0xFF) - BASE_MOTOR_ID;
if (mot_num > MAX_MOTORS)
return 0;

opcode = (RxMessage.ExtId >> 8) & 0xFF;

switch (opcode)
{
case CAN_COM_GET_ALL :

motor_rt_params[mot_num].current = ((RxMessage.Data[1]<<8) | RxMessage.Data[0]);
motor_rt_params[mot_num].speed = ((RxMessage.Data[3]<<8) | RxMessage.Data[2]);
motor_rt_params[mot_num].position = ((RxMessage.Data[5]<<8) | RxMessage.Data[4]);
ack = 1;
break;

case CAN_COM_I_AM :
motor_rt_params[mot_num].ena = 1;
motor_rt_params[mot_num].mot_id = BASE_MOTOR_ID + mot_num;
ack = 1;
break;

case CAN_COM_IGET :
motor_rt_params[mot_num].current = ( RxMessage.Data[1]<<8) | RxMessage.Data[0]);
pos = CAN_IGET_POS;
ack = 1;
break;

case CAN_COM_PGET :
motor_rt_params[mot_num].position = (( RxMessage.Data[1]<<8) | RxMessage.Data[0]);
pos = CAN_PGET_POS;
ack = 1;
break;

case CAN_COM_VGET :
motor_rt_params[mot_num].speed = (( RxMessage.Data[1]<<8) | RxMessage.Data[0]);
pos = CAN_VGET_POS;
ack = 1;
break;
}

if (ack)
motor_rt_params[mot_num].rx_flags |= (1<<pos);

return ack;
}

0

#7 User is offline   scifi Icon

  • Гуру
  • PipPipPipPipPipPip
  • Group: Свой
  • Posts: 3 020
  • Joined: 07 февраля 07

Posted 28 сентября 2018 - 13:24

Процитирую себя:
Цитата(scifi @ Sep 28 2018, 13:08) <{POST_SNAPBACK}>
Кстати, из очевидных кандидатов - переменные, через которые передаются сигналы из обработчиков прерываний.

Обработчик прерывания есть?
0

#8 User is offline   Jenya7 Icon

  • Профессионал
  • PipPipPipPipPip
  • Group: Участник
  • Posts: 1 778
  • Joined: 29 марта 12

Posted 28 сентября 2018 - 13:27

Цитата(scifi @ Sep 28 2018, 16:24) <{POST_SNAPBACK}>
Процитирую себя:

Обработчик прерывания есть?


у меня есть несколько обработчиков прерывания, на UART, на CAN, но там эта переменная никак не появляется. я прбовал объявить ее static - не помогло.
0

#9 User is offline   scifi Icon

  • Гуру
  • PipPipPipPipPipPip
  • Group: Свой
  • Posts: 3 020
  • Joined: 07 февраля 07

Posted 28 сентября 2018 - 13:28

Цитата(Jenya7 @ Sep 28 2018, 13:27) <{POST_SNAPBACK}>
у меня есть несколько обработчиков прерывания, на UART, на CAN, но там эта переменная никак не появляется. я прбовал объявить ее static - не помогло.

Да не эта переменная. Вообще любая переменная, которая используется в обработчике прерывания и вне его. cranky.gif
0

#10 User is offline   Jenya7 Icon

  • Профессионал
  • PipPipPipPipPip
  • Group: Участник
  • Posts: 1 778
  • Joined: 29 марта 12

Posted 28 сентября 2018 - 13:40

Цитата(scifi @ Sep 28 2018, 16:28) <{POST_SNAPBACK}>
Да не эта переменная. Вообще любая переменная, которая используется в обработчике прерывания и вне его. cranky.gif


объявить их volatile?
0

#11 User is offline   VladislavS Icon

  • Местный
  • PipPipPip
  • Group: Свой
  • Posts: 475
  • Joined: 14 апреля 05

Posted 28 сентября 2018 - 13:42

Цитата(Jenya7 @ Sep 28 2018, 13:40) <{POST_SNAPBACK}>
объявить их volatile?
А когда-то можно было не объявлять?
0

#12 User is offline   scifi Icon

  • Гуру
  • PipPipPipPipPipPip
  • Group: Свой
  • Posts: 3 020
  • Joined: 07 февраля 07

Posted 28 сентября 2018 - 13:43

Цитата(Jenya7 @ Sep 28 2018, 13:40) <{POST_SNAPBACK}>
объявить их volatile?

Можно и так, типа ковровой бомбардировки. А можно внимательно посмотреть на код и попробовать понять, какие из них требуют volatile, а какие - нет.
0

#13 User is offline   E.V.G. Icon

  • Участник
  • Pip
  • Group: Участник
  • Posts: 34
  • Joined: 31 января 10

Posted 28 сентября 2018 - 13:50

Либо mot_num становится отрицательным из-за (RxMessage.ExtId & 0xFF) < BASE_MOTOR_ID, либо opcode не соответствует перечню команд в switch.
Копайте в этом направлении.
0

#14 User is offline   Сергей Борщ Icon

  • Гуру
  • PipPipPipPipPipPip
  • Group: Модераторы
  • Posts: 8 455
  • Joined: 15 мая 06

Posted 28 сентября 2018 - 14:04

Теперь покажите объявление can_params. Ее член message_received меняется в прерываниии?
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
0

#15 User is offline   Jenya7 Icon

  • Профессионал
  • PipPipPipPipPip
  • Group: Участник
  • Posts: 1 778
  • Joined: 29 марта 12

Posted 28 сентября 2018 - 14:12

Цитата(E.V.G. @ Sep 28 2018, 16:50) <{POST_SNAPBACK}>
Либо mot_num становится отрицательным из-за (RxMessage.ExtId & 0xFF) < BASE_MOTOR_ID, либо opcode не соответствует перечню команд в switch.
Копайте в этом направлении.


так в любом случае return ack; ack - oн всегда будет определен.

Цитата(Сергей Борщ @ Sep 28 2018, 17:04) <{POST_SNAPBACK}>
Теперь покажите объявление can_params. Ее член message_received меняется в прерываниии?


я заменил флаг can_params.message_received на volatile uint32_t can_message_received; и он устанавливается в прерывании
Код
void USB_LP_CAN1_RX0_IRQHandler(void)
{
  can_params.fifo_num = CAN_FIFO0;
  
  can_message_received = 1;

  CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
}


ради эксперемента сделал /*master_ack = */ CAN_RX_Master(); и в начале функции опроса жестко поставил master_ack = 1; - все равно заходит в else.

О! Только после того как определил static volatile uint32_t master_ack; - все стало на свои места. отдельно static или отдельно volatile не работает.

This post has been edited by Jenya7: 28 сентября 2018 - 14:43

0

  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

1
0