Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

C++ для микроконтроллеров

Вс авг 20, 2017 18:49:37

Хочу поделиться наработками по программированию микроконтроллеров на языке C++.

Внутри:
- пример с динамической индикацией (исходники + proteus)
- пример с LCD на HD44780 (исходники + proteus)
- небольшое описание

Микроконтроллеры ATtiny2313 и ATmega32, компилятор IAR

Всё находится здесь
https://ru.files.fm/u/a2sfccuf#/list/,файлuC_cpp.7z

Re: C++ для микроконтроллеров

Вт авг 22, 2017 20:52:42

Ахтунг! "Небезопасный источник."

Re: C++ для микроконтроллеров

Чт авг 24, 2017 18:53:53

Чем заходите?
Касперский определяет как "Безопасный веб-сайт (по данным Kaspersky Security Network)"

Файл прикрепил к сообщению
Вложения
uC_cpp.7z
(662.08 KiB) Скачиваний: 288

Re: C++ для микроконтроллеров

Пн авг 28, 2017 15:26:13

не очень понятно пока, зачем. Классы со сплошь public static inline void методами - имхо маленько не то, ради чего стоит использовать плюсы.

Re: C++ для микроконтроллеров

Пн авг 28, 2017 15:58:12

не очень понятно пока, зачем. Классы со сплошь public static inline void методами - имхо маленько не то, ради чего стоит использовать плюсы.

На самом деле все не так плохо, в эмбедде большинство методов и должны быть static и часто inline, хотя непонятно зачем автор при помощи #pragma явно заставляет компилятор инлайнить методы там, где они и так будут инлайниться согласно правилам языка. Вот если бы тут все методы были статические и не использовались шаблоны, тогда да, можно было бы спокойно заменить классы неймспейсами ничего особо не потеряв...

Re: C++ для микроконтроллеров

Пн авг 28, 2017 16:45:09

>> имхо маленько не то, ради чего стоит использовать плюсы
К сожалению C++ для ПК и для микроконтроллеров отличается. Нельзя многое из ПК использовать в микроконтроллерах - микроконтроллер не справиться, ну и стиль программирования для микроконтроллера не имеет смысла для ПК.
>> непонятно зачем автор при помощи #pragma явно заставляет компилятор инлайнить методы
наличие ключевого слова inline не означает, что компилятор обязательно будет инлайнить метод (по крайней мере в IAR), для принудительного "инлайнинга" необходимо использовать #pragma. Во многих местах можно #pragma убрать и ничего не измениться, но не везде (можете по экспериментировать). Для себя решил, что если метод должен инлайнится, то наличие #pragma обязательно (в основном это касается прерываний).

Re: C++ для микроконтроллеров

Пн авг 28, 2017 17:10:46

наличие ключевого слова inline не означает, что компилятор обязательно будет инлайнить метод (по крайней мере в IAR), для принудительного "инлайнинга" необходимо использовать #pragma. Во многих местах можно #pragma убрать и ничего не измениться, но не везде (можете по экспериментировать). Для себя решил, что если метод должен инлайнится, то наличие #pragma обязательно (в основном это касается прерываний).

А речь не про наличие inline, а про случаи типа таких:
Код:
class TCounter
{
public:
        #pragma inline = forced
        static inline void Init(void)
        {
            Recount = VALUE;
            FCounter::Reset();
        }
...
};

Тут не нужен ни inline, ни #pragma inline, в стандарте по этому поводу говорится следующее: A member function may be defined in its class definition, in which case it is an inline member function, or it may be defined outside of its class definition if it has already been declared but not defined in its class definition.

И почему этот метод принимает void?

Re: C++ для микроконтроллеров

Пн авг 28, 2017 18:29:26

начну с "почему void".
Для определения переменной Recount необходимо указать тип. Тип для Recount определяется на стадии компиляции в шаблоне в зависимости от значения (у меня это 1000, т.е тип будет uint16_t).
Код:
typedef STATIC_TYPE_UNSIGNED_VALUE(Value) T;
static volatile T Recount;

Мне (по условию) не требовалось менять значение инициализации (Если алгоритм требует, то конечно можно и передать значение). Тогда будет так:
Код:
static inline void Init(T value )
{
    Recount = value;
    FCounter::Reset();
}

