Страница 1 из 2
Контекст вызова обработчика, зарегистрированного attachInter
Добавлено: Вт дек 16, 2025 16:12:22
jcxz
Прошу помощи знатоков внутренней кухни работы ардуино. Нужно понять как работает некоторый код, написанный под ардуино. Сам я не знаком с её внутренней кухней.
Как я понимаю: Пользовательский код в ардуино должен быть описан внутри loop(), которая платформой вызывается итеративно, в супер-цикле.
А пользовательский обработчик прерывания handleInterrupt(), регистрируемый вызовом attachInterrupt(..., handleInterrupt, ...) - он в каком контексте будет вызван?
В отдельном контексте аппаратного ISR (как обычное прерывание на микроконтроллере)?
Или он будет вызван в контексте супер-цикла, в котором итеративно выполняется loop()?
Погуглив, нашёл следующую инфу, что среда исполнения Ардуино реализована в виде си-шного:
Код: Выделить всё
int main(void)
{
init();
initVariant();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
Получается - serialEventRun() вызывается из контекста главного цикла.
handleInterrupt() зарегистрированная attachInterrupt() будет также вызвана (последовательно рядом с serialEventRun())?
Или она будет вызвана непосредственно из контекста аппаратного ISR?
Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Вт дек 16, 2025 18:24:27
maxlab
[uquote="jcxz",url="/forum/viewtopic.php?p=4772740#p4772740"]Или она будет вызвана непосредственно из контекста аппаратного ISR?[/uquote]
attachInterrupt - это чисто железячное прерывание. Поэтому в некоторых туториалах рекомендуют минимум кода в присоединенном обработчике прерывания. Например взведение каких либо флагов и немедленный выход. А флаги уже обрабатываются в супер цикле loop()
Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Вт дек 16, 2025 19:00:48
jcxz
[uquote="maxlab",url="/forum/viewtopic.php?p=4772766#p4772766"]attachInterrupt - это чисто железячное прерывание. Поэтому в некоторых туториалах рекомендуют минимум кода в присоединенном обработчике прерывания. Например взведение каких либо флагов и немедленный выход. А флаги уже обрабатываются в супер цикле loop()[/uquote]Это точно???
Почему сомнения: Тот код, в котором разбираюсь, внутри handleInterrupt() содержит кучу кода. В handleInterrupt() есть не только функции типа delayMicroseconds(...), но и даже записи/чтения массивов байт в SPI. Т.е. - блокирующий доступ к разделяемым ресурсам. В главном цикле (loop()) есть такой доступ к этим ресурсам и в handleInterrupt() - тоже.
Получается одно из двух:
1) или этот handleInterrupt() не может вызываться из ISR, а вызывается из контекста главного цикла;
2) или это говнокод.

Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Вт дек 16, 2025 19:25:27
veso74
Компиляторы и IDE не помешают вам писать плохой код. Но некоторые из них выдадут предупреждения. Даже если просто попытались тестировать.
Ответственность за происходящее несет автор кода, даже если код бесполезен.
ниже: МК PIC

Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Вт дек 16, 2025 20:02:17
linux_rulezz
jcxz, если тебе так хочется на аврке древней писать, то зачем абдурина? Ну и пиши себе на сях. И не будет никаких вопросов к "внутренней кухне", т.к. вся она будет самодельной.
Но таки лучше 32-битные приличные ARM'ы или RISC-V взять, у которых шикарная периферия (хотя, все равно всегда не хватает каналов DMA, количества таймеров или еще чего). Главное - пиши сам код, а не генерируй калокубами всякими!
Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Вт дек 16, 2025 20:09:48
jcxz
[uquote="linux_rulezz",url="/forum/viewtopic.php?p=4772796#p4772796"]jcxz, если тебе так хочется на аврке древней писать, то зачем абдурина? Ну и пиши себе на сях.[/uquote]Для вас персональный совет: Учитесь читать тему, на которую отвечаете!
Ни на какой "аврке" я не пишу. Так же как не пишу на абдурине.
Вопрос был про попытку понять: Как работает некий готовый чужой код написанный на ардуино.
PS: Если вам нечего сказать по теме - прошу не засорять её бесполезным мусором!
Чукчи-нечитатели - проходите пожалуйста мимо!
Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Вт дек 16, 2025 20:15:40
BOB51
Обработчик serial уже встроен "внутри" по умолчанию.
А вот функция attachInterrupt() добавляется по желанию/необходимости.
Можно и чего то своего добавить, но с оглядкой на возможные проблемы при "наложении" ресурсов IDE, добавляемых по умолчанию и собственноручно написанных самоделок.
В принципе... Или пользуйтесь "чистым СИ" или принимайте правила/ограничения референса ардуино.
можно еще и тут посмотреть:
https://alexgyver.ru/lessons/

