Есть ли что-то неправильное в том, чтобы передать это в качестве аргумента для регистрации ISR?

Я пишу прошивку для esp32 на C++, и мне показалось замечательным передать ссылку на объект в качестве параметра при регистрации ISR, потому что я могу просто делегировать работу из ISR конкретному объекту (ресурсу в данном случае), управление свойствами и функциональностью ресурса непосредственно из класса. Однако я не совсем уверен, на что обращать внимание при использовании этой техники.

  1. Есть ли в этом что-то изначально неправильное?
  2. Если нет, то о чем нужно помнить, делая это?

person Skusku    schedule 22.01.2021    source источник
comment
Как вы вызываете ISR с аргументами?   -  person Colin    schedule 22.01.2021
comment
В основном это то же самое, что и программирование в многопоточной среде, за исключением того, что вы не можете выполнять блокировку. Так что, возможно, вам нужно что-то вроде internalpointers.com/post/. ?   -  person dratenik    schedule 22.01.2021
comment
С помощью esp-idf мы регистрируем ISR, а также передаем void* при регистрации, который будет использоваться в качестве параметра в ISR.   -  person Skusku    schedule 22.01.2021
comment
@Colin Я обновил вопрос, чтобы он был более реалистичным, и в соответствии с вашим комментарием.   -  person Skusku    schedule 22.01.2021
comment
Небольшие накладные расходы, вызванные дополнительной косвенностью, обычно не представляют проблемы и стоят того, чтобы добиться лучшей инкапсуляции/модуляризации. Аргумент ISR, очевидно, является удобной функцией, предоставляемой кодом оболочки ESP-IDF ISR, поскольку он изначально не поддерживается вашим MCU. Но это не имеет большого значения.   -  person HS2    schedule 22.01.2021
comment
Чтобы уточнить мой комментарий выше: поскольку прерывание может произойти в любое время, весь код должен быть подготовлен к тому, что вещи, обновленные isr, могут измениться в любое время в середине любого фрагмента кода. И вы не можете сделать блокировку, перевести isr ​​в спящий режим и ждать, пока прерванный код отпустит блокировку, чтобы вы могли выполнить обновление. Так что ваши обновления лучше быть атомарными. Есть способы сделать это, но они довольно болезненны, и вам, вероятно, следует свести к минимуму количество переменных, которые вы собираетесь обновлять таким образом.   -  person dratenik    schedule 22.01.2021
comment
@dratenik как это относится к изменению состояния объектов, в частности, по сравнению с изменением любого состояния внутри ISR?   -  person Skusku    schedule 22.01.2021
comment
what should one be aware of when doing it? Слишком широкий вопрос. Ты должен быть в курсе всего...   -  person KamilCuk    schedule 22.01.2021
comment
Объекты не добавляют ничего особенного по сравнению с обновлением любой другой части данных.   -  person dratenik    schedule 22.01.2021
comment
Итак, вы вызываете какую-то библиотеку драйверов прерываний, которая находится между вашим кодом и «голым железом»?   -  person Lundin    schedule 22.01.2021
comment
@Lundin да, esp-idf, если быть точным   -  person Skusku    schedule 22.01.2021


Ответы (2)


Есть ли что-то неправильное в передаче «это» в качестве аргумента для регистрации ISR?

No.

Есть ли в этом что-то изначально неправильное?

No.

Если нет, то о чем нужно помнить, делая это?

Срок службы объекта. Оптимизация компилятора. Совместное использование ресурсов. Блокировка. Атомарный доступ. Специфическая аппаратная семантика. Кроме того, esp32 — это двухъядерная платформа. Список можно продолжить, и есть много книг о программировании на esp32, о программировании в параллельных средах и о совместном использовании ресурсов между основной частью кода и подпрограммами обработки прерываний. Следует знать обо всех таких темах, связанных с программированием, а также о хороших соглашениях о коде, именовании и языке C++.

