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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Странная проблема при оптимизации
Jenya7
сообщение Sep 28 2018, 09:29
Сообщение #1


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Есть такой код
Код
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?

Сообщение отредактировал Jenya7 - Sep 28 2018, 09:31
Go to the top of the page
 
+Quote Post
scifi
сообщение Sep 28 2018, 09:50
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



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

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

Есть и другие варианты. 1) Найти косяк в своём коде. 2) Не включать оптимизацию.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Sep 28 2018, 09:55
Сообщение #3


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



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


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


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

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

Сообщение отредактировал Jenya7 - Sep 28 2018, 10:00
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 28 2018, 10:05
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



CAN_RX_Master() покажите. Предполагаю, что оптимизатор видит ее тело, находит в нем только один возможный результат и выкидывает все условие.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
scifi
сообщение Sep 28 2018, 10:08
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



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

Мы же не видим ваш код и настройки сборки. Компилятор даже умеет собирать программы, смешивая код и переменные из разных файлов. Если увидит, что переменная не нужна (да хотя бы и глобальная) - может выкинуть её. Ну а volatile - это в качестве примера, и скорее всего в каком-то другом месте. Кстати, из очевидных кандидатов - переменные, через которые передаются сигналы из обработчиков прерываний.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Sep 28 2018, 10:18
Сообщение #6


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Сергей Борщ @ Sep 28 2018, 16:05) *
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;
}
Go to the top of the page
 
+Quote Post
scifi
сообщение Sep 28 2018, 10:24
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



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

Обработчик прерывания есть?
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Sep 28 2018, 10:27
Сообщение #8


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



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

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


у меня есть несколько обработчиков прерывания, на UART, на CAN, но там эта переменная никак не появляется. я прбовал объявить ее static - не помогло.
Go to the top of the page
 
+Quote Post
scifi
сообщение Sep 28 2018, 10:28
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



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

Да не эта переменная. Вообще любая переменная, которая используется в обработчике прерывания и вне его. cranky.gif
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Sep 28 2018, 10:40
Сообщение #10


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



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


объявить их volatile?
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Sep 28 2018, 10:42
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Цитата(Jenya7 @ Sep 28 2018, 13:40) *
объявить их volatile?
А когда-то можно было не объявлять?
Go to the top of the page
 
+Quote Post
scifi
сообщение Sep 28 2018, 10:43
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



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

Можно и так, типа ковровой бомбардировки. А можно внимательно посмотреть на код и попробовать понять, какие из них требуют volatile, а какие - нет.
Go to the top of the page
 
+Quote Post
E.V.G.
сообщение Sep 28 2018, 10:50
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 31-01-10
Из: Арзамас
Пользователь №: 55 175



Либо mot_num становится отрицательным из-за (RxMessage.ExtId & 0xFF) < BASE_MOTOR_ID, либо opcode не соответствует перечню команд в switch.
Копайте в этом направлении.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 28 2018, 11:04
Сообщение #14


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Теперь покажите объявление can_params. Ее член message_received меняется в прерываниии?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Sep 28 2018, 11:12
Сообщение #15


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



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


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

Цитата(Сергей Борщ @ Sep 28 2018, 17:04) *
Теперь покажите объявление 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 не работает.

Сообщение отредактировал Jenya7 - Sep 28 2018, 11:43
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 April 2024 - 16:54
Рейтинг@Mail.ru


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