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

 
 
3 страниц V  < 1 2 3  
Reply to this topicStart new topic
> С++, обработчик прерывания как статическая ф-я класса.
klen
сообщение May 27 2010, 08:27
Сообщение #31


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



мдя... С++ пошел в микроконтроллеры. кчему бы это wink.gif
тенденция однако..... вывод; много лишнего озу и флеша wink.gif

если не использовать "гадости" типа виртуальных функций, RTTI , эксепшены и прочих архитектрных излишестьв то получается удобно и почти бесплатно.
пробывал сделать обертку для FreeRTOS, все задачи наследуются от базового класа в котором все есть - отается переопределить функцию задачи. в резултате кода приложения стало процентов на 90 smile.gif меньше, стало проще читать код. скорость не страдает, размер чуток - небольшие с++ накладные расходы. такчто я думаю что при умном применении с++ польза есть.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение May 27 2010, 08:34
Сообщение #32


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(klen @ May 27 2010, 12:27) *
мдя... С++ пошел в микроконтроллеры. кчему бы это wink.gif
тенденция однако.....

Да уж C# давно пошёл...
Я даже кидал ссылку, для PIC чего-то пытались сваять
Не по теме, конечно, но всё же...


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
klen
сообщение May 27 2010, 08:38
Сообщение #33


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



Цитата(MrYuran @ May 27 2010, 12:34) *
Да уж C# давно пошёл...

наш "любимый" мелкомягкй везде свои костыли протолкнуть пытается ... при комунизме такое вот творчество наверно сдохло бы быстро, а вот буржуи молоццы - умеют играть в игу " кто дольше допинает дохлую лошадь в светлое будущее'
Go to the top of the page
 
+Quote Post
Damon
сообщение May 27 2010, 09:01
Сообщение #34


Участник
*

Группа: Участник
Сообщений: 59
Регистрация: 12-12-05
Пользователь №: 12 125



Цитата(klen @ May 27 2010, 12:27) *
если не использовать "гадости" типа виртуальных функций...

Ну Вы зря так про виртуальные ф-ции! Они тянут, конечно, за собой дополнительный код, но иногда без никак!
Как пример, после некоторой адаптации State Machine к (выработанным мною, для себя) требованиям к встраиваемой технике (в частности отказался от динамической памяти и заставил все работать в стеке), я познал дао (или дзен? :-)

Как бы то ни было, предпочитаю статический полиморфизм динамическому (выражаясь словами Дэвида Вандевурда, Николайа М. Джосаттиса). Он меньше места занимает, потому как, оптимизируется лучше.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 27 2010, 10:26
Сообщение #35


Гуру
******

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



Цитата(Damon @ May 27 2010, 10:26) *
Код
    static void IRQHandler( ) asm( "__vector_10" ); // Или, не 10 ( взято "с потолка" ), в любом случае, меняя нумер можно
                                                                                 //  подставить куда угодно
};
Вот-вот. 10 надо подставлять вручную, что убивает всю красоту.


--------------------
На любой вопрос даю любой ответ
"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
Damon
сообщение May 27 2010, 11:21
Сообщение #36


Участник
*

Группа: Участник
Сообщений: 59
Регистрация: 12-12-05
Пользователь №: 12 125



Цитата(Сергей Борщ @ May 27 2010, 14:26) *
Вот-вот. 10 надо подставлять вручную, что убивает всю красоту.

Не обязательно. :-)
В оригинале ( C++ Interrupts ) использовался макрос:
Код
#define CLASS_IRQ(name, vector) \
    static void name(void) asm(__STRINGIFY(vector)) \
    __attribute__ ((signal, __INTR_ATTRS))

Он рабочий, как я понял, только с некоторыми оговорками:
  1. при описании тела ф-ции необходимо добавить перед ней 'extern "C"'
  2. заменить "YYYYYYY_XXX_vect" (например, TIMER0_OVF_vect) на "__vector_XX"

