Перейти к содержанию
    

прерывания в C++

В разделе по scmRTOS, в процессе диспута про OS, я встретил пример кода на C++, в котором был представлен некий класс, описывающий работу UART. И в этом классе один из методов якобы был обработчиком прерывания! Как сделать обработчик прерывания отдельной функцией- мне понятно. Но как сделать метод класса таким обработчиком- совершенно неясно в практическом плане. Я работаю с кристаллами STM32 Cortex, пишу на C++, поэтому очень интересует данный вопрос. Если кто умеет назначать метод класса обработчиком прерываний- буду крайне признателен за наводку.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В разделе по scmRTOS, в процессе диспута про OS, я встретил пример кода на C++, в котором был представлен некий класс, описывающий работу UART. И в этом классе один из методов якобы был обработчиком прерывания! Как сделать обработчик прерывания отдельной функцией- мне понятно. Но как сделать метод класса таким обработчиком- совершенно неясно в практическом плане. Я работаю с кристаллами STM32 Cortex, пишу на C++, поэтому очень интересует данный вопрос. Если кто умеет назначать метод класса обработчиком прерываний- буду крайне признателен за наводку.

 

Обсуждалось например тут:ссылка

 

 

Обсуждалось например тут:ссылка

 

Вот ещё пример

class Tuart_class {
public:
    #pragma vector=TCE0_OVF_vect
    __interrupt static void UsartHandler()
    {
        unsigned char i=USART_GetChar(&USARTC0);
    }
    
};

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И в этом классе один из методов якобы был обработчиком прерывания!

...

Если кто умеет назначать метод класса обработчиком прерываний- буду крайне признателен за наводку.

Вся Дерибасовская умеет.

В той же теме давались линки на конкретные примеры в разных темах на этом же форуме.

 

Могу только повторить, что у некоторых компиляторов нет соответствующей директивы (для avr-gcc что-то было с атрибутами подмены имени, но мне не понравилось) и вызов обработчика придётся делать через промежуточную friend-функцию. Но с inline-подстановкой обработчика работать будет не хуже, зато можно вызвать нестатический метод конкретного объекта.

 

Зависит от компилятора, читайте документацию на свой компилятор, не требуйте от других указать Вам страницу и абзац.

 

Вот ещё пример
Да в той теме, в которой он «развёл дискуссию», давалась куча линков на подобные примеры в разных темах. Просто он читать темы по линкам и разбираться не захотел, спорить интереснее.

 

p.s. Просьба к модераторам переместить тему во «В помощь начинающему». Если после всех примеров вопрос по прежнему поставлен, ему самое место там.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обсуждалось например тут:ссылка

Спасибо за ответ. Но ваша ссылка касается обсуждения исключительно в рамках scmRTOS, авторы которой наделали кучу заголовочных файлов с удобными им макросами. Я же работаю в стандарте C++ IAR v6.0 c библиотекой CMSIS специально для STM32. В этой библиотеке уже заготовлены все возмжные для каждого кристалла обработчики прерываний с заданными именами, начально это пустышки. Юзеру остается только наполнить эти пустые ISR своим конкретным кодом и обьявить этот обработчик дружественным в нужных классах. Других путей я не вижу.

 

Вот ещё пример

class Tuart_class {
public:
    #pragma vector=TCE0_OVF_vect
    __interrupt static void UsartHandler()
    {
        unsigned char i=USART_GetChar(&USARTC0);
    }
    
};

 

В хелпе IAR v6.0 для ARM и Cortex я не нашел управляющего слова __interrupt. А у директивы pragma не нашел параметра vector. Что я делаю не так?

 

 

 

Но с inline-подстановкой обработчика работать будет не хуже, зато можно вызвать нестатический метод конкретного объекта.

По-моему inline-подстановка в данном случае используется не по назначению. Не для этого она придумана. Да и вообще, задача сделать метод класса обработчиком прерывания имеет чисто академический интерес из той же серии- использовать обьектное программирование не по назначению.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я даже не знаю что и говорить... Вроде и вопросы не для совсем начинающих, но кроме как для ветки "Анекдоты" она не годится.

2 Aprox - ну вам же уже несколько раз сказали - читайте документацию, как на язык программирования так и на платформу программирования, раз слушать умные советы профессионалов вы не хотите.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за ответ. Но ваша ссылка касается обсуждения исключительно в рамках scmRTOS, авторы которой наделали кучу заголовочных файлов с удобными им макросами.

Не думаю что дело в заголовочных файлах scmrtos.

 

В хелпе IAR v6.0 для ARM и Cortex я не нашел управляющего слова __interrupt. А у директивы pragma не нашел параметра vector. Что я делаю не так?

 

Да, пример был для IAR ARV. Но вряд ли в IAR ARM нет такой возможности.

 

Я же работаю в стандарте C++ IAR v6.0 c библиотекой CMSIS специально для STM32. В этой библиотеке уже заготовлены все возмжные для каждого кристалла обработчики прерываний с заданными именами, начально это пустышки. Юзеру остается только наполнить эти пустые ISR своим конкретным кодом и обьявить этот обработчик дружественным в нужных классах. Других путей я не вижу.

 

Вот что пишут в доке по IAR ARM:

 

C++ AND SPECIAL FUNCTION TYPES

C++ member functions can be declared using special function types, with the restriction

that interrupt member functions must be static. When a non-static member function is

called, it must be applied to an object. When an interrupt occurs and the interrupt

function is called, there is no object available to apply the member function to.

