Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Создание обработчика прерываний

Цель этого упражнения — обработать прерывание, которое срабатывает при нажатии кнопки BOOT.

Заготовку кода для этого упражнения можно найти в advanced/button-interrupt/src/main.rs.

Решение упражнения находится в advanced/button-interrupt/examples/solution.rs. Запустить его можно командой:

cargo run --example solution

✅ Задания

  1. Настройте кнопку BOOT (GPIO9) с помощью структуры PinDriver со следующими параметрами:
    • режим входа (Input mode);
    • подтяжка к питанию (Pull up);
    • прерывание по положительному фронту (Interrupt on positive edge).
  2. Создайте новое уведомление (notification) и notifier:
    • см. документацию hal::task::notification.
  3. В блоке unsafe создайте подписку и её функцию обратного вызова.
    • см. PinDriver::subscribe и task::notify_and_yield;
    • причины, по которым это unsafe:
      • функция обратного вызова выполняется в ISR (Interrupt Service Routine), поэтому не следует вызывать в ней блокирующие функции; это относится к STD, libc и API FreeRTOS (за исключением нескольких разрешённых);
      • замыкание обратного вызова захватывает своё окружение, и в него можно передать статические переменные. Захваченные переменные должны переживать подписку. Можно также использовать нестатические переменные, но для этого нужна дополнительная осторожность; подробнее см. документацию esp_idf_hal::gpio::PinDriver::subscribe_nonstatic.
  4. В цикле включите прерывание и дождитесь уведомления:
    • прерывание нужно включать после каждого полученного уведомления, из контекста не-ISR;
    • для ожидания можно использовать esp_idf_svc::hal::delay::BLOCK.
  5. Запустите программу, нажмите кнопку BOOT и посмотрите, как это работает!

🔎 В этом упражнении мы используем уведомления, которые передают только последнее значение. Если прерывание сработало несколько раз до того, как прочитано значение уведомления, вы сможете прочитать только последнее. Очереди, напротив, позволяют получить несколько значений. Подробнее см. esp_idf_hal::task::queue::Queue.