реклама на сайте
подробности

 
 
5 страниц V  « < 2 3 4 5 >  
Reply to this topicStart new topic
> C++ и ООП для микроконтроллеров AVR
andrewlekar
сообщение May 19 2014, 02:50
Сообщение #46


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



В scmRTOS посмотрите как обработчики сделаны. У меня опыта нет упихивания С++ в контроллер.

Цитата
И что значит "Поля в классах нужно инициализировать руками"

В Си вы пишете в module.c:
Код
static int data;


И эта переменная у вас будет инициализирована нулём.

В С++ вы пишете в module.h:
Код
class Module { private: int data;};


И эта переменная у вас инициализирована не будет.

Сообщение отредактировал andrewlekar - May 19 2014, 02:51
Go to the top of the page
 
+Quote Post
doom13
сообщение May 19 2014, 03:12
Сообщение #47


Профессионал
*****

Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539



Цитата(yanvasiij @ May 19 2014, 09:33) *
А как быть с обработчиками прерываний? Вот я хочу сделать класс драйверов, как туда засунуть обработчик?


Можно так:
Код
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;
        ...
};

Go to the top of the page
 
+Quote Post
yanvasiij
сообщение May 19 2014, 04:05
Сообщение #48


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Цитата(andrewlekar @ May 19 2014, 13:00) *
В С++ вы пишете в module.h:
Код
class Module { private: int data;};


И эта переменная у вас инициализирована не будет.


Ну я так понимаю на то конструкторы и есть. Мне вот только не совсем понятно: можно ли объявлять объект - не создавать его динамически. То есть в приведенном Вами примере создание объекта вот так:
Код
class Module { private: int data;};

Module myModule;

int main (void)
{
    myModule.data=100500;
    while(1)
...
}


Цитата(doom13 @ May 19 2014, 13:22) *
Можно так:
...

Не совсем понял: Вы передали указатель на функцию обработчик прерывания в метод InitIsr?
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение May 19 2014, 04:25
Сообщение #49


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Цитата
можно ли объявлять объект - не создавать его динамически.

Можно. Только в вашем примере data будет недоступен.
Go to the top of the page
 
+Quote Post
doom13
сообщение May 19 2014, 04:58
Сообщение #50


Профессионал
*****

Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539



Цитата(yanvasiij @ May 19 2014, 11:15) *
Не совсем понял: Вы передали указатель на функцию обработчик прерывания в метод InitIsr?

Теперь для каждого объекта можно задать свой обработчик прерывания, Ваши предложения...
Моя практика показала, что если обработчик прерывания - член класса, то он должен быть статик, или не работает. Т.о. это выбрано для реализации возможности задать собственный обработчик прерывания для каждого объекта.
Go to the top of the page
 
+Quote Post
megajohn
сообщение May 19 2014, 05:02
Сообщение #51


Профессионал
*****

Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143



Цитата(dxp @ May 11 2009, 19:22) *
... которая дает возможность использовать полиморфизм (в данном случае: переопределяемое на рантайме поведение).


...многие его средства - это абстракции уровня этапа компиляции.


а вот мне тут кажется противоречие. Или нет ?

и помнится, для реализации virtual нужно дополнительно место в RAM для каких-то таблиц ( давно где-то читал, но proof не дам - не знаю где читал )


--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 19 2014, 05:09
Сообщение #52


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(doom13 @ May 19 2014, 12:08) *
Ваши предложения...
Код
class driver
{
public:
    void isr_handler();
    ....
};

driver Device1;

ISR(XXXX_vect)
{
    Device1.isr_handler();
};



--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
msalov
сообщение May 19 2014, 05:12
Сообщение #53


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(megajohn @ May 19 2014, 12:12) *
и помнится, для реализации virtual нужно дополнительно место в RAM для каких-то таблиц ( давно где-то читал, но proof не дам - не знаю где читал )


В "тело" каждого экземпляра класса добавляется указатель на таблицу виртуальных функций. Сами таблицы лежат в ПЗУ.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 19 2014, 05:14
Сообщение #54


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(megajohn @ May 19 2014, 12:12) *
и помнится, для реализации virtual нужно дополнительно место в RAM для каких-то таблиц ( давно где-то читал, но proof не дам - не знаю где читал )
Таблица в количестве одной штуки на каждый класс с виртуальными функциями. Обычно хранится в памяти кода (avr-gcc до сих пор этого не умеет, хранит в ОЗУ). В каждом объекте такого класса один указатель (уже в ОЗУ) на эту таблицу. Таблица состоит из указателей на реализации виртуальных функций, т.е. если класс имеет одну виртуальную функцию, то таблица состоит из одного указателя. Примерно так, "на пальцах".


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
doom13
сообщение May 19 2014, 06:03
Сообщение #55