но тогда входное значение будет (должно) иметь тоже тип uint16_t. Если сразу задать тип для Recount, то придётся делать класс под каждый тип, что не целесообразно.

Ну и отсюда почему inline. Т.к. это шаблонный класс, и инициализация предполагалась только один раз поэтому код решил инлайнить, чтобы компилятор не оформил это в вызов метода.

Добавлено after 13 minutes 7 seconds:
вообще всё что связано с inline появилось после того как начал заниматься прерываниями в C++.

Re: C++ для микроконтроллеров

Пн авг 28, 2017 18:33:40

Dm37, я говорю совершенно о другом :) В С было так:
Код:
void func(void);

В С++ стало так:
Код:
void func();

Ты пишешь на С++, но местами как будто на С. Очень часто когда я вижу подобный код с ним в комплекте еще идут typedef struct и прочие пережитки чистого С.

Ну и отсюда почему inline. Т.к. это шаблонный класс, и инициализация предполагалась только один раз поэтому код решил инлайнить, чтобы компилятор не оформил это в вызов метода.

Еще раз повторяю, любой метод определенный в теле класса неявно является встроенным, т.е. инлайнится согласно правилам самого языка. Конечно можно явно прописать и inline со всякими прагмами, но это не имеет никакого значения.

Re: C++ для микроконтроллеров

Пн авг 28, 2017 18:50:23

>> В С++ стало так:
я это знаю, это не нарушает синтаксис

>> struct
в любом учебнике по C++ struct показан как public класс

по поводу inline, C++ не работает с прерываниями, это надстройка embedded. Поэтому корректной работы от компилятора ждать не приходится, надо ему помочь (ещё раз повторюсь, что сначала не было inline, он появился только после работы с прерываниями, когда результат был отрицательный)

Я ждал замечаний не по поводу синтаксиса (что пока достаточно спорно), а по организации программы, ошибкам, рекомендации

Re: C++ для микроконтроллеров

Вт авг 29, 2017 04:03:43

Добрый день, с С++ совсем не знаком по этому и пишу, подскажите в нем есть более удобные способы/методы распараллеливания задач(на конечных автоматах), ну скажем вот в функции инициализации LCD,
Код:
        static void Init(void)
        {
            InitPorts();
            DELAY_MS(15);
            SetModeCmd();
            WriteCfg(0x30);
            DELAY_MS(4.1);
            WriteCfg(0x30);
            DELAY_US(100);
            WriteCfg(0x30);
            DELAY_US(100);
            WriteCfg(0x20);
            DELAY_US(100);
            Write(0x28);
            DELAY_US(40);
            Write(0x08);
            DELAY_US(40);
            Write(0x0C);
            DELAY_US(40);
            Write(0x01);
            DELAY_MS(1.6);
            Write(0x06);
      }

Что бы вместо DELAY_MS происходил выход в майн, и проход по всем остальным задачам.
В общем есть ли там более удобное использование switch case ?

Re: C++ для микроконтроллеров

Вт авг 29, 2017 04:30:21

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

Re: C++ для микроконтроллеров

Вт авг 29, 2017 06:57:41

pokk писал(а):Что бы вместо DELAY_MS происходил выход в майн, и проход по всем остальным задачам
как велико ваше желание выстрелить себе в ногу? какие-такие задачи требуют от вас этого самого "распараллеливания"? вы на 100% уверены, что это необходимо?

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

Re: C для микроконтроллеров

Вт авг 29, 2017 07:27:51

DELAY_US нет смысла переделывать, а вот DELAY_MS особо если с большими цифрами, да работающий внутри прерывания вполне может придать контроллеру некоторую ... туповатовть. (динам. индикация может подвисать, нажатие кнопки (не на INTе) может оказаться пропущенным, "собака" не кормлена...

Re: C++ для микроконтроллеров

Вт авг 29, 2017 08:25:25

Да на все 100% уверен что надо, даже функцию инициализацию надо так как, весь маин состоит из параллельных частей, а индикатор может повисать,из за внешних помех, так что приходится его передергивать(пере инициализировать).
Ответить