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

 
 
> Как отучить IAR использовать регистры FPU где не нужно?
jcxz
сообщение Aug 18 2018, 20:25
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Столкнулся с очень неприятным моментом в работе IAR:
В какой-то момент заглянул в листинг и увидел, что копируя структуру, IAR использует регистры FPU!
Хотя и рядом нет никаких операций с плавучкой. Просто есть структура, есть две переменных типа этой структуры и есть операция копирования одной переменной в другую (присваиванием, без memcpy()). И я вижу что IAR 7.80.4 лепит такой код (с оптимизацией и без):
Код
ADD      R2,SP,#+8
VLDM     R2,{D0-D3}
VSTM     R1,{D0-D3}

Что очень неприятно, ведь работа идёт под РТОС, в одной из задач ОС. В этой задаче нет никаких операций с плавучкой. Соответственно данная задача создаётся с указанием ОС что она не использует FPU. Соответственно ОС при переключении контекста с/в данную задачу не сохраняет/восстанавливает регистры FPU. Соответственно - будут разрушены регистры FPU в тех задачах, которые используют FPU (а также в тех, в коих IAR так же впихнул такое копирование через FPU).
Некоторые задачи в программе используют плавучку, значит полностью запретить FPU нельзя. Можно конечно сделать сохранение контекста FPU для всех задач вне зависимости от использования ими FPU, но не хотелось бы, так как все стеки задач придётся увеличить, увеличится время переключений контекста задач. Да и вообще - зачем? ОЗУ ведь не резиновая?

