Я хочу запустить периодическое «служебное» событие, которое регулярно вызывается прерыванием по таймеру.Прерывание срабатывает часто (кГц +), хотя для завершения функции может потребоваться много времени, поэтому я не могу просто выполнить ее в строке.
В прошлом я делал это на ATMEGA,где ISR может просто разрешить другим прерываниям запускать (включая себя снова) с помощью sei ().Оборачивая событие в флаг «все еще выполняется», оно не накапливается в стеке и не вызывает ... вы знаете:
if (!inFunction) { inFunction = true; doFunction(); inFunction = false; }
Я не думаю, что это можно сделать -по крайней мере так же легко - на XMEGA, благодаря контроллеру прерываний PMIC.Похоже, что флаги прерывания могут быть сброшены только путем выполнения RETI.
Итак, я подумал, что было бы удобно, если бы я мог убедить GCC произвести хвостовой вызов из прерывания.Это немедленно выполнило бы событие, одновременно очистив прерывания.
Это было бы достаточно легко сделать в ассемблере, просто нажмите адрес и IRET.(Ну, немного стеков, потому что ISR, но, да.) Но я предполагаю, что это будет хак в GCC, возможно, пользовательская оболочка ASM вокруг «голой» функции?
Альтернативно, яЯ хотел бы просто установить программное прерывание с низким приоритетом, но я не вижу преднамеренного способа сделать это.
Я мог бы использовать программное обеспечение для запуска прерывания от неиспользуемого в противном случае периферийного устройства.Это хорошо в качестве особого случая, но затем, если мне когда-нибудь понадобится использовать это устройство, я должен найти другое.Это также плохо для повторного использования кода.
Действительно, это проблема XY, и я это знаю.Я думаю, что хочу сделать X, но на самом деле мне нужен метод Y, о котором я просто не знаю.
Один лучший способ - установить флаг, а затем позволить main () с ним справиться, когда он обойдётк этому.К сожалению, у меня есть функции блокировки в main () (обработка пользовательского ввода через последовательный порт), так что это потребует работы и станет беспорядком.полное переключение задач - но, черт возьми, если я собираюсь эффективно внедрить ОСРВ, или вытащить ее, только для этого.Должен быть лучший способ.
Я действительно покрыл все возможности и загнал себя в угол?Должен ли я пойти на компромисс и выбрать один из них?Я что-то пропустил лучше?