person KamilCuk    schedule 22.01.2021
comment
Правильно ли я думаю, что с оптимизацией компилятора вы намекаете на правильное использование volatile? - person Skusku; 22.01.2021
comment
Ну и что volatile он буквально отключает оптимизацию компилятора. Но есть также переупорядочивание инструкций, std::atomic и std::memory_order, а также барьеры на случай, если вы хотите использовать оптимизацию компилятора вместо использования volatile. - person KamilCuk; 22.01.2021
comment
любую книгу вы бы порекомендовали на эту тему? - person Skusku; 22.01.2021

Я могу просто делегировать работу из ISR конкретному объекту (в данном случае ресурсу), управляя свойствами и функциями ресурса непосредственно из класса.

Это уже неправильно. Если вы пишете драйвер в виде класса для определенного аппаратного периферийного устройства, то ISR должен быть внутри этого класса как статическая функция-член. Или, по крайней мере, находиться в той же единице перевода, что и функция static, но это противоречит цели использования класса с самого начала.

Если вы разрабатываете программу таким образом, то, конечно, вы можете передать ссылку на этот класс.

Есть ли в этом что-то изначально неправильное?

Помимо вышесказанного, тогда да, это должен быть одноэлементный объект со статической продолжительностью хранения. А использование объектов статической длительности хранения классов C++ по своей сути неправильно во встраиваемых системах, потому что они будут вызываться CRT во время запуска микроконтроллера. Что, в свою очередь, заставляет все такие программы C++ запускаться медленнее, чем эквивалент C.

Но и в этом конкретном случае, если прерывание необходимо запустить своевременно с момента сброса при включении питания, тогда инициализация объекта C++ не обеспечит необходимой производительности в реальном времени. Это делает классы C++ непригодными для таких прерываний, как сторожевые таймеры, предупреждения о низком напряжении, монитор часов, исключения ЦП и другие важные аппаратные прерывания.

Если нет, то о чем нужно помнить, делая это?

Обычные проблемы с повторным входом, возникающие при обмене данными между ISR и вызывающей программой. Этот механизм повторного входа может быть инкапсулирован в классе.

И, как обычно, переменные, участвующие в этом, могут нуждаться в квалификации volatile, чтобы предотвратить неправильную оптимизацию компилятора, в зависимости от того, насколько тупой ваш компилятор. Это не имеет ничего общего с повторным входом. См. раздел Использование volatile при разработке встроенного C.

person Lundin    schedule 22.01.2021
comment
Спасибо за подробный ответ. Возможно я немного не понял, ISR статичен в единице трансляции, где лежит и сам класс. Вместо этого я поставлю его статическим в самом классе. (1) Однако я не понимаю, как сделать ISR статическим, не являющимся членом, может нарушить цель класса, поскольку, например, у нас все еще может быть RAII. (2) Зачем нам нужна статическая продолжительность хранения? Могу ли я передать указатель на объект в стеке, если я уверен, что ISR не зарегистрирован, когда объект умирает? - person Skusku; 22.01.2021
comment
@Skusku 1) Поскольку единственная цель использования класса в этом случае - это частная инкапсуляция и хранение переменных, совместно используемых с ISR, как частных. Если вы не можете этого сделать, то C++ только добавляет бесполезное раздувание, и вы должны были закодировать эту часть на C. 2) Потому что в 99% всех приложений нет смысла добавлять и удалять ISR на лету. И потому что это должна быть одноэлементная реализация. - person Lundin; 22.01.2021
comment
Также RAII ничего не добавляет в контексте низкоуровневой связи ISR. - person Lundin; 22.01.2021
comment
Я беру точку 99%, но я не думаю, что это всегда должен быть синглтон. Возьмем что-то вроде программного SPI, использующего таймеры. cstr может устанавливать таймер и регистрировать прерывания таймера, dstr может их удалять и отменять регистрацию (RAII). Если я передам таймер и gpios, используемые в cstr, у меня может быть несколько программных SPI, использующих разные таймеры и gpios. - person Skusku; 22.01.2021
comment
@Skusku Вам нужно столько таймеров, сколько необходимо для наихудшего сценария. Ни больше ни меньше. Если у вас не так много таймеров одновременно, ваша программа не будет работать. И по той же причине для встроенной системы редко имеет смысл отменять регистрацию таймеров или освобождать ресурсы. - person Lundin; 22.01.2021