Как запретить IAR-у использовать регистры FPU для всего, кроме операций с плавучкой? Что-то в мануале не найду ничего про такое.... sad.gif(((((
Go to the top of the page
 
+Quote Post
3 страниц V  < 1 2 3 >  
Start new topic
Ответов (15 - 29)
ih_
сообщение Aug 23 2018, 13:40
Сообщение #16


Частый гость
**

Группа: Свой
Сообщений: 77
Регистрация: 2-04-08
Из: Россия, Киров
Пользователь №: 36 422



Цитата(jcxz @ Aug 23 2018, 12:34) *
А какая разница?...
Есть разница. У некоторых МК РОНы отображаются на память. И если в Вашем случае это так, то я хотел предложить создать по этому адресу volatile переменную, тогда компилятор не посягнул бы на эту область памяти - регистр.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Aug 23 2018, 13:41
Сообщение #17


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(AlexandrY @ Aug 19 2018, 14:44) *
Между тем в uCOS для портов на ARM под IAR повсеместно используется запрет на сохранение контекста FP.

Ошибся.
В uCOS-III опция OS_OPT_TASK_SAVE_FP есть , но для порта под Cortex-M4 не применяется.
Т.е. если компилятор объявил макрос __ARMVFP__ , то все задачи без исключения сохраняют контекст fpu.
Другое дело, что в startup файлах из bsp может случайно не взводится флаг FPCA в регистре CONTROL, допустим проигнорен вызов __iar_program_start, и прерывания по умолчанию не сохраняют контекст fpu.

Эт в MQX версии community большая проблема, там такая опция работает и реально блокирует сохранение контекста fpu при переключении задач, а FPCA сознательно не взводится.
Так они ускоряют переключение контекста.

Экспериментировал как-то насколько сохранение контекста fpu увеличивает расход процессорного времени в обычном режиме. Не обнаружил существенной разницы.
Однако на быстрых прерываниях ядра обслуживающих сэмплирование в токовой цепи моторов менее чем за 1 мкс все становится критичней.
И тут MQX работает умнее чем uCOS и прочие FreeRTOS-ы.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Aug 23 2018, 14:02
Сообщение #18


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



А что, флажок который говорит что FPU поюзали и его надо сохранить - отменили?
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Aug 23 2018, 14:29
Сообщение #19


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(Genadi Zawidowski @ Aug 23 2018, 17:02) *
А что, флажок который говорит что FPU поюзали и его надо сохранить - отменили?

Беда в том, что флажок не говорит. laughing.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 23 2018, 14:49
Сообщение #20


Гуру
******

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



QUOTE (jcxz @ Aug 23 2018, 12:34) *
А какая разница? Контекст то ведь будет сохранять та же функция ОС, которая сохраняет и при вытеснении в тот же формат.
Пожалуй, вы правы. Тогда источником проблем остается только такой сценарий - задача, не сохраняющая регистры сопроцессора в момент копирования структуры через эти регистры прерывается другой задачей - либо законно использующей сопроцессор, либо такой же, которая в это время тоже решит скопировать структуру. Действительно, трудноотлавливаемый момент.


--------------------
На любой вопрос даю любой ответ
"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
Genadi Zawidowsk...
сообщение Aug 23 2018, 16:31
Сообщение #21


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Цитата
флажок не говорит
Баг в ядре процессора?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 23 2018, 20:01
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ih_ @ Aug 23 2018, 16:40) *
Есть разница. У некоторых МК РОНы отображаются на память. И если в Вашем случае это так, то я хотел предложить создать по этому адресу volatile переменную, тогда компилятор не посягнул бы на эту область памяти - регистр.

Я писал выше - у меня Cortex-M4. У него регистры никуда не отображаются.

Цитата(AlexandrY @ Aug 23 2018, 16:41) *
Т.е. если компилятор объявил макрос __ARMVFP__ , то все задачи без исключения сохраняют контекст fpu.
Другое дело, что в startup файлах из bsp может случайно не взводится флаг FPCA в регистре CONTROL, допустим проигнорен вызов __iar_program_start, и прерывания по умолчанию не сохраняют контекст fpu.

И FPCA и ASPEN и LSPEN (в FPCCR) у меня сброшены. И сброшены не случайно, поверьте про них я знаю. Сброшены потому что в ISR-ах в этом проекте плавучку не использую.
Я не знаю как там дела обстоят в uCOS-III, у меня uCOS-II. И читать и понимать исходники я думаю что умею. Эта функция в uCOS-II вызывается при переключении активной задачи:
CODE
#if (OS_CPU_HOOKS_EN > 0u) && (OS_TASK_SW_HOOK_EN > 0u)
void OSTaskSwHook (void)
{

#if (OS_CPU_ARM_FP_EN > 0u)
if ((OSTCBCur->OSTCBOpt & OS_TASK_OPT_SAVE_FP) != (INT16U)0) {
OS_CPU_FP_Reg_Push(OSTCBCur->OSTCBStkPtr);
}

if ((OSTCBHighRdy->OSTCBOpt & OS_TASK_OPT_SAVE_FP) != (INT16U)0) {
OS_CPU_FP_Reg_Pop(OSTCBHighRdy->OSTCBStkPtr);
}
#endif

#if OS_APP_HOOKS_EN > 0u
App_TaskSwHook();
#endif
}
#endif

OS_CPU_HOOKS_EN, OS_TASK_SW_HOOK_EN, OS_CPU_ARM_FP_EN - все равны 1.
OS_CPU_FP_Reg_Push и OS_CPU_FP_Reg_Pop - тоже не пустые и делают то, что и полагается.
Обратите внимание на OS_TASK_OPT_SAVE_FP - именно этот флаг передаётся в аргументе prio (6-й бит) и говорит ОСи что задача юзает FPU и что нужно в сохраняемый/восстанавливаемый контекст для данной задачи включить регистры FPU.
Более того - одна из задач (Idle-задача) у меня имеет размер стека == 64 байта, т.е. - только-только чтобы сохранить регистры CPU, и если-бы туда сохранялись ещё и регистры FPU, то данные выше этого стека были бы снесены, а там весьма важные данные и они не портятся.
Да и отладчиком я пользоваться умею всё-таки... laughing.gif

Цитата(Genadi Zawidowski @ Aug 23 2018, 17:02) *
А что, флажок который говорит что FPU поюзали и его надо сохранить - отменили?

Когда FPU поюзала процедура копирования, то сохранять уже поздно.

Цитата(Сергей Борщ @ Aug 23 2018, 17:49) *
Пожалуй, вы правы. Тогда источником проблем остается только такой сценарий - задача, не сохраняющая регистры сопроцессора в момент копирования структуры через эти регистры прерывается другой задачей - либо законно использующей сопроцессор, либо такой же, которая в это время тоже решит скопировать структуру. Действительно, трудноотлавливаемый момент.

Да, Вы правы, именно в таком случае. Когда задача копирует через FPU, то значит она в этот момент активная, а все остальные задачи выгружены в память (все их копии регистров FPU все находятся в памяти). И естественно в этом случае она не может эти данные попортить. Но вот её данные - попортить могут.

PS: Кстати - Ваше замечание навело меня на мысль, что в качестве костыля можно на время копирования структур запрещать прерывания (критическая секция).
Правда нет гарантии, что при копировании просто нескольких переменных, расположенных рядом, оптимизатор не захочет также прибегнуть к FPU. Или не копировании, а заполнении их константой. sad.gif
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Aug 23 2018, 20:05
Сообщение #23


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(jcxz @ Aug 23 2018, 22:41) *
Я не знаю как там дела обстоят в uCOS-III, у меня uCOS-II. И читать и понимать исходники я думаю что умею.

За uCOS-II я не писал, как раз чтобы вам предоставить возможность высказаться.

Все идет к тому что надо переходить на mbed. Самая нативная RTOS.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 23 2018, 20:14
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(AlexandrY @ Aug 23 2018, 23:05) *
Все идет к тому что надо переходить на mbed. Самая нативная RTOS.

А толку? как это поможет? IAR, узрев её исходники, сразу поостерегётся своевольничать? cool.gif
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 24 2018, 04:05
Сообщение #25


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(jcxz @ Aug 23 2018, 23:01) *
PS: Кстати - Ваше замечание навело меня на мысль, что в качестве костыля можно на время копирования структур запрещать прерывания (критическая секция).

А я сразу подумал о таком решении, но постеснялся предлагать очевидное.
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Aug 24 2018, 09:40
Сообщение #26


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата(jcxz @ Aug 24 2018, 00:01) *
PS: Кстати - Ваше замечание навело меня на мысль, что в качестве костыля можно на время копирования структур запрещать прерывания (критическая секция).

Именно так и пришлось делать в одном из проектов под ZYNQ, поскольку там компилятор в memcpy() использует FPU-регистры.
А где-то на сайте FreeRTOS даже читал, что действительно есть такой косяк. Вызываю в начале задачи vPortTaskUsesFPU() (даже забыл, что и во FreeRTOS можно указать задаче, использует ли она FPU или нет), и все равно все memcpy() защищаю критической секцией.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Aug 24 2018, 14:39
Сообщение #27


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(jcxz @ Aug 23 2018, 23:14) *
А толку? как это поможет? IAR, узрев её исходники, сразу поостерегётся своевольничать? cool.gif

Да нет, просто в IAR 8.30 появился неплохой плагин под mbed. Можно уже нормально юзать. А там самый короткий переключатель контекста.

Кстати, в версии 8.30 у меня не получилось заставить использовать fpu при копировании структур.
Так что тревога отменяется.


Цитата(ViKo @ Aug 24 2018, 07:05) *
А я сразу подумал о таком решении, но постеснялся предлагать очевидное.

Если речь идет об ISR уровня ядра длительностью в 0.5 мкс и джитером 0.1 мкс , то такой путь неприемлем.
Хотя кому в голову придет в таких ISR копировать структуры!?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 25 2018, 05:08
Сообщение #28


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



И зачем их копировать? Для малых структур я копирую поэлементно. А большие копирую через указатели на int, приведя к ним адреса структур исходной и назначения.
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Aug 25 2018, 06:42
Сообщение #29


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата(ViKo @ Aug 25 2018, 08:08) *
И зачем их копировать? Для малых структур я копирую поэлементно. А большие копирую через указатели на int, приведя к ним адреса структур исходной и назначения.

Это еще зачем?
Ведь структурные типы можно присваивать друг другу. Например
Код
typedef struct
{...}TMyStruct;

TMyStruct s1, s2;
...
s1 = s2;

Наглядно, читабельно и понятно. Без всяких приведений на int и поэлементных копирований...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 25 2018, 06:44
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Aug 25 2018, 08:08) *
И зачем их копировать? Для малых структур я копирую поэлементно. А большие копирую через указатели на int, приведя к ним адреса структур исходной и назначения.

Умный оптимизатор может объединить ваши соседние копирования в более крупное одно. И получится то же самое. И не только структуры, можно предположить что любые рядом расположенные копирования смежных переменных: оптимизатору ведь по-барабану - единая это структура или просто несколько переменных, если адреса в памяти расположены смежно и нет volatile.
Здесь ключевой момент (как я показывал вначале): чтобы размер структуры был кратен 32 байтам - тогда видимо и используется FPU.
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd August 2025 - 09:40
Рейтинг@Mail.ru


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