Действительно, ошибка была. Сейчас я её поправил. Но не факт, что больше нет других ошибок.
Проблема в том, что в архитектуре Cortex-M1 неудобно сделано маскирование прерываний.
Напомню всю историю.
С помощью регистра PRIMASK маскируются все прерываний и исключения, кроме тех, у которых приоритет отрицательный. К сожалению, исключение, используемое для переключения задач, SVC имеет приоритет 0. Кроме того, если вызывается SVC при PRIMASK=1, то происходит Hard Fault. Поэтому (это ещё ты, Максим, делал) пришлось перейти на PendSV для переключения задач.
Но это не решает основной проблемы: при PRIMASK=1 невозможно переключить задачи!
Я переделал (в предыдущих версиях) маскирование прерываний таким образом:
arm_intr_disable сбрасывает в ноль маску контроллера прерываний NVIC, PRIMASK при этом остаётся равным 0, т.е. переключение задач возможно. При этом старая маска контроллера сохраняется в переменную, указанную в параметре arm_intr_disable.
arm_intr_restore восстанавливает маску NVIC из переменной.
Маска NVIC сохраняется в контексте задачи.
Это работало, если всего одна задача в системе (на этом я и тестировал). Но если несколько задач, то получалось, что маска сохранялась только в контексте самой приоритетной задачи, а в контексте других задач она была равна 0. Соответственно, после переключения на такую задачу, все прерывания оказывались замаскированы.
Чтобы обойти эту проблему, нужно сохранить в начальном контексте каждой задачи маску прерываний в том виде, как она есть при выходе из uos_init. Здесь пришлось пойти на непопулярные меры. Я добавил в kernel/main.c в функцию main() вызов uos_post_init (). Сама функция реализована в том же файле - она пустая, со слабой линковкой.
При необходимости эту функцию можно переопределить в machdep (что и сделано для cortex-m). В этой функции инициализируется контекст каждой задачи правильной маской NVIC.
После всего я вернул переключение задач с PendSV на SVC.
Твой тест test-irq.c с небольшими изменениями добавил в examples. Теперь он работает.
вторник, 27 августа 2013 г., 12:07:58 UTC+4 пользователь Дмитрий Подхватилин написал: