jenya7 0 28 сентября, 2018 Опубликовано 28 сентября, 2018 (изменено) · Жалоба Есть такой код 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? Изменено 28 сентября, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба Грабли обычно одни и те же: volatile и гонки. Все? Сливаем IAR? Есть и другие варианты. 1) Найти косяк в своём коде. 2) Не включать оптимизацию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 сентября, 2018 Опубликовано 28 сентября, 2018 (изменено) · Жалоба Грабли обычно одни и те же: volatile и гонки. Есть и другие варианты. 1) Найти косяк в своём коде. 2) Не включать оптимизацию. volatile? а с чего он оптимизирует обычную глобальную переменную? Не включать оптимизацию? оптимизация - это единственное наиболее сильное преимущество IAR. Без оптимизации и в Атолике можно кропать. определил как volatile - то же самое - заходит в else. Изменено 28 сентября, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба CAN_RX_Master() покажите. Предполагаю, что оптимизатор видит ее тело, находит в нем только один возможный результат и выкидывает все условие. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба volatile? а с чего он оптимизирует обычную глобальную переменную? Мы же не видим ваш код и настройки сборки. Компилятор даже умеет собирать программы, смешивая код и переменные из разных файлов. Если увидит, что переменная не нужна (да хотя бы и глобальная) - может выкинуть её. Ну а volatile - это в качестве примера, и скорее всего в каком-то другом месте. Кстати, из очевидных кандидатов - переменные, через которые передаются сигналы из обработчиков прерываний. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба CAN_RX_Master() покажите. Предполагаю, что оптимизатор видит ее тело, находит в нем только один возможный результат и выкидывает все условие. 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; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба Процитирую себя: Кстати, из очевидных кандидатов - переменные, через которые передаются сигналы из обработчиков прерываний. Обработчик прерывания есть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба Процитирую себя: Обработчик прерывания есть? у меня есть несколько обработчиков прерывания, на UART, на CAN, но там эта переменная никак не появляется. я прбовал объявить ее static - не помогло. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба у меня есть несколько обработчиков прерывания, на UART, на CAN, но там эта переменная никак не появляется. я прбовал объявить ее static - не помогло. Да не эта переменная. Вообще любая переменная, которая используется в обработчике прерывания и вне его. :cranky: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба Да не эта переменная. Вообще любая переменная, которая используется в обработчике прерывания и вне его. :cranky: объявить их volatile? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба объявить их volatile?А когда-то можно было не объявлять? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба объявить их volatile? Можно и так, типа ковровой бомбардировки. А можно внимательно посмотреть на код и попробовать понять, какие из них требуют volatile, а какие - нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
E.V.G. 0 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба Либо mot_num становится отрицательным из-за (RxMessage.ExtId & 0xFF) < BASE_MOTOR_ID, либо opcode не соответствует перечню команд в switch. Копайте в этом направлении. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба Теперь покажите объявление can_params. Ее член message_received меняется в прерываниии? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 сентября, 2018 Опубликовано 28 сентября, 2018 (изменено) · Жалоба Либо mot_num становится отрицательным из-за (RxMessage.ExtId & 0xFF) < BASE_MOTOR_ID, либо opcode не соответствует перечню команд в switch. Копайте в этом направлении. так в любом случае return ack; ack - oн всегда будет определен. Теперь покажите объявление 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 не работает. Изменено 28 сентября, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться