Обработчик прерываний ARM Cortex-M на C++

Можно ли написать обработчик прерываний на C++ для чипов ARM Cortex, таких как ST и NXP.

В настоящее время я разрабатываю много кода на C++ для чипов ARM cortex. Мне немного надоело вызывать объект static/global/singleton C++ из функции обратного вызова C. Есть ли способ не использовать функцию C.

Есть ли способ напрямую вызывать объектные функции С++ при возникновении прерывания?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 225
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

Он по-прежнему должен использовать связь языка C с соглашением о вызовах обработчиков прерываний. Это означает отсутствие функций-членов. (Формально статические функции-члены также недопустимы, хотя на практике они обычно работают. Нестатические функции-члены использовать нельзя.)

В C++ сначала включите связь языка C с помощью extern "C". Также используйте любое ключевое слово компилятора для обработчиков прерываний, которое вы использовали бы в C, например __interrupt.

Внутри функции вы можете использовать всю мощь C++ — объекты, циклы for-in, интеллектуальные указатели, экземпляры шаблонов и т. д. Хотя вы все равно хотите быть осторожным с тем, сколько работы вы делаете в контексте прерывания, а C++ имеет тенденцию скрывать сложность, поэтому вы больше не чувствуете, сколько машинных инструкций генерируется.


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

Другие семейства процессоров используют фиксированный адрес только для вектора сброса и устанавливают другие обработчики прерываний, записывая адрес каждого обработчика в регистр специальной функции, соответствующий его прерыванию. Для них имеет значение только соглашение о вызовах, а не имя/связь функции. ARM Cortex-M позволяет вам написать регистр специальной функции для поиска всей таблицы векторов по альтернативному адресу, но не для перемещения отдельных обработчиков.

Могу ли я обобщить ваш ответ: нет, это невозможно из-за требования использовать соглашение о вызовах C? Если это так, возникает другой вопрос, почему мы связаны этой конвенцией?

Bart 29.05.2019 15:51

@Bart: Трудно подвести итог, потому что у вас было несколько вопросов. Ваш первый "Можно ли написать обработчик прерываний на C++ для чипов ARM Cortex?" ответ да. Для "Есть ли способ не пересылать через функцию C?" также Да. Для «Есть ли способ напрямую вызвать объектную функцию C++ при возникновении прерывания?» Нет. Есть несколько вещей, которые могут означать «объектная функция C++», и ни одна из них не может использоваться в качестве обработчиков прерываний.

Ben Voigt 29.05.2019 15:54

@Bart: А что касается того, почему вы связаны этим соглашением, это потому, что оно встроено в аппаратное обеспечение. Процессор ничего не знает о this указателях или чем-то подобном. Фактически, обработчики прерываний могут даже не использовать соглашение о вызовах C, используемое для других функций, вы можете получить специальное соглашение о вызовах, используя ключевое слово (например, __interrupt, поэтому в C++ вы получите extern "C" __interrupt void whatever(void)). (Написание ключевого слова зависит от вашего компилятора) Компилятор позаботится об этой детали. Чего он не может сделать, так это создать указатель this из воздуха.

Ben Voigt 29.05.2019 15:57

Благодарим Вас за разъяснения. Я понимаю, что ты имеешь в виду. Используя одноэлементный или глобальный объект, я неявно прекратил использовать это, поэтому работаю над этой проблемой.

Bart 29.05.2019 15:59

@old_timer: Можете ли вы проверить, достаточно ли точно мое редактирование, чтобы избежать путаницы?

Ben Voigt 29.05.2019 16:38

Компиляторы C могут выбрать свое собственное соглашение, нет никаких правил, которые могли бы их остановить. они могут использовать обычный или рекомендуемый вариант или пойти своим путем. Чтобы cortex-m мог иметь адрес метки функции c в векторной таблице и заставить его работать, компилятор должен соответствовать соглашению, «запеченному» в логике. иначе C тоже не будет работать. Затем вы можете использовать традиционный подход к обертыванию вашей функции C либо специфическими функциями компилятора, либо самостоятельно в сборке.

old_timer 29.05.2019 16:47

@old_timer: Да, безусловно, вы можете написать обработчик прерываний (или переадресацию) на ассемблере, если хотите, дав ему ожидаемое имя. Вы можете выбрать свои собственные имена символов для функций-обработчиков, если вы пишете свой собственный (или модифицируете) код поддержки платформы. Но большинство людей будут использовать функцию запуска, предоставляемую компилятором, чтобы они правильно инициализировали глобальные переменные и т. д. до вызова main(). И в этом общем случае обработчики прерываний должны использовать имена, назначенные библиотекой поддержки платформы, которые имеют связь с C.

Ben Voigt 29.05.2019 18:21

и большинство людей используют gnu или kiel или что-то другое, использующее совместимое соглашение о вызовах.

old_timer 29.05.2019 19:54

вектор сброса является особым случаем даже для C, но определенно для C++ другие векторы - это те, для которых вы хотите использовать эту функцию cortex-m.

old_timer 29.05.2019 19:54

Я думаю, что здесь упоминается что-то важное: это зависит от компилятора. Тем временем я нашел эту ссылку на сайт ИАР. Это пример таблицы преобразователя прерываний в C++. Я посмотрел на это, но должен понять это еще.

Bart 30.05.2019 08:56

Is away to directly call a C++ object function when a interrupt occurs?

Короче нет. Даже если вы объявите свой нестатический метод как void (void), у него все равно будет неявный аргумент — this. С другой стороны, обработчик прерываний вообще не имеет аргументов.

Спасибо за ваш ответ, я понимаю, что вы имеете в виду. Только статическая функция этого класса будет допустимым кандидатом.

Bart 29.05.2019 16:12

Другие вопросы по теме