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

 
 
> C++ и макросы имени Аскольда Волкова., Хочу скрестить:)
AHTOXA
сообщение Jul 29 2009, 08:41
Сообщение #1


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Тема не совсем про scmRTOS, но тут много спецов по плюсамsmile.gif

Сделал такую штуку:
Код
class BasePin
{
    public:
        virtual void On() = 0;
        virtual void Off() = 0;
        virtual void Cpl() = 0;
...
};

Это базовый абстрактный класс. Нужен, чтоб можно было передавать ссылку на любую ножку куда угодно. Например, класс TDAC(spi& spiRef, BasePin& CS), конструктору передаётся ссылка на spi и ссылка на ножку чипселекта.

Дальше начинаю городить шаблоны:
Код
template<int port, int pin, char activestate = 'H'> class Pin;

template<int pin>
class Pin<1, pin>: public BasePin
{
    public:
        virtual void On() { P1OUT |= 1<<pin; }\
...
};

template<int pin>
class Pin<1, pin, 'L'>: public BasePin
{
    public:
        virtual void On(){ P1OUT &= ~(1<<pin); }
...
};


И так 5 раз (для портов 1-5). Как-то коряво...

Пробовал так:
Код
template<int port, int pin, char activestate = 'H'>
class Pin: public BasePin
{
    public:
        virtual void On() {
            if (port == 1) P1OUT |= 1<<pin;
            if (port == 2) P2OUT |= 1<<pin;
            if (port == 3) P3OUT |= 1<<pin;
            if (port == 4) P4OUT |= 1<<pin;
            if (port == 5) P5OUT |= 1<<pin;
        }
...
};


Так вроде поменьше писанины, но тоже корявенько.

Теперь внимание, вопросsmile.gif
Есть ли какая-нибудь возможность получить вот такое:
Код
template<int port, int pin, char activestate = 'H'>
class Pin: public BasePin
{
    public:
        virtual void On() {P##portOUT |= 1<<pin; }
...
};


То есть, хочу нечто вроде макроподстановки. Вроде где-то что-то встречал подобное, но никак не вспомню, куда копать.


ЗЫ. А работает вроде хорошо. То есть,

Код
Pin<1, 2, 'L'> PIN12;
#define PIN_12 1, 2, L
Pin<2, 3> PIN23;
#define PIN_23 2, 3, H
...
    PIN12.On();
    on(PIN_12);
    PIN23.On();
    on(PIN_23);


компилится в
Код
    1808:    e2 c2 21 00     bic.b    #4,    &0x0021  ;r2 As==10
    180c:    e2 c2 21 00     bic.b    #4,    &0x0021  ;r2 As==10
    1810:    f2 d2 29 00     bis.b    #8,    &0x0029  ;r2 As==11
    1814:    f2 d2 29 00     bis.b    #8,    &0x0029  ;r2 As==11


Накладные расходы - vtable+процедуры на каждую созданную ножку. За это я получаю возможность передавать ссылку на ножку. Я давно этого хотел.

При обращении по ссылке (в TDAC) вызовы уже из vtable, но это для меня приемлемо.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Сергей Борщ
сообщение Jul 29 2009, 10:50
Сообщение #2


Гуру
******

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



Цитата(AHTOXA @ Jul 29 2009, 11:41) *
Пробовал так:
Код
template<int port, int pin, char activestate = 'H'>
class Pin: public BasePin
{
    public:
        virtual void On() {
            if (port == 1) P1OUT |= 1<<pin;
            if (port == 2) P2OUT |= 1<<pin;
            if (port == 3) P3OUT |= 1<<pin;
            if (port == 4) P4OUT |= 1<<pin;
            if (port == 5) P5OUT |= 1<<pin;
        }
...
};


Так вроде поменьше писанины, но тоже корявенько.
Я делал так. это не совсем по теме, но...:
Код
#ifndef USCIA_H__
#define USCIA_H__
#include    <io.h>

#ifndef USCIB_H__
enum usci_module_t { USCI0, USCI1 };
#endif


template <usci_module_t const module>
class uscia_t
{
public:
    class usca_ctl0_t    /* USCI Ax Control Register 0 */
    {
    public:
        uint8_t operator=(uint8_t value) { module ? UCA1CTL0 = value : UCA0CTL0 = value; return value; }
        void operator|=(uint8_t value) { module ? UCA1CTL0 |= value : UCA0CTL0 |= value; }
        void operator&=(uint8_t value) { module ? UCA1CTL0 &= value : UCA0CTL0 &= value; }
        operator uint8_t() { return module ? UCA1CTL0 : UCA0CTL0; }
    } static CTL0;
...
// pins
    class txd_bit
    {
    public:
        operator uint8_t() { return module ? (1 << 6) : (1 << 4); }
    }  static TXD_BIT;