Особое внимание к "чужим кодам" - чтоб что то "свое" встраивать за рамками предоставленных в IDE правил надо очень детально разбираться как в структуре самой IDE, так и в Си да в придачу и в С++.
Довольно неблагодарная задача с учетом отношения к ардуиноIDE у местных обитателей...

Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Вт дек 16, 2025 20:19:37
linux_rulezz
Ни на какой "аврке" я не пишу. Так же как не пишу на абдурине.
Вопрос был про попытку понять: Как работает некий готовый чужой код написанный на ардуино.
Абдурина === быдлокод. Если он еще и чужой, то единственный правильный вариант - выбросить его в мусорку! Да и самому в этой говно-среде писать ни в коем случае не стоит. Как и во всяких калокубах и им подобных говногенераторах.
Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Вт дек 16, 2025 20:21:19
BOB51
Не следует так заявлять - все зависит от автора и знания особенностей конкретного средства разработки.

Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Вт дек 16, 2025 20:44:03
linux_rulezz
BOB51, не отрицаю, среди абдуринщиков может затесаться 0.01% грамотных. Но это - скорей исключение, чем правило. Обычно этой "средой" пользуются лишь совсем уж безграмотные. И почерпнуть из их кода что-либо полезное не получится.
Кстати, было как-то дело: перенесли эту гадость под STM32 и некоторые другие 32-битные МК. Доходило до абсурда: на МК есть аппаратный USB, а пользуются софтовым. Или, как они любят: МК не умеет делений даже, а в него флоаты пихают. Ну и самый цимус: I2C ногодрыгом. Или ШИМ. Или неиспользование DMA там, где он очень даже не помешал бы.
Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Вт дек 16, 2025 20:52:50
BOB51
За АРМы ничего сказать не могу поскольку таковыми не пользуюсь.
Относительно АВР под ардуино - то более известная тематика, имеющая прикладное применение и относительно хорошо проработаны по различным источникам информации.

Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Вт дек 16, 2025 20:56:00
veso74
jcxz, предоставьте весь код. Потому что то, что вы показали, не является Arduino - там нет ни USBDevice, ни for (;;), ни пустой loop(); и setup(); Ето просто код на C/C++, скомпилированный компилятором Arduino (GCC).
Плата Arduino Due?
Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Вт дек 16, 2025 21:03:37
jcxz
[uquote="veso74",url="/forum/viewtopic.php?p=4772815#p4772815"]
jcxz, предоставьте весь код. Потому что то, что вы показали, не является Arduino[/uquote]Опять нечитатель...
Я ничего не "предоставлял". Я спрашивал об общей структуре процесса выполнения кода. И привёл нагугленный вариант описания такой структуры.
Схематичный вариант. Просто иллюстрирующий схему выполнения кода в ардуино.
Если хочется кода, то вот он:
https://github.com/thotro/arduino-dw1000
Это код, о котором я писал. Но сильно сомневаюсь что кто-то захочет в нём разбираться...
Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Вт дек 16, 2025 21:16:53
veso74
Все написано в описание функции attachInterrupt() -> pin делает INTERRUPT, а функция привязывает его аппаратно к пользовательской функции:
https://github.com/arduino/reference-en ... pt-numbers
В Aruino UNO их два.
Пользовательская функция - отдельная функция. Не входит в loop. A rезультаты можно получить, напр. с помощью флагов.
Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Вт дек 16, 2025 21:57:52
BOB51
[uquote="jcxz",url="/forum/viewtopic.php?p=4772819#p4772819"][uquote="veso74",url="/forum/viewtopic.php?p=4772815#p4772815"]
jcxz, предоставьте весь код. Потому что то, что вы показали, не является Arduino[/uquote]Опять нечитатель...
Я ничего не "предоставлял". Я спрашивал об общей структуре процесса выполнения кода. И привёл нагугленный вариант описания такой структуры.
Схематичный вариант. Просто иллюстрирующий схему выполнения кода в ардуино.
Если хочется кода, то вот он:
https://github.com/thotro/arduino-dw1000
Это код, о котором я писал. Но сильно сомневаюсь что кто-то захочет в нём разбираться...[/uquote]
УПС...
А что это за платформа такая:
"Библиотека, предоставляющая базовые функции для использования
чипов/модулей DW1000 от Decawave с Arduino"??
Спойлер
Decawave
теперь является частью Qorvo
Узнайте больше о технологии сверхширокополосной связи, продуктах и многом другом
на сайте Qorvo:
Сверхширокополосный концентратор:
Технологии
Рынки и сферы применения
Продукты:
Решения UWB, совместимые с чипом Apple U1
Оценочные комплекты UWB
Модули UWB
Микросхемы UWB
Ресурсы:
Часто задаваемые вопросы
Инструкции по применению
Официальные документы
Видео
Партнеры UWB
Форум сообщества
Брошюра о сверхширокополосной связи
Пресс-релиз: Qorvo завершает сделку по приобретению Decawave
Это ведь специализированный модуль со своими специфическими библиотеками.
Его рассматривать то надо имея знания по соответствующим микросхемам/МК, там применяемым...
В среде ардуино достаточно много разнообразных МК с собственными особыми правилами (а бывает и с дополнительными компиляторами).
То уж точно не для начинающих разбор кодов устраивать.