Профессионал
*****

Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539



Цитата(Сергей Борщ @ May 19 2014, 12:19) *
Код
class driver
{
public:
    void isr_handler();
    ....
};

driver Device1;

ISR(XXXX_vect)
{
    Device1.isr_handler();
};

В таком исполнении ISR() нельзя сделать членом какого-то класса.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 19 2014, 07:48
Сообщение #56


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(doom13 @ May 19 2014, 13:13) *
В таком исполнении ISR() нельзя сделать членом какого-то класса.
А зачем ему быть членом класса? Оно даже логически слабо в класс просится. Членом класса является isr_handler(). Допустим у вас 4 UARTa: класс - один, объектов - 4, вектора прерываний для каждого объекта свои и каждый вектор вызывает один и тот же обработчик но для своего, конкретного объекта. С натяжкой можно было бы согласиться спрятать ISR внутрь класса для периферии, которая на кристалле одна. Но где гарантия, что завтра не придется переносить этот код на кристалл, у которого этой периферии две или три?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
doom13
сообщение May 19 2014, 08:36
Сообщение #57


Профессионал
*****

Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539



Цитата(Сергей Борщ @ May 19 2014, 14:58) *
А зачем ему быть членом класса? Оно даже логически слабо в класс просится. Членом класса является isr_handler(). Допустим у вас 4 UARTa: класс - один, объектов - 4, вектора прерываний для каждого объекта свои и каждый вектор вызывает один и тот же обработчик но для своего, конкретного объекта. С натяжкой можно было бы согласиться спрятать ISR внутрь класса для периферии, которая на кристалле одна. Но где гарантия, что завтра не придется переносить этот код на кристалл, у которого этой периферии две или три?


Для каждого объекта, естественно, свой обработчик, его и задаём при помощи InitIsr (RegisterIsr если нравится).

Хорошо, но допустим есть какой-то класс Device, у него есть интерфейс управления (class Spi), интерфейс передачи данных (class Uart), системный счётчик (class Timer), для каждого необходимо задать обработчик прерывания. Ну а обработчик прерывания логически просится в класс Device, т.к. он непосредственно и выполняет операции необходимые для функционирования Device.

Допустим в системе пять таймеров, для каждого нужен свой обработчик. Логично всё "одинаковое" запихнуть внутрь класса, обработчик, который может отличаться для каждого таймера реализовать как callback-функцию.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 19 2014, 09:01
Сообщение #58


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(doom13 @ May 19 2014, 15:46) *
Допустим в системе пять таймеров, для каждого нужен свой обработчик.
Угу. И каждый имеет свой вектор прерывания ISR(Timer_XX_vect) Как все пять обработчиков сделать статическими членами класса timer? Или я чего-то не понял в вашей идеологии?
Цитата(doom13 @ May 19 2014, 15:46) *
Логично всё "одинаковое" запихнуть внутрь класса, обработчик, который может отличаться для каждого таймера реализовать как callback-функцию.
Угу, как callback или как виртуальную функцию. Или построить наследников на шаблонах используя Curiously recurring template pattern (я так думаю, сам не пробовал пока).


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
doom13
сообщение May 19 2014, 09:17
Сообщение #59


Профессионал
*****

Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539



Цитата(Сергей Борщ @ May 19 2014, 16:11) *
Угу. И каждый имеет свой вектор прерывания ISR(Timer_XX_vect) Как все пять обработчиков сделать статическими членами класса timer? Или я чего-то не понял в вашей идеологии?

Все пять обработчиков и не являются статическими членами класса Timer. У Timer есть только функция регистрации прерывания. Обработчик прерывания необходимо зарегистрировать после создания объекта.

Цитата(Сергей Борщ @ May 19 2014, 16:11) *
Угу, как callback или как виртуальную функцию. Или построить наследников на шаблонах используя Curiously recurring template pattern (я так думаю, сам не пробовал пока).

Тут не понял иронию, что не так в моей реализации? Всё работает и , по-идее, нет никаких противоречий. Можно и унаследовать если есть желание.
Go to the top of the page
 
+Quote Post
megajohn
сообщение May 19 2014, 09:25
Сообщение #60


Профессионал
*****

Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143



Цитата(doom13 @ May 19 2014, 17:27) *
Все пять обработчиков и не являются статическими членами класса Timer. У Timer есть только функция регистрации прерывания. Обработчик прерывания необходимо зарегистрировать после создания объекта.


я так и делал, но нужно при регистрации передавать this и собсвенно иметь массив этих void* на this


--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post

5 страниц V  « < 2 3 4 5 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 09:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01506 секунд с 7
ELECTRONIX ©2004-2016