Я пишу код многопоточности для Cortex M4F. Все работает, и теперь я пытаюсь сделать переключение контекста FPU более эффективным с помощью ленивого стекирования.
Я прочитал AN298 и I. реализовал альтернативный подход, основанный на отключении FPU и обработке UsageFault, но нижние (S0-S15
) регистры не сохраняются / не восстанавливаются правильно аппаратными средствами. Я думаю, что проблема заключается в рисунке 11:
В соответствии с этим, когда PendSV запускается, FPCAR
должен указывать на пространство, зарезервированное в стеке задачи A. Но, как я понимаю, поскольку CONTROL.FPCA
находится на высоком уровне в задаче C, FPCAR
будет обновлен, чтобы указывать на стек задачи C при входе в PendSV. Если это так, S0-S15
и FPSCR
будут сохранены в стеке задачи C, а не задачи A, что, конечно, неверно.
Я что-то упустил или неправильно написано?
Кстати, я проверил несколько ОСРВ с открытым исходным кодом. FreeRTOS и mbed RTOS всегда складываются S16-S31
во время переключения контекста, что приводит к автоматическому S0-S15
стеку, то есть они используют отложенное стекание только для уменьшения задержки прерывания, но обеспечивают полное сохранение состояния для задач (как в первом подходе, описанном в приложении). Порт TNKernel для M4F использует подход UsageFault, но полностью сохраняет / восстанавливает S0-S31
с помощью программного обеспечения, эффективно обходя любую проблему с FPCAR
(за счет 48 загрузок / сохранений вместо 32, 16 аппаратных перезаписываются при восстановлении). Кажется, что никто не использует подход UsageFault, сохраняя только S16-S31
.
(Кстати, это также размещено в сообществе ARM, но многие вопросы, кажется, остаться без ответа там. Если я получу там ответ, я воспроизведу его и здесь)