Второй пункт можно реализовать через макросы (что-то навроде #define TIMER0_OVF_vect __vector_XX)

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

Да и скрыто это будет от енд-юзера... Код получается практически повторно используемым. Фактически, как это нынче модно называть, Framework'ом. Таким образом можно охватить фактически всю перефирию контроллера и код станет вполне повторно используемым. Но здесь есть одна засада! Начну немного издалека.

В Delphi и .NET, компоненты на форме делегируют обработку событий методам формы, что весьма удобно и выглядит красиво.
Хотелось бы реализовать что-то подобное. Т.е. класс таймера, к примеру реагирует на прерывание от него и, например, перезагружает регистр счетчика необходимым значением, на этом его функции обработки прерывания заканчиваются. Сама же обработка события делегируется другому объекту для обработки и следованию общей логики выполнения программы. Сама идея не нова -- паттерн command из книжки GoF. Лично мне очень понравилась реализация этого паттерна от Александреску. После того, как продрался через его описание в книжке. ИМХО, объяснять Александреску нихрена не умеет! Вот только есть нюанс, любые реализации этого паттерна используют виртуальные ф-ции, что тянет за собой доп код и мешает оптимизации. В случае Александреску, получается пара ф-ций "пересылки" аргументов к месту назначения. Даже после оптимизации все равно останется косвенный переход по VTable, т.ч. "сквозной" оптимизации не получится. И если для ARM'ов еще можно махнуть рукой или плюнуть (нужное подчеркнуть), то, например, для ATmega48, плеваться придется много и долго...
Есть вариант решения с использованием шаблонов. Данный пример для "большой" машины и только в целях иллюстрации принципа (не надо мне потом предъявлять по поводу использования std::list на ATmega48! :-).
Код
/*
* Command.h
*
*  Created on: 26.05.2010
*      Author: damon
*/

#ifndef COMMAND_H_
#define COMMAND_H_

#include <iostream>
#include <list>
#include <string>

template< class Handlers >
class Command: public Handlers
{
public:
    Command( ) { }

    void Signal( int sign )
    {
        Handlers::OnSignal( sign );
    }
};

class CommandHandler
{
private:
    std::string str_;

public:
    CommandHandler( char *str )
    {
        str_ = str;
    }

    void Print( int val )
    {
        std::cout << str_ << std::endl << "\t Полученное значение: " << val << std::endl;
    }
};

class CommandSwitcher
{
private:
    std::list< CommandHandler * > handlers_;

public:
    void AddHandler( CommandHandler *handler )
    {
        handlers_.push_back( handler );
    }

    void operator+=( CommandHandler *handler )
    {
        AddHandler( handler );
    }

    void DelHandler( CommandHandler *handler )
    {
        handlers_.remove( handler );
    }

    void operator-=( CommandHandler *handler )
    {
        DelHandler( handler );
    }

    void OnSignal( int sign )
    {
        std::for_each( handlers_.begin( ), handlers_.end( ), bind2nd( mem_fun( &CommandHandler::Print ), sign ) );
    }
};

#endif /* COMMAND_H_ */


Код
//main.cpp
#include "Command.h"

int main()
{
    Command< CommandSwitcher > command;

    CommandHandler firstHandler(  ( char * ) "First handler"  );
    CommandHandler secondHandler( ( char * ) "Second handler" );
    CommandHandler thirdHandler(  ( char * ) "Third handler"  );

    command += &firstHandler;
    command += &secondHandler;
    command += &thirdHandler;

    command.Signal( 10 );

    std::cout << std::endl;

    command -= &firstHandler;

    command.Signal( 1 );

    return 0;
}


Таким образом вся логика "коммутации" сигнала о событии сосредоточена в классе CommandSwitcher, который никоим образом не зависит от класса Command. При этом, при использовании класса Command в другом проекте не понадобится вносит в него никаких изменений! Меняться будет только CommandSwitcher!

При этом виртуальные ф-ции не используются, а поскольку шаблонные методы описываются в хидере, есть надежда на их "сквозную" оптимизацию, что благотворно скажется на размере и скорости прошивки контроллера!

Сообщение отредактировал Damon - May 27 2010, 11:25
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 19:56
Рейтинг@Mail.ru


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