Цитата(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, то данные выше этого стека были бы снесены, а там весьма важные данные и они не портятся.
Да и отладчиком я пользоваться умею всё-таки...
Цитата(Genadi Zawidowski @ Aug 23 2018, 17:02)
А что, флажок который говорит что FPU поюзали и его надо сохранить - отменили?
Когда FPU поюзала процедура копирования, то сохранять уже поздно.
Цитата(Сергей Борщ @ Aug 23 2018, 17:49)
Пожалуй, вы правы. Тогда источником проблем остается только такой сценарий - задача, не сохраняющая регистры сопроцессора в момент копирования структуры через эти регистры прерывается другой задачей - либо законно использующей сопроцессор, либо такой же, которая в это время тоже решит скопировать структуру. Действительно, трудноотлавливаемый момент.
Да, Вы правы, именно в таком случае. Когда задача копирует через FPU, то значит она в этот момент активная, а все остальные задачи выгружены в память (все их копии регистров FPU все находятся в памяти). И естественно в этом случае она не может эти данные попортить. Но вот её данные - попортить могут.
PS: Кстати - Ваше замечание навело меня на мысль, что в качестве костыля можно на время копирования структур запрещать прерывания (критическая секция).
Правда нет гарантии, что при копировании просто нескольких переменных, расположенных рядом, оптимизатор не захочет также прибегнуть к FPU. Или не копировании, а заполнении их константой.