    class rxd_bit
    {
    public:
        operator uint8_t() { return module ? (1 << 7) : (1 << 5); }
    }  static RXD_BIT;
};

template <usci_module_t module>
class uart_t
{
    typedef uscia_t<module> UCA;
public:
    static INLINE inline void init(uint32_t const divider);
....
};

template <usci_module_t module>
void uart_t<module>::init(uint32_t const divider)
{
    UCA::CTL1 |= (1  * UCSWRST);
    UCA::CTL1 = 0
        |(0 * UCRXEIE)|(0 * UCBRKIE)|(0 * UCTXADDR)
        |(1 * UCSWRST)
        |(1 * UCSSEL1)|(0 * UCSSEL0)
      ;
    UCA::CTL0 = (0 * UCPEN)|(0 * UCMSB)|(0 * UC7BIT)|(0 * UCSPB)|(0 * UCMODE1)|(0 * UCMODE0)|(0 * UCSYNC);

    UCA::BR0 = (divider / 16) & 0xFF;
    UCA::BR1 = (divider / 16) >> 8;
    UCA::MCTL = ((divider - (divider / 16) * 16) * UCBRF0)
        |(0 * UCBRS0)|(1 * UCOS16);
    UCA::CTL1 &= ~(1  * UCSWRST);
    P3SEL |= UCA::RXD_BIT | UCA::TXD_BIT;
    UCA::IFG |= UCA::TXIFG;
    UCA::IE |= UCA::RXIE;
}


--------------------
На любой вопрос даю любой ответ
"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
AHTOXA
сообщение Aug 19 2009, 05:09
Сообщение #3


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



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

Цитата(Сергей Борщ @ Jul 29 2009, 16:50) *
Я делал так. это не совсем по теме, но...:
Код
enum usci_module_t { USCI0, USCI1 };

template <usci_module_t const module>
class uscia_t
{
public:
     class usca_ctl0_t    /* USCI Ax Control Register 0 */
     {
     public:
         uint8_t operator=(uint8_t value) { module ? UCA1CTL0 = value : UCA0CTL0 = value; return value; }
         void operator|=(uint8_t value) { module ? UCA1CTL0 |= value : UCA0CTL0 |= value; }
         void operator&=(uint8_t value) { module ? UCA1CTL0 &= value : UCA0CTL0 &= value; }
         operator uint8_t() { return module ? UCA1CTL0 : UCA0CTL0; }
     } static CTL0;
...
// pins
     class txd_bit
     {
     public:
         operator uint8_t() { return module ? (1 << 6) : (1 << 4); }
     }  static TXD_BIT;
...
};

template <usci_module_t module>
class uart_t
{
     typedef uscia_t<module> UCA;
public:
     static INLINE inline void init(uint32_t const divider);
....
};

template <usci_module_t module>
void uart_t<module>::init(uint32_t const divider)
{
     UCA::CTL1 |= (1  * UCSWRST);
     UCA::CTL1 = 0
...
}


Здесь ведь можно сделать ещё красивее, если унаследовать uart_t от uscia_t:
Код
template <usci_module_t module>
class uart_t: public uscia_t<module>
{
public:
     static INLINE inline void init(uint32_t const divider);
....
};


Тогда не потребуется указывать UCA:: при обращении к регистрам:

Код
template <usci_module_t module>
void uart_t<module>::init(uint32_t const divider)
{
     CTL1 |= (1  * UCSWRST);
     CTL1 = 0
...
}


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 19 2009, 09:07
Сообщение #4


Гуру
******

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



Цитата(AHTOXA @ Aug 19 2009, 08:09) *
Тогда не потребуется указывать UCA:: при обращении к регистрам:
А это мысль! Нет предела совершнству!


--------------------
На любой вопрос даю любой ответ
"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
AHTOXA
сообщение Aug 28 2009, 16:54
Сообщение #5


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Сергей Борщ @ Aug 19 2009, 15:07) *
А это мысль! Нет предела совершнству!