Если простенькое UNO(нано или про-мини) то структура программы к примеру по симулятору (и в рамках GCC):
Спойлер


Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Ср дек 17, 2025 02:09:04
jcxz
[uquote="BOB51",url="/forum/viewtopic.php?p=4772830#p4772830"]А что это за платформа такая:
"Библиотека, предоставляющая базовые функции для использования чипов/модулей DW1000 от Decawave с Arduino"??[/uquote]Это код для работы с DW1000. Для измерения расстояния между двумя приёмо-передатчиками с точностью не хуже 10 см (заявлена производителем) и дальностью до 200-300 м.
[uquote="BOB51",url="/forum/viewtopic.php?p=4772830#p4772830"]Это ведь специализированный модуль со своими специфическими библиотеками.
Его рассматривать то надо имея знания по соответствующим микросхемам/МК, там применяемым...[/uquote]Это готовый проект кода для DW1000. На youtube есть ролики пользователей, которые использовали его и получали примерно заявленную точность. "Знание применяемых микросхем" - это юзер-мануал на более чем сотню регистров. Со сложным и запутанным программированием. Хочется взять этот проект и портировать его на свой МК. А не устраивать "закат солнца вручную" длительностью в несколько месяцев самостоятельных кувырканий с нуля. С негарантированным результатом.
Но после даже поверхностного анализа кода этого проекта, заметил, что функция обработчика прерываний handleInterrupt() в этом проекте обращается ко множеству разделяемых ресурсов (глобальные переменные, SPI-канал и т.п.) параллельно фоновому процессу в loop(). Без каких-либо видимых средств синхронизации/cериализации доступа. Что недопустимо в принципе. Или я не вижу этих средств синхронизации/cериализации. Тогда просьба - указать мне на них.
Т.е. - допустимо такое только если handleInterrupt() будет вызываться платформой ардуино из контекста фонового процесса loop(), а не из контекста аппаратного ISR. Отсюда и возник исходный вопрос.
Судя по роликам на youtube, код должен прекрасно работать.
PS: Ещё раз повторяю для нечитающих исходный вопрос: Я не спрашиваю как правильно делать! Не спрашиваю как работать с прерываниями и в многопоточной среде. И не просил меня поучать на эту тему. Я это сам прекрасно знаю и умею писать код для МК. Может даже получше вас, поучатели.
Мой вопрос только о том: Как в среде ардуино реализовано исполнение пользовательского обработчика handleInterrupt()? Всё! Не более. Не знаете - проходите мимо.
Добавлено after 9 minutes 48 seconds:
[uquote="BOB51",url="/forum/viewtopic.php?p=4772830#p4772830"]Если простенькое UNO(нано или про-мини) то структура программы к примеру по симулятору[/uquote]Судя по коду того проекта, handleInterrupt() должен вызываться подобно serialEventRun() из вашего примера.
Иначе проект будет неработоспособным.
Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Ср дек 17, 2025 09:06:53
OKF
[uquote="jcxz",url="/forum/viewtopic.php?p=4772862#p4772862"]Судя по коду того проекта, handleInterrupt() должен вызываться подобно serialEventRun() из вашего примера.
Иначе проект будет неработоспособным.[/uquote]
Нет. Это обработчик железного прерывания INTx, подключаемого по attachInterrupt.
Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Ср дек 17, 2025 09:31:57
BOB51
Такие библиотеки анализируют по другому.
Прикладные для спецкрсталлов могут быть написаны в рамках и по правилам стандартного GCC да плюс подключение файлов на ассемблере внутри. Не надо путать с теми функциями, что "референсом" предоставляются.
И раскапывать там ничего смысла нет - или используем "как есть" или своё по даташитам пишем (ежли достаточно знаний и навыков).

Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Ср дек 17, 2025 10:09:53
u37
Для всезнайки - ISR всегда выполняется средствами ISR (обработка прерывания) вне зависимости где и как лежит код. Для любого процессора. Иное невозможно.
Выполнение кода может прерываться другими прерываниями, если контроллер прерываний это позволяет. Но выполнение кода ISR не может быть перенесено в фоновый процесс (USER). В некоторых процессорах это вообще два типа пространства - системное и user.
Ваша тема не имеет смысла. Хватит флудить.
Re: Контекст вызова обработчика, зарегистрированного attachI
Добавлено: Ср дек 17, 2025 10:43:19
BOB51
Ну уж так и не может обслуживание прерывания идти фоновым.
К примеру основная программа и псевдо параллельный обработчик на прерываниях по таймеру (клавиатура, динамическая индикация)... Переключение на другую часть программы с последующим возвратом в основную (обработчик аппаратного прерывания выполняет только подстановку в стек адреса возврата и reti).
Это только адрес вектора точки запуска обработчика прерывания жестко аппаратно определен. А что там дальше будет выполняться и где сам обработчик прерывания будет размещён - на усмотрение автора программы...
