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

Работа с ногами AVR на С++

А что это? А то может мне тоже это нравится, а я и не знаю ;)

----

Почитал. Пока не понял, нравится ли... Но скорее да, чем нет:)

Вчера вопрос видел, но уже выпадал в осадок.

Создал новую тему, чтобы тут не мешать.

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


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

Ну и нормально Только #if defined (PORTA) - лишнее, ибо не будет вызываться, пока вы не определите Pin<'A'...>. В этом прелесть шаблонов
Да? А я ведь сначала без этих излишеств написал. У меня WinAVR тогда ругается
'PORTE' was not declared in this scope

ну и действительно такого порта нет в восьмой меге например. А компилятор всетаки анализирует весь текст видимо. Может я чтото не так сделал?

С другой стороны для порта A дейсвительно это лишняя проверка, потомучто этот порт есть у всех авр-ок :lol:

 

По поводу режима ноги - для сложных случаев я оставил режим BIDIR. Можно еще режимов напридумывать. Я ж ведь ради чего это делаю - чтобы не париться с инициализацией ножек. Хочется чтоб это все делал конструктор. Вот кстати непонятка: если обьявление Pin<'A'...> сделано НЕ внутри какойто функции, то куда вставит компилятор код конструкторов?

 

А вы, похоже, смотрели вариант для stm32?
Да. Но я просмотрел всю тему. Полезного почерпнул не только из последнего поста. :)

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


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

У меня WinAVR тогда ругается
'PORTE' was not declared in this scope

Хм. Действительно. Надо подумать:)

По поводу режима ноги - для сложных случаев я оставил режим BIDIR. Можно еще режимов напридумывать. Я ж ведь ради чего это делаю - чтобы не париться с инициализацией ножек. Хочется чтоб это все делал конструктор.

Зачем плодить сущности? Пусть её инициализирует конструктор, но не конструктор ножки, а конструктор объекта, которому принадлежит ножка. Ну хотя дело конечно ваше:)

Вот кстати непонятка: если обьявление Pin<'A'...> сделано НЕ внутри какойто функции, то куда вставит компилятор код конструкторов?
В глобальную инициализацию. Обычно после обнуления секции BSS.
Но я просмотрел всю тему. Полезного почерпнул не только из последнего поста. :)

Это хорошо:) Просто мне показалось, что вариант MSP больше подходит для AVR.

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


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

Продолжу задавать вопросы по плюсам в этой теме. Предыстория та-же.

Написал класс клавиатуры MtxKeyboard со статическими переменными и функциями. Не забыл добавить в него виртуальные функции, которые будут и у наследников. Наследники такие:

template<int row, int col>
class MtxButton : public MtxKeyboard
{
public:
    /*virtual /*inline*/  uint8_t Get()        { return State[(col-1)]&(1<<(row-1));}
    /*virtual /*inline */ uint8_t Pressed()    { return (Get()&&(Ticks>=KEYPRES_TRESHOLD))? 1 : 0;}
    /*virtual /*inline */ uint8_t Locked()    { return (Get()&&(Ticks>=KEYLOCK_TRESHOLD))? 1 : 0;}
};

Простенькая тестовая прога:

MtxButton<1,1> Key_Num1;
MtxButton<1,2> Key_Num2;
MtxButton<1,3> Key_Num3;
MtxButton<1,4> Key_Num4;
//========== еще 16 кнопок

class Client_c
{public:
    Client_c(MtxKeyboard *  pB):pButton(pB){};
    MtxKeyboard * pButton;};

Client_c Client_1(&Key_Num1);
Client_c Client_2(&Key_Num2);
Client_c * pClient[]={&Client_1,&Client_2};

int main(void){
  for(;;)  {
      Keys.Scan();
      if (Key_Num1.Pressed())pin1.Toggle();
              if (Client_1.pButton->Pressed())pin2.Toggle();  }
return 0;}

на максимальной оптимизации в WinAVR130309 компилится в 500+ байт кода и около 10байт ОЗУ. Но вот как только я делаю функции наследников виртуальными - таже прога компилится в 3000+ байт кода и 230байт ОЗУ. Я в курсе про таблицу вызова виртуальных процедур, но 2 тыщи слов она не сожрет. В чем проблема? По сгенеренному асму не могу понять.. Какбудто оптимизация отключается. На всякий случай приложил исходники.

