Перейти к содержанию
    

Странная проблема при оптимизации

в начале функции опроса жестко поставил master_ack = 1; - все равно заходит в else.

Кстати, с "заходит" тоже бывают сюрпризы. При высоком уровне оптимизации исходник и машинный код соотносятся очень условно. Курсор в отладчике может прыгать по исходнику довольно хаотично. Чтобы точно сказать, что "заходит", надо там сделать вывод в UART или что-то типа того.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кстати, с "заходит" тоже бывают сюрпризы. При высоком уровне оптимизации исходник и машинный код соотносятся очень условно. Курсор в отладчике может прыгать по исходнику довольно хаотично. Чтобы точно сказать, что "заходит", надо там сделать вывод в UART или что-то типа того.

да но если я не ставлю точку останова а код свободно бежит то в результате мастер не находит слейв. а без оптимизации находит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

да но если я не ставлю точку останова а код свободно бежит то в результате мастер не находит слейв. а без оптимизации находит.

Скорее всего, не на тот участок кода смотрите. Надёжнее выводить значения интересующих переменных через тот же UART, так оптимизатор их не покорёжит. Внутрисхемный отладчик может и не помочь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кстати, с "заходит" тоже ...

 

 

+100500

 

2TC

странно когда программист говорит компилятору - а теперь сделай красиво как хошь... а потом требует на отладке все стэпы которые ему казались что должны быть. Не находите?

Если вы хотите дебажить выхлоп оптимизатора - то ТОЛЬКО(!) на уровне азма. всё остальное будет от лукавого.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Пляски с бубном. Отключите оптимизацию, Вы к ней явно не готовы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 9/28/2018 at 8:40 PM, scifi said:

Пляски с бубном. Отключите оптимизацию, Вы к ней явно не готовы.

А вот в техподдержке IARа подтвердили что так быть не должно. так что посмотрим еще кто к чему не готов.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

31 minutes ago, jenya7 said:

А вот в техподдержке IARа подтвердили что так быть не должно. так что посмотрим еще кто к чему не готов.

 

Если докопаетесь до сути, отпишитесь, интересно же. Ну а я пока смотрю на всё это скептически. Должно быть, тех. поддержка ещё не разобралась. Мы же не разобрались, а чем мы хуже той поддержки?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, scifi said:

Если докопаетесь до сути, отпишитесь, интересно же. Ну а я пока смотрю на всё это скептически. Должно быть, тех. поддержка ещё не разобралась. Мы же не разобрались, а чем мы хуже той поддержки?

я послал им проект на расмотрение. они еще не ответили. для начала посоветовали (кто бы сомневался) обновить версию. у меня 7.7 а там уже 8.х на горизонте маячит.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 9/28/2018 at 3:12 PM, jenya7 said:

я заменил флаг can_params.message_received на volatile uint32_t can_message_received; и он устанавливается в прерывании

А сбрасывается где?

переменная can_message_received должна быть volatile и меняться только в одной функции - в прерывании.

например:

volatile u32 CMR=0;

void interupt (void)
{
CMR++;
}

void main(void)
{
static u32 CMR_T=0;

initInterrupt();

if (CMR_T!=CMR)
	{
	printf("interrupt!!!\n");
	CMR_T++; //or  CMR_T=CMR;
	}
}

никакого смысла вызывать функцию и сохранять результат в volatile - нет. это костыль.

 

конструкция static volatile допустима в Си, но говорит о непонимании алгоритма работы МК.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, _4afc_ said:

А сбрасывается где?

переменная can_message_received должна быть volatile и меняться только в одной функции - в прерывании.

например:

никакого смысла вызывать функцию и сохранять результат в volatile - нет. это костыль.

 

конструкция static volatile допустима в Си, но говорит о непонимании алгоритма работы МК.

да ладно. у меня все проекты работают с выставлением флага в прерывании и очисткой его в принимающей функции. иначе зачем volatile.

void ISR(void)
{
    flag = 1;
}


void RX_Func(void)
{
    if (flag)
    {
        flag = 0;

        //do something
    }
}

и потом дело совсем в другом. мы отклонились от первоначальной темы.

 

загрузил проект в IAR 8.22.2 - то же самое  при static volatile uint32_t master_ack;  работает. по другому - не работает. даже без отладки. в ран тайм.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, _4afc_ сказал:

конструкция static volatile допустима в Си, но говорит о непонимании алгоритма работы МК.

Да ладно?! С чего бы это? Видимо я тоже не понимаю работы МК, раз у меня во всех проектах полно таких переменных.  :)))))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

44 minutes ago, jenya7 said:

да ладно. у меня все проекты работают с выставлением флага в прерывании и очисткой его в принимающей функции. иначе зачем volatile.

и потом дело совсем в другом. мы отклонились от первоначальной темы.

загрузил проект в IAR 8.22.2 - то же самое  при static volatile uint32_t master_ack;  работает. по другому - не работает. даже без отладки. в ран тайм.

 

проект на си или с++?

master_ack используется в одном файле или нескольких?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, jenya7 said:

да ладно. у меня все проекты работают с выставлением флага в прерывании и очисткой его в принимающей функции.

Вот не совсем понял, используете ли Вы volatile, возможно да, но позвольте расставить точки...

int flag = 0;

void ISR(void) 
{ 
    flag = 1; 
} 

void RX_Func(void) 
{ 
    if (flag) 
    { 
         flag = 0; 
         //do something 
    } 
}

Вот это пример того где переменная flag должна использоваться с volatile. Без volatile действия будут происходить примерно так: Оптимизатор, увидит что функцию ISR() никто не вызывает и решит что переменную flag можно оставить в инициализированном значении, потом смотрит, а там if а значение не меняется, ну и выкасит весь или одну из частей if/else если оно есть.
Если Вы используете volatile, оптимизатор просто не анализирует данную переменную и оставляет все как есть.

И самое главное правило при работе с оптимизацией: Не пытайся предугадать что сделает оптимизатор!
Поэтому выше описанный алгоритм это только мои фантазии, как себя поведет оптимизация никто не знает :) , но что делает ключевое слово volatile Вы сможете найти в стандарте С.

Теперь про static, разберитесь для чего это ключевое слово и не подставляйте его бездумно, хотя бы постесняйтесь писать нам об этом)! Это не проффесионально!
Если на пальцах: Есть всего три варианта использования static, два из них ограничить область видимости функции либо глобальной переменной, рамками одного объектного файла
Третий вариант использования говорит о том, что локальная переменная располагается не на стеке и инициализируется единожды!

Теперь по поводу заявок на то что не работает оптимизация. В 99.999% это не плохой компилятор, это ошибки в коде! И в данном случае чтобы помочь нам, найти вам проблему, нужен весь листинг этого случая!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, _4afc_ сказал:

CMR_T++; //or CMR_T=CMR;

А вот так делать действительно нельзя, ибо без критической секции здесь результат будет неопределённым.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

Just now, jcxz said:

А вот так делать действительно нельзя, ибо без критической секции здесь результат будет неопределённым.

Почему неопределённым? Если мы не хотим пропустить количество?

CMR_T++ должно помочь

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...