Special function types can be used for static member functions. For example, in the

following example, the function handler is declared as an interrupt function:

class Device

{

static __irq void handler();

};

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, пример был для IAR ARV. Но вряд ли в IAR ARM нет такой возможности.

Увы, по причине того, что контроллер прерываний в Cortex автоматически сохраняет контекст при срабатывании прерывания, становится уже ненужным управляющее слово __irq, обычно указывающее компилятору сохранять контекст программным способом.

Вот, что пишут в той же доке IAR ARM, на которую вы же и ссылались:

Note: ARM Cortex-M has a different interrupt mechanism than other ARM devices,

and for these devices a different set of primitives is available.....

.....

On ARM Cortex-M, an interrupt service routine enters and returns in the same way as a

normal function, which means no special keywords are required. Thus, the keywords

__irq, __fiq, and __nested are not available when you compile for ARM Cortex-M.

These exception function names are defined in cstartup_M.c and cstartup_M.s.

 

Иными словами, время старых, привычных решений уходит.

 

2 Aprox - ну вам же уже несколько раз сказали - читайте документацию, как на язык программирования так и на платформу программирования, раз слушать умные советы профессионалов вы не хотите.

"Врачу - исцелися сам."

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По-моему inline-подстановка в данном случае используется не по назначению. Не для этого она придумана.
Её можно и не использовать. Тут она предлагается исключительно в целях повышения эффективности построенного кода, для чего она и придумана.

 

Да и вообще, задача сделать метод класса обработчиком прерывания имеет чисто академический интерес из той же серии- использовать обьектное программирование не по назначению.
Ну это с Вашей, современной точки зрения.

Со старой, привычной точки зрения

In OOP, each object is capable of receiving messages, processing data, and sending messages to other objects

The tasks we are allowed to ask an object to perform (or equivalently, the messages it understands) are that object's methods.

Вызов метода — это способ послать сообщение объекту. Прерывания — это сообщения от аппаратуры.

Так что всё в рамках использования по назначению.

 

Иными словами, время старых, привычных решений уходит.
Уже слышали.

В подпись поставьте, чтобы не писать каждый раз.

Только новую тему с обсуждением устаревшести движка данного форума и возможностях подписей в современных движках не открывайте.

 

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

Если очень лень, можно ограничиться этим:

Наверное вы не поняли, что задачей в моем случае является ISR, которая оформлена в виде защищенного метода в классе с защищенными данными.
Т.е. в сообщении 103 автор использует ISR - приватные методы и именно это он противопоставляет scmRTOS на протяжении нескольких страниц той темы. Но когда ему показали, как это делается в scmRTOS, он в сообщении 143 уже пишет:

Кстати, у вас метод uart_t::irq_handler() представлен как член класса uart_t. Позвольте каверзный вопрос, как это удается в С++ оформить метод класса в виде ISR? Да еще и зарегестрировать соответствующий вектор в контроллере прерываний?
И десятком сообщений позже по поводу своего знания C++ и инструментария:

Естественно, нестатический метод обработчиком не поставить.
Отчего же? Что нам мешает динамически изменять вектора в контроллере прерываний? Дело же в другом- ISR должна быть оформлена по другому, не как обычные процедуры и функции.

Естественно, статический можно либо вызвать из обработчика либо назначить обработчиком — в зависимости от возможностей компилятора.

С++ знаете так же хорошо, как и историю развития микроконтроллеров?

Вполне достаточно, чтобы понять- методы в классах нельзя назначать как ISR. В принципе нельзя, независимо от возможностей компилятора. На эту ошибку я и указал Antoxa. Что же касается вызвать метод класса из настоящей ISR, то последняя должна размещаться в программном модуле, тоже написанном на С++. И вот, я действительно не знаю- есть ли в компиляторе С++, например IAR, такие служебные слова, которые превращают обычную функцию в ISR? Если знаете- буду очень признателен услышать.
И это несмотря на наличие примеров и ссылок на примеры до этого.

И несмотря на то, что начинал он разговор с того, что «в его случае» ISR является методом класса.

 

После чего решайте, стоит ли дублировать тут ответы, которые уже давались.

 

Кстати, обратите внимание на реакцию на слова «нестатический метод класса». В привате с предложением «продолжить дискуссию» он тоже спрашивал меня — что я имею ввиду под «статическим и динамическим» методами класса (это я к тому, что с таким уровнем постановки вопроса тема точно для раздела «В помощь начинающему»)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ReAll

Прошу обратить внимание на мой пост 2: Artem, где я ссылкой на официальный документ компилятора IAR для Cortex-M показал, что ваши приемы программирования прерываний нынче не работают. В разделе scmRTOS я много раз давал ссылку на кристаллы с ядром Cortex-M, тем самым образуя контекст разговора. Но почему-то оппоненты предпочли сердиться и нервничать вместо того, чтобы прочитать внимательно документацию на компилятор С++ IAR для Cortex-M. Вот и сейчас, с "профессионалами" происходит то же самое. Ну, прочтите же наконец о прерываниях документацию на компилятор C/C++ для Cortex-M!

 

Ну это с Вашей, современной точки зрения.

Со старой, привычной точки зрения

In OOP, each object is capable of receiving messages, processing data, and sending messages to other objects

The tasks we are allowed to ask an object to perform (or equivalently, the messages it understands) are that object's methods.

Вызов метода — это способ послать сообщение объекту. Прерывания — это сообщения от аппаратуры.

Так что всё в рамках использования по назначению.

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

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...