virtual.zip

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


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

Как только функции стали виртуальными у класса MtxButton<> появились собственные данные - указатель на таблицу виртуальных методов. Соответственно появились конструкторы, что бы эти данные проинициализировать. Далее, т.к. объекты статические и с конструктором, появились вызовы конструкторов до main, что потянуло всю run-time поддержку для вызова таких конструкторов и деструкторов.

 

Можно спросить - нафига наследовать MtxButton от MtxKeyboard , которая по жизни должна быть одна на всех, да еще и с виртуальными функциями, что вообще нонсенс. Такое наследование логически породит столько клавиатур, сколько будет создано кнопок.

Если уж хочется приткнуть куда нибудь клавиатуру, сделай так:

class BtnBase {
protected:
static MtxKeyboard keyboard;
};

template<int row, int col>
class MtxButton : public BtnBase
{
public:
    uint8_t Get()        { return keyboard.State[(col-1)]&(1<<(row-1));}
    uint8_t Pressed()    { return (Get()&&(keyboard.Ticks>=KEYPRES_TRESHOLD))? 1 : 0;}
    uint8_t Locked()    { return (kGet()&&(keyboard.Ticks>=KEYLOCK_TRESHOLD))? 1 : 0;}
};

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


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

Можно спросить - нафига наследовать MtxButton от MtxKeyboard , которая по жизни должна быть одна на всех, да еще и с виртуальными функциями, что вообще нонсенс.
Ну я сделал все члены класса MtxKeyboard статическими, так что этот класс не должен размножаться при появлении дочерних классов. Но ваша запись со вложенным статическим классом более грамотна, спасибо. Виртуализовать функции кнопок я хочу чтобы была возможность загонять указатели на них в массивы и потом динамически перебирать в цикле. Хотя это и не всегда надо и всегда можно обойти, но если есть возможность без огромных неоправданных затрат использовать красивости плюсов - я хочу их использовать. Просто я только начинаю осваивать плюсы и могу легко сваять слона из мухи по неопытности. Такчто не раздражайтесь пожалуйста сильно по этому поводу.

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


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

Ладно, чтобы не смотрели на меня косо, открою карты. =) Мне надо написать прогу для работы пульта оператора, к которому подключается до 20 панелей клиентов. Для каждого клиента на пульте есть кнопка и двухцветный светик. Поведение всех клиентов описывается одной машиной состояний (StateMachine).

Я задумал описать класс клиента, который содержит статус, процедуру обработки состояний, и ссылки на свои кнопку и светик, которые инициализируются в конструкторе. Кнопки и светики описаны в отдельных классах с интерфейсом "Нажата?", "Включить красный", "Выключить" и тп.. В main будет цикл, который будет перебирать массив указателей на классы клиентов и запускать процедуру обработки очередного клиента. Одна виртуальная функция добавляет 50байт кода для каждой кнопки или светика. Умножаем на кол-во кнопок и светиков, и еще на колво виртуальных методов и получаем много килобайт, невлезаем. Вот я и думаю как бы поизящнее решить эту проблему, чтобы поменьше писанины и пооптимальнее код.

 

От виртуальных функций можно избавиться, избавившись от шаблонов и заплатив парой байт ОЗУ на каждую кнопку и светик - помнить номер строки и столбца не как параметр шаблона, а как константу.

 

Интересно как решали такую проблему другие. =)

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


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

Одна виртуальная функция добавляет 50байт кода для каждой кнопки или светика.
Это не виртуальная функция добавляет, а шаблонный класс. Для такого применения шаблоны не годятся.

 

Вот я и думаю как бы поизящнее решить эту проблему, чтобы поменьше писанины и пооптимальнее код.

От виртуальных функций можно избавиться, избавившись от шаблонов и заплатив парой байт ОЗУ на каждую кнопку и светик - помнить номер строки и столбца не как параметр шаблона, а как константу.

Именно так. Пара констант (не обязательно в ОЗУ, кстати) займут много меньше кода, чем 3 функции.

 

Интересно как решали такую проблему другие. =)
Можно вообще отказаться от констант, если передавать их в качестве параметра (или глобала) в цикле в main. Такое решение позволит съэкономить память, но идет вразрез с ООП.

(Собственно при таком подходе это будет обычная, не ООП программа)

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


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

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...