Работа с прерываниями
Благодаря возможностям PinMux в SoC Plus1 почти любая линия Linux-платы Tibbo Project PCB размера 3 (LTPP3), 2-го поколения может работать как прерывание. Чтобы включить линию прерывания, выберите её свойством io.intnum, отключите линию свойством io.enabled, назначьте её прерыванием через io.intnum, при необходимости задайте фронт свойством io.intedge, а затем включите прерывание свойством io.intenabled:
io.num = PL_IO_NUM_11; // Set the I/O line to 11
io.enabled = NO; // Set the I/O line as an input
io.intnum = PL_INT_NUM_7; // Set the interrupt number to 7
io.intedge = INT_EDGE_BOTH; // Set the interrupt edge to BOTH
io.intenabled = YES; // Enable the interrupt
Обработчики событий
После включения линии изменение её состояния будет генерировать события on_io_int и on_io_int_line. Использовать оба обработчика не нужно - лучше выбрать какой-то один. Если объявить оба обработчика, то при возникновении прерывания, когда в очереди нет предыдущих событий прерывания, в очередь событий будет добавлено несколько событий.
Событие on_io_int
Аргумент linestate события on_io_int закодирован побитово: каждый бит значения соответствует одной линии прерывания. Для PL_INT_NUM_0 это бит 0, для PL_INT_NUM_1 - бит 1 и так далее. Бит аргумента linestate устанавливается, когда на соответствующей линии прерывания обнаружено изменение состояния (из LOW в HIGH или из HIGH в LOW). Обработчик события on_io_int может затем определить, что вызвало прерывание (см. пример ниже).
Для совместимости с приложениями, разработанными для платформ на базе TiOS, в очередь событий одновременно может быть добавлено только одно событие on_io_int.
Событие on_io_int_line
У события on_io_int_line три аргумента:
- ionum - номер линии ввода-вывода, на которой возникло прерывание (см. перечисление pl_io_num)
- intnum - номер линии прерывания, на которой возникло прерывание (см. перечисление pl_int_num)
- edge - фронт, по которому возникло прерывание (см. перечисление pl_int_edge)
Передача и номера линии ввода-вывода, и номера линии прерывания облегчает идентификацию и обработку прерываний. Обработчик события on_io_int_line может затем определить, что вызвало прерывание (см. пример ниже).
Событие on_io_int_line добавляется в очередь событий последовательно для каждого возникшего прерывания.
Пример
// Declare the on_io_int event handler
void on_io_int(byte linestate) {
// Print the value of the linestate argument
sys.debugprintline("on_io_int linestate: " + str(linestate));
}
// Declare the on_io_int_line event handler
void on_io_int_line(pl_io_num ionum, pl_int_num intnum, pl_int_edge edge) {
// Print the value of the ionum, intnum, and edge arguments
sys.debugprintline("on_io_int_line ionum: %d intnum: %d edge: %d", ionum, intnum, edge;
}
Результат будет таким:
on_io_int linestate: 128on_io_int_line ionum: 11 intnum: 7 edge: 1
Учтите, что слово «прерывание» здесь употребляется в несколько вольном смысле. В традиционных микроконтроллерах изменение состояния линии прерывания почти мгновенно приостанавливает выполнение основного кода и передаёт управление «процедуре прерывания». Отсюда и термин: выполнение основного кода прерывается.
В объекте io. изменение состояния линии прерывания не нарушает выполнение ни одного обработчика событий и не меняет порядок ожидающих событий в очереди. События on_io_int и on_io_int_line добавляются в конец очереди и не обрабатываются, пока не будут обработаны все более ранние события. Поэтому на самом деле ничего не прерывается. Заметьте, что скорость реакции на прерывание здесь тоже не гарантируется: время между обнаружением изменения состояния линии и выполнением обработчиков событий on_io_int и on_io_int_line зависит от числа ожидающих в очереди событий и потому не может быть точно определено заранее.
Итог: «прерывания» объекта io. следует рассматривать как более удобную альтернативу программному опросу линий ввода-вывода.
Имена линий прерываний, например PL_INT_NUM_0, определяет перечисление pl_int_num.