Оказывается, есть... Эта красота не работает в более свежих gcc. Ругается, что мембер из базового класса "was not declared in this scope" в классе-потомке.
Я покопался в интернете, оказывается, что стандарт на этот счёт гласит:

14.6.2/3
In the definition of a class template or a member of a class template, if a base class of the class template depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.

И даже есть специальный баг, из-за которого, возможно, это работает в msp-gcc smile.gif

Я опечален sad.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- AHTOXA   C++ и макросы имени Аскольда Волкова.   Jul 29 2009, 08:41
- - sergeeff   А зачем нужен параметр шаблона activestate, если о...   Jul 29 2009, 10:17
|- - AHTOXA   Цитата(sergeeff @ Jul 29 2009, 16:17) А з...   Jul 29 2009, 10:30
|- - AHTOXA   Цитата(Сергей Борщ @ Jul 29 2009, 16:50) ...   Jul 29 2009, 11:32
||- - Сергей Борщ   Цитата(AHTOXA @ Jul 29 2009, 14:32) Да, э...   Jul 29 2009, 12:35
- - sergeeff   А в чем навар в объявлении Кодtemplate<> ...   Jul 29 2009, 13:16
- - AHTOXA   Цитата(Сергей Борщ @ Jul 29 2009, 18:35) ...   Jul 29 2009, 14:29
|- - sergeeff   Цитата(AHTOXA @ Jul 29 2009, 17:29) Ну я ...   Jul 29 2009, 21:45
|- - AHTOXA   Цитата(sergeeff @ Jul 30 2009, 03:45) Что...   Jul 30 2009, 04:57
|- - sergeeff   Цитата(AHTOXA @ Jul 30 2009, 07:57) Если ...   Jul 30 2009, 07:02
|- - AHTOXA   Цитата(sergeeff @ Jul 30 2009, 13:02) Над...   Jul 30 2009, 07:55
|- - sergeeff   Цитата(AHTOXA @ Jul 30 2009, 10:55) Так ч...   Jul 30 2009, 21:27
|- - AHTOXA   Цитата(sergeeff @ Jul 31 2009, 03:27) 1. ...   Jul 31 2009, 05:10
- - MrYuran   Кодvirtual void On() { if (port == ...   Jul 30 2009, 04:48
- - sergeeff   Вы внимательно пересмотрите свой топик. Про эту вс...   Jul 31 2009, 06:48
|- - AHTOXA   Цитата(sergeeff @ Jul 31 2009, 12:48) Вы ...   Jul 31 2009, 08:06
- - AHTOXA   Короче, вот что получилось в итоге: От общего ви...   Sep 5 2009, 21:44
- - AHTOXA   Вот для msp430:   Sep 8 2009, 04:19
- - Waso   На днях опять пришлось иметь дело с проектом, где ...   Sep 3 2010, 16:10


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

 


RSS Текстовая версия Сейчас: 23rd August 2025 - 14:59
Рейтинг@Mail.ru


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