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

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

4 минуты назад, Integro сказал:

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

Расширим пальцы:  :)

static используется не только для переменных, но и как модификатор для функций и членов структур/классов.

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


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

2 минуты назад, _4afc_ сказал:

 

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

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

Потому что операция инкремента неатомарна на многих архитектурах. А она у Вас модифицируется в ISR. Тогда в фоновом процессе она должна быть защищена критической секцией (или атомарность ++ должна быть достигнута иным способом).

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


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

Just now, jcxz said:

Потому что операция инкремента неатомарна на многих архитектурах. А она у Вас модифицируется в ISR. Тогда в фоновом процессе она должна быть защищена критической секцией (или атомарность ++ должна быть достигнута иным способом).

Если CMR размером 1 байт или CMR записывается на асме одной командой в память атомарность вроде сохранится.

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


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

11 минут назад, _4afc_ сказал:

Если CMR размером 1 байт или CMR записывается на асме одной командой в память атомарность вроде сохранится.

Какая разница сколько байт??? И операция инкремента это не просто запись, это - чтение-модификация-запись. А только запись она да - скорее всего будет атомарна .

LDRB R0, [...]

ADDS R0, R0, #1

STRB R0, [...]

Попробуйте теперь вставить вызов прерывания в любую точку до/после/или между этими командами и увидите что результаты будут совершенно разные.

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


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

8 minutes ago, jcxz said:

Расширим пальцы:  :)

static используется не только для переменных, но и как модификатор для функций и членов структур/классов.

Тут речи про классы и плюсы небыло, я про чистый С.
Повторюсь, три случая:
1. static void _local_func(void); // функция видна в рамках обьектника
2. static my_type_t _local_common_variable = 0;  // переменна видна в рамках обьектника
3. static uint32_t call_counter = 0;  // Переменная в функции

Или есть еще какие варианты? я про чистый си. Если можите развернуто ответить про CPP, рад послушать про статические члены структур (но не классов).

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


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

1 минуту назад, Integro сказал:

Тут речи про классы и плюсы небыло, я про чистый С.

Я тоже. Как ни странно даже чистый си имеет struct.

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


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

2 минуты назад, Integro сказал:

Или есть еще какие варианты? я про чистый си.

Я же уже написал варианты, читайте внимательнее:

static void Func() {}

struct Typ {

static int member;

};

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


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

Just now, jcxz said:

Какая разница сколько байт??? И операция инкремента это не просто запись, это - чтение-модификация-запись. А только запись она да - скорее всего будет атомарна .


LDRB R0, [...]

ADDS R0, R0, #1

STRB R0, [...]

Попробуйте теперь вставить вызов прерывания в любую точку до/после/или между этими командами и увидите что результаты будут совершенно разные.

В моём примере предполагалось, что в прерывании меняется переменная CMR.

А в main который не в прерывании её значение мониторится.

Я исходил из того, что main не может прервать ISR - потому инкремент в ISR атомарен.

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


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

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

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

 

Может у нас эта проблема:

Quote

If functions and variables are not refered to in the main() call-tree or in any interrupt call-tree the linker will remove them by default.

You can prevent this and force the linker to keep a certain variable or function by using the __root extension keyword.

IAR - Technical Note 51348

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


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

5 минут назад, _4afc_ сказал:

А в main который не в прерывании её значение мониторится.

У Вас в main() не мониторится, а инкрементируется.

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


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

Just now, jcxz said:

У Вас в main() не мониторится, а инкрементируется.

Там другая переменная, CMR_T которая пытается догнать CMR.

Для атомарности можно ещё вытащить CMR из if типа

u32 cmr2;

cmr2=cmr;

if (cmr2!=cmr_t) ...

 

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


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

1 hour ago, jcxz said:

Я же уже написал варианты, читайте внимательнее:

static void Func() {}

struct Typ {

static int member;

};

 

Про статическую функцию я писал, Вы видимо, не заметили!

 

Вот этот код не скомпилируется С компилятором:

struct Typ {
    static int member;
};

 

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


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

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

master_ack равен 1. при optimization = High я попадаю в else. при optimization = Low я попадаю в if.

 А вы это под отладкой просто смотрели?

Может лучше просто листинг этого куска посмотреть, тогда будет понятнее.

При высоком уровне оптимизации (особенно когда части then и else короткие ), например, может быть использован IT блок и then с else поменян местами, так что вообще по с коду будут непонятны перемещения, а если еще там функции заинлайнятся.... 

 

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


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

мда... ребята проблемы не нашли

Quote

We have tried to reproduce the problem but not yet managed to do so.

Our test shows that the first branch is reached with optimization level High (Balanced, Size, Speed), in other words, same result as with optimization level Low.
We also tried to remove the 'volatile' from the declaration of master_ack.
We have modified the project so that it can run in the simulator from main(). Just do "step into" until execution ends up in the if statement in MASTER_MotInit.

Please modify the project so that we can repeat the issue with the simulator and send it back to us.

как говориться - с нашей стороны все патроны вышли. а вы их у себя ловите.

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


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

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

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

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

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

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

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

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

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

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