andrewlekar 0 Posted May 19, 2014 (edited) · Report post В scmRTOS посмотрите как обработчики сделаны. У меня опыта нет упихивания С++ в контроллер. И что значит "Поля в классах нужно инициализировать руками" В Си вы пишете в module.c: static int data; И эта переменная у вас будет инициализирована нулём. В С++ вы пишете в module.h: class Module { private: int data;}; И эта переменная у вас инициализирована не будет. Edited May 19, 2014 by andrewlekar Share this post Link to post Share on other sites
doom13 0 Posted May 19, 2014 · Report post А как быть с обработчиками прерываний? Вот я хочу сделать класс драйверов, как туда засунуть обработчик? Можно так: typedef void (*isr_func)(void* context); class Driver { public: ... void InitIsr(isr_func isr); ... }; class Device { private: Device() { ... driver->InitIsr(Isr); ... } ... static void Isr(void* context); Driver *driver; ... }; Share this post Link to post Share on other sites
yanvasilij 0 Posted May 19, 2014 · Report post В С++ вы пишете в module.h: class Module { private: int data;}; И эта переменная у вас инициализирована не будет. Ну я так понимаю на то конструкторы и есть. Мне вот только не совсем понятно: можно ли объявлять объект - не создавать его динамически. То есть в приведенном Вами примере создание объекта вот так: class Module { private: int data;}; Module myModule; int main (void) { myModule.data=100500; while(1) ... } Можно так: ... Не совсем понял: Вы передали указатель на функцию обработчик прерывания в метод InitIsr? Share this post Link to post Share on other sites
andrewlekar 0 Posted May 19, 2014 · Report post можно ли объявлять объект - не создавать его динамически. Можно. Только в вашем примере data будет недоступен. Share this post Link to post Share on other sites
doom13 0 Posted May 19, 2014 · Report post Не совсем понял: Вы передали указатель на функцию обработчик прерывания в метод InitIsr? Теперь для каждого объекта можно задать свой обработчик прерывания, Ваши предложения... Моя практика показала, что если обработчик прерывания - член класса, то он должен быть статик, или не работает. Т.о. это выбрано для реализации возможности задать собственный обработчик прерывания для каждого объекта. Share this post Link to post Share on other sites
megajohn 0 Posted May 19, 2014 · Report post ... которая дает возможность использовать полиморфизм (в данном случае: переопределяемое на рантайме поведение). ...многие его средства - это абстракции уровня этапа компиляции. а вот мне тут кажется противоречие. Или нет ? и помнится, для реализации virtual нужно дополнительно место в RAM для каких-то таблиц ( давно где-то читал, но proof не дам - не знаю где читал ) Share this post Link to post Share on other sites
Сергей Борщ 0 Posted May 19, 2014 · Report post Ваши предложения... class driver { public: void isr_handler(); .... }; driver Device1; ISR(XXXX_vect) { Device1.isr_handler(); }; Share this post Link to post Share on other sites
msalov 0 Posted May 19, 2014 · Report post и помнится, для реализации virtual нужно дополнительно место в RAM для каких-то таблиц ( давно где-то читал, но proof не дам - не знаю где читал ) В "тело" каждого экземпляра класса добавляется указатель на таблицу виртуальных функций. Сами таблицы лежат в ПЗУ. Share this post Link to post Share on other sites
Сергей Борщ 0 Posted May 19, 2014 · Report post и помнится, для реализации virtual нужно дополнительно место в RAM для каких-то таблиц ( давно где-то читал, но proof не дам - не знаю где читал )Таблица в количестве одной штуки на каждый класс с виртуальными функциями. Обычно хранится в памяти кода (avr-gcc до сих пор этого не умеет, хранит в ОЗУ). В каждом объекте такого класса один указатель (уже в ОЗУ) на эту таблицу. Таблица состоит из указателей на реализации виртуальных функций, т.е. если класс имеет одну виртуальную функцию, то таблица состоит из одного указателя. Примерно так, "на пальцах". Share this post Link to post Share on other sites
doom13 0 Posted May 19, 2014 · Report post class driver { public: void isr_handler(); .... }; driver Device1; ISR(XXXX_vect) { Device1.isr_handler(); }; В таком исполнении ISR() нельзя сделать членом какого-то класса. Share this post Link to post Share on other sites
Сергей Борщ 0 Posted May 19, 2014 · Report post В таком исполнении ISR() нельзя сделать членом какого-то класса.А зачем ему быть членом класса? Оно даже логически слабо в класс просится. Членом класса является isr_handler(). Допустим у вас 4 UARTa: класс - один, объектов - 4, вектора прерываний для каждого объекта свои и каждый вектор вызывает один и тот же обработчик но для своего, конкретного объекта. С натяжкой можно было бы согласиться спрятать ISR внутрь класса для периферии, которая на кристалле одна. Но где гарантия, что завтра не придется переносить этот код на кристалл, у которого этой периферии две или три? Share this post Link to post Share on other sites
doom13 0 Posted May 19, 2014 · Report post А зачем ему быть членом класса? Оно даже логически слабо в класс просится. Членом класса является isr_handler(). Допустим у вас 4 UARTa: класс - один, объектов - 4, вектора прерываний для каждого объекта свои и каждый вектор вызывает один и тот же обработчик но для своего, конкретного объекта. С натяжкой можно было бы согласиться спрятать ISR внутрь класса для периферии, которая на кристалле одна. Но где гарантия, что завтра не придется переносить этот код на кристалл, у которого этой периферии две или три? Для каждого объекта, естественно, свой обработчик, его и задаём при помощи InitIsr (RegisterIsr если нравится). Хорошо, но допустим есть какой-то класс Device, у него есть интерфейс управления (class Spi), интерфейс передачи данных (class Uart), системный счётчик (class Timer), для каждого необходимо задать обработчик прерывания. Ну а обработчик прерывания логически просится в класс Device, т.к. он непосредственно и выполняет операции необходимые для функционирования Device. Допустим в системе пять таймеров, для каждого нужен свой обработчик. Логично всё "одинаковое" запихнуть внутрь класса, обработчик, который может отличаться для каждого таймера реализовать как callback-функцию. Share this post Link to post Share on other sites
Сергей Борщ 0 Posted May 19, 2014 · Report post Допустим в системе пять таймеров, для каждого нужен свой обработчик.Угу. И каждый имеет свой вектор прерывания ISR(Timer_XX_vect) Как все пять обработчиков сделать статическими членами класса timer? Или я чего-то не понял в вашей идеологии? Логично всё "одинаковое" запихнуть внутрь класса, обработчик, который может отличаться для каждого таймера реализовать как callback-функцию.Угу, как callback или как виртуальную функцию. Или построить наследников на шаблонах используя Curiously recurring template pattern (я так думаю, сам не пробовал пока). Share this post Link to post Share on other sites
doom13 0 Posted May 19, 2014 · Report post Угу. И каждый имеет свой вектор прерывания ISR(Timer_XX_vect) Как все пять обработчиков сделать статическими членами класса timer? Или я чего-то не понял в вашей идеологии? Все пять обработчиков и не являются статическими членами класса Timer. У Timer есть только функция регистрации прерывания. Обработчик прерывания необходимо зарегистрировать после создания объекта. Угу, как callback или как виртуальную функцию. Или построить наследников на шаблонах используя Curiously recurring template pattern (я так думаю, сам не пробовал пока). Тут не понял иронию, что не так в моей реализации? Всё работает и , по-идее, нет никаких противоречий. Можно и унаследовать если есть желание. Share this post Link to post Share on other sites
megajohn 0 Posted May 19, 2014 · Report post Все пять обработчиков и не являются статическими членами класса Timer. У Timer есть только функция регистрации прерывания. Обработчик прерывания необходимо зарегистрировать после создания объекта. я так и делал, но нужно при регистрации передавать this и собсвенно иметь массив этих void* на this Share this post Link to post Share on other sites