Драйвер SWI предоставляет функции для управления программными прерываниями (software interrupts, SWI). Это дает возможность пользователям выделять SWI и передавать дополнительные флаги в функции его обработчика прерывания (ISR).
Программные прерывания выделяются из доступного пула SWI. По умолчанию доступно 6 прерываний, от SWI0 до SWI5. Обратите внимание, что это количество уменьшается, если в программе используется либо SoftDevice, либо протокол Gazell, либо протокол ESB. Для дополнительной информации по использованию ресурсов для библиотеки определенного протокола см. соответствующую документацию.
Драйвер SWI необходимо инициализировать вызовом функции nrf_drv_swi_init. Если инициализация прошла успешно, то функция вернет NRF_SUCCESS.
Чтобы выделить прерывание, вызовите функцию nrf_drv_swi_alloc function. На входе она получает указатель на переменную nrf_swi_t (дескриптор на выделяемое SWI), функцию обработчика события (event handler), и значение, которое показывает приоритет прерывания. Если выделение прошло успешно, то функция возвратит NRF_SUCCESS, и будет заполнена переменная, на которую ссылается указатель на nrf_swi_t.
Обработчик события и флаги. Когда выделяется драйвер, программист должен предоставить callback-функцию (см. описание типа nrf_swi_handler_t, второй параметр функции nrf_drv_swi_alloc). Аргументы у этой callback-функции - SWI и некоторые флаги пользователя. Флаги пользователя представлены как битовая маска.
Чтобы вызвать срабатывание SWI, вызовите функцию nrf_drv_swi_trigger с заданными флагами. Когда сработало SWI, будет вызвана соответствующая callback-функция с указанными флагами (представленными как битовая маска). Флаги можно использовать, например, для отслеживания источника прерывания, или они могут быть игнорированы, если не нужны. Обратите внимание, что callback-функция может быть вызвана с несколькими установленными флагами, если SWI сработало несколько раз с разными флагами из обработчика прерывания с приоритетом такого же уровня или более высокого.
Специальные опции. Чтобы запретить выделение определенных SWI из свободного пула, добавьте соответствующее глобальное макроопределение (#define) препроцессора (от SWI_DISABLE0 до SWI_DISABLE5). Любое запрещенное SWI не будет выделяться, и таким образом не будет доступно для пользователя.
Примечание: во многих примерах из SDK (например SDK v12.3.0), использующих SoftDevice и стек BLE, задается макроопределение SWI_DISABLE0 для того, чтобы оно было зарезервировано для использования в SoftDevice (вызов nrf_drv_swi_alloc не будет выделять SWI0).
В следующем примере демонстрируется использование SWI. Имейте в виду, что этот пример не оптимизирован по энергопотреблению.
static nrf_swi_t my_swi;
void swi_event_handler(nrf_swi_t swi, nrf_swi_flags_t flags)
{
// Если сработал обработчик "my_swi", и присутствует флаг #3:
if ((swi == my_swi) && (flags & (1 << 3)))
{
/* Тут выполняются какие-нибудь действия. */
}
return;
}
...
ret_code_t err_code;
nrf_swi_t my_swi;
// Инициализация библиотеки SWI:
err_code = nrf_drv_swi_init();
APP_ERROR_CHECK(err_code);
// Выделение и настройка одного SWI:
err_code = nrf_drv_swi_alloc(&my_swi, swi_event_handler, APP_IRQ_PRIORITY_LOW);
APP_ERROR_CHECK(err_code);
while (true)
{
// Вызовет срабатывание SWI с флагом #3:
nrf_drv_swi_trigger(my_swi, 3);
// Задержка в 1 секунду:
nrf_delay_ms(1000);
}
[Использование совместно с SoftDevice]
Библиотека SWI может использоваться вместе с SoftDevice. Однако в этом случае будет ограничено количество прерываний, доступных для пользователя. Для дополнительной информации по использованию ресурсов см. документацию на соответствующий SoftDevice.
Будьте осторожны, когда используете для SWI приоритет APP_IRQ_PRIORITY_HIGH. ISR для SWI, который работает слишком долго, может нарушить корректное функционирование SoftDevice.
[Ссылки]
1. nRF5 SDK v12 Hardware Driwers SWI site:nordicsemi.com. |