Описание бага:
В коде функции os_start() взводился флаг PendSV и разрешались прерывания. Тут же происходило прерывание PendSV, и из него вызывалась функция os_context_switch_hook(), в которой происходило обращение к ProcessTable[SchedProcPriority]. Однако этот момент переменная SchedProcPriority ещё не была проинициализирована. Она инициализируется только в TKernel::sched_isr().
Похоже, что нам везло просто, и SchedProcPriority был нулевым. (Таким образом первое переключение было на Idle-процесс).
Кроме того, поскольку первое прерывание происходило на Main Stack, то первое автоматическое сохранение контекста производилось на Main Stack, и от него бесполезно отъедалось 32 байта.
В настоящий момент всё исправлено (в репозитории, в ветке pre-v400). Бонусы - минус три команды из обработчика прерывания переключения контекста (~2.7мкс в 1-EventFlag), сэкономлено 32 байта стека.
Благодарности:
- Сергею Борщу за то, что затеял оптимизацию, в процессе которой всё и обнаружилось, и за предложенный вариант исправления;
- Андрею Чуйкину - за быстрое исправление порта для IAR;
- Ну и мне немножко