All streams
Search
Write a publication
Pull to refresh
88
0
Вадим Дерябкин @Vadimatorikda

Инженер-программист

Send message
невозможности использовать динамическую память

Запрет на предприятии? Если так, то да, больно. Если нет, то при использовании FreeRTOS все более чем шикарно. Работа с динамической памятью (при достаточном выделении ресурсов под ее дефрагментацию и прочее) очень удобна.
кривой поддержки хотя бы С++11

GCC адекватно может в C++14 (около года пишу так).
от безумных аппаратных косяков в процах

В самих ядрах косяков либо нет совсем, либо их не много. А вот периферия… Да.
ошибок монтажа…

С опытом такие вещи достаточно быстро раскрываются. Особенно если монтаж осуществлял не ты сам.
Лично мне нравится под МК программировать. Как только ты доходишь до понимания того, что твоего кода 5-10 кб, а остальное библиотеки и ты закидываешь их в отдельное место и больше почти не шьешь, то прошивка занимает не более 2-3 секунд. Очень удобно. А остальные 200 кб BSP лежат себе тихонько в конце flash и все. Как-нибудь напишу статью на эту тему. Как организовать это правильно. Есть подводные камни.
За статью спасибо. Приятно было почитать. Однако именно так я врят ли буду вопрос. Все же я когда-то давно написал универсальное средство вывода и отладки (да-да, на базе UART-а. Вернее USB-UART-а, но ни суть. Надо кстати задокументировать будет и описать...). Его мне хватает с головой.
Не знал о существовании данного решения. Спасибо за ссылки. Бегло изучил материал. Правда интересно. Однако стоит заметить, что речь все же о XML -> C++. У меня же используется PlanUML. Полноценная оценка плюсов и минусов — отдельная задача. С ходу могу сказать только что изучение PlanUML происходит многократно быстрее чем XML. Но опять же, кому как. Думаю, тут дело вкуса. В будущем подробнее изучу представленный вами материал.
Мое решение позволят просто в кратчайшие сроки решить задачу не потеряв в качестве.
Спасибо за советы. За подробностями проследую в личную беседу, если вы не против.
Она рисуется автоматически с помощью PlantUML (вас интересует первая ссылка на jar файл, в нем указываете путь до папки с файлом с расширением pu и он тут же генерирует png файл рядом с файлом pu). В этом и основное преимущество. Все наглядно и самому не нужно ничего отрисовывать.
Сейчас заметил. Структуру, которую вы оборачиваете в template должна быть объявлена примерно таким образом:
/*
 * Перечень регистров физического порта ввода-вывода.
 */
struct pll_cfg_struct {
    const uint32_t              pllcfg_reg_msk;         // Маска конфигурации PLL целиком.
    const uint32_t              dev_bus_msk;            // Маска регистра RCCCFG (только части с делителями частоты шин).
    const uint32_t              flash_acr_msk;          // Маска всего регистра flash_acr (предсказатель + задержки обращения к Flash).
    const bool                  src;                    // true = HSE, false = HSI
};

Важно подчеркнуть: структура не должна иметь полей volatile! Иначе будет ошибка на подобии:
../ayplayer_clock.h:6:161: error: the type 'const pll_cfg<(EC_RCC_PLL_SOURCE)1, 25u, 240u, (EC_RCC_PLL_P)0, 15u, (EC_RCC_AHB_DIV)0, (EC_RCC_APB1_DIV)5, (EC_RCC_APB2_DIV)4, 3300ul>' of constexpr variable 'pll_max' is not literal

Причем ругаться будет на объект, объявленный так:
const constexpr pll_cfg< EC_RCC_PLL_SOURCE::HSE, 25, 240, EC_RCC_PLL_P::DIV_2, 15, EC_RCC_AHB_DIV::DIV_1, EC_RCC_APB1_DIV::DIV_4, EC_RCC_APB2_DIV::DIV_2, 3300 >pll_max;

Как по мне, это достаточно не очевидно. Т.к. ошибка в структуре, от которой идет наследование (и затем обратный cast).

Второй момент. Если при объявлении объекта написать const класс< параметры шаблона > имя_объекта, а не const constexpr < параметры шаблона > имя_объекта, то со случайной вероятностью при разных компиляциях объект может попадать либо во flash, либо в RAM (причем в RAM с левыми адресами, заполнеными нулями, за пределами bss и data секций...). Над последним долго маял голову const constexpr перед объявлением объекта решает.

Пикчу «для важных переговоров») Спасибо)
Кажется, юзвери начинают что-то подозревать...)))
А статья понравилась. Если всю статью одним предложением, то «если чего-то будет не хватать — говори директору, пусть решение на его совести. Тебя в его (решении) исполнении никто не упрекнет») Хорошая позиция. Мне нравится.
Он предназначен для открытия доступа к методу, когда экземпляр объекта для которого метод вызывается — константный. Без этого модификатора нельзя вызывать методы на константных объектах.
class C {
public:
  void m1() {}
  void m2() const {}
};

C c1;
const C c2;

c1.m1(); // можно
c1.m2(); // можно
c2.m1(); // нельзя, потому что c1 объявлен как const, а m1() - нет
c2.m2(); // можно, потому что c1 объявлен как const и m2() объявлена как const

Пример отсюда (не мой).
Просто, как говорилось в статье, все объекты библиотеки должны будут объявляться как const constexpr (помним, что в C++14 constexpr != const).
Ахахах))) Лол, да) Но, нет. В нулевых, свой велосипед дороже (шука). У автора значительно отличается подход, это раз. У него нет той архитектуры, под которую пишу я, это два. Ну и я мельком глянул реализацию, тот код написан немного с другими приоритетами, еже ли у меня. Моя библиотека пишется в упор на проекты, в которых я собираюсь ее использовать. Об этой библиотеке будет отдельно, когда ее будет не стыдно показать. Пока что хранилище на github-е только с целью дублирования исходников. Никому не советую пока там копаться)
Как-то забыл о нем… Да, в будущих статьях обязательно учту (задействую).
Изучил. Интересный проект. Но он решает немного иную задачу. Он оптимизирует логику доступа к регистрам с целью повышения быстродействия. В моем же случае мне нужно просто получить маски регистров определенных полей регистров. Логика доступа к регистрам (оптимизация и последовательность) это тема уже отдельной статьи. В этой просто было рассказано, как получить маски (константы типа uint32_t) для объектов. А как ими пользоваться, уже дело объекта.
Планируете ли вы добавить в библиотеку такие объекты как: график (по точкам из массива), диаграммы (так же из массива), эквалайзер. Просто я планирую использовать последний в своем проекте. Посмотрев демо-видео конечно пришла очень страшная идея: сделать на каждую «палку» эквалайзера по вертикальному статус-бару, но 100 статус баров (для простого эквалайзера на OLED дисплее) — это очень страшно)))
Одного лишь названия библиотеки хватило, чтобы я обратил на нее свое внимание… Ну это все лирика. Временами на хабре появляются подобные статьи, где люди показывают нечто подобное. Но ваш уровень мне понравился больше. Честно, на код пока не смотрел, но демо понравилось, а так же стиль работы с GUI, похожий на библиотеку QT. Задам вам сейчас несколько «вопросов от новичка»:
1.1 Рассчитана ли библиотека на монохромные экраны? Например, часто применяемые 128x64.
1.2 Имеется ли возможность рисования без буфера для монохромных экранов (в случае их поддержки)?
1.3 Имеется ли возможность выбора между отрисовкой с использование буфера и без него для монохромных экранов (в случае их поддержки)?
2.1 Какого рода требуется драйвер для цветного дисплея? Имеется ввиду, библиотеке рисования просто требуется поставить указатель на нужный пиксель строки/столбца LCD и после передать N пакетов, содержащих в себе цвета пикселей (массив цветов пикселей) из буфера, или будет требоваться по пиксельное обращение к буферу экрана?
2.2 В дополнение к предыдущему вопросу: отрисовка идет сразу готовой сформированной (или формирующийся динамически между передачами) картинки (драйвер просто копирует из буфера мк в буфер LCD) или же отрисовка идет по-элементно: сначала прямоугольник кнопки, потом внутри него текст и т.д.
2.3 Есть ли возможность создать const связанный список на этапе компиляции, а потом просто подставлять нужный список для отрисовки? Например, у меня 3 меню, все положения и т.д. заранее известны. Меняются только значения и такст. Я могу сделать const связанный список, который будет содержать указатели на изменяемые данные (которые будут динамически обновляться при каждой перерисовке)?
Чтобы было более понятно: очень много модулей мк в моих проектах (на CPP), работают на constexpr. Например. При условии, что GPIO никогда не меняют своих настроек в процессе работы (1 линия — 1 режим работы), я использую constexpr функции, которым скармливаю конфигурации каждого вывода, а на выходе получаю просто массив uint32_t переменных, которые в реальном времени (времени выполнения) копирую в выбранные GPIO.
Возможно ли нечто подобное в вашей библиотеке? Например, создаю объект (или структуру) описания одного окна, потом, если нужно, добавляю в него ссылки на другие окна, все это во время компиляции вычисляется и создается const структуры, которыми потом будет оперировать библиотека в реальном времени.
Просто из моего опыта. Чаще всего используют Eclipse на предприятиях (просто из опыта, подробного анализа не проводил). В домашних проектах я лично предпочитаю Qt Creator + самописный мейк + личный API (вместо HAL, написанный под свои нужды, а так же свой стартап и ld). Но вот про тонкую настроку Qt Creator под МК сейчас пишет мой друг. Т.к. он первый, кто рассказал мне, что так тоже можно. В скором времени он опубликует подробный отчет, в котором расскажет, как настроить Qt + gcc + openocd.
А насчет скорости… Компилирует ведь не Eclipse, а gcc. Так что… Но да, он довольно тяжелый. Я не упомянул, кстати говоря, что для тех, у кого много RAM, можно поправить настройки, чтобы Eclipse использовал хотя бы 1 Гб, вместо стандартных, кажется, 256 мб. Эо значительно ускоряет работу.
Цель была получить сборку не для конкретно stm32, а для любого контроллера на базе ARM (Я буду в будущем часто ссылаться на эту статью, разбирая различные контроллеры. Порой даже неизвестных производителей.).
К тому же, хотелось показать, как на самом деле все это работает. Чтобы у человека было ясное представление обо всей подноготной этой сборки.
Статья классная, на мой взгляд. Сам некоторое время писал на ассемблере под STM32F103 и К1986ВЕ92QI (Миландр, но ядро то же). Довольно интересно было. Но сейчас на работе пишем исключительно местными обертками основанными на HAL (таковы правила). Так что производительность иногда очень страдает. Зато читабельность многократно выше. Жду продолжения.
О данном формате слышу впервые. Но погуглил. Интересно. Но, опять же, редкий. Цель у меня, все же, снизить нагрузку на МК как можно сильнее. Т.к. воспроизведение звука может быть не основной задачей. Соответственно нужно еще более простой формат чем xm. О написании легковесного и быстрого драйвера на МК я напишу еще серию статеек (уже начала, можете посмотреть).
Спасибо за ссылку. Посмотрел. Интересно. Очень. Но я все таки закончу начатое и создам собственную программу. Постараюсь реализовать больший функционал, чем там. Своей ссылкой только подогрели интерес) Спасибо.
Спасибо за положительный отзыв.
  1. Стоит отметить, что формат довольно изощренный в силу своей древности: во-первых, big-endian, и, во-вторых, величины переменной длины с 7-битными байтами.
    Я отметил это в статье. Да, это по-началу смущало. Да и не только это… Но описав все тонкости извлечения MIDI в отдельном классе — мы избавили себя от надобности помнить их.
  2. Кстати, что-то не нашел у Вас упоминания про важные мета-события, такие как end-of-track, set tempo и key signature
    По-поводу end-of-track. Данное событие содержит ту же структуру, что и другие мета-события. Так же: время, 0xFF, 0x2F, длинна 0. Так как данной команды нет в списке распознаваемых — мы ее просто считываем как мета-событие (3 байта, включая 0xFF). А учитывая тот факт, что после каждого считанного события мы сверяемся со счетчиком байт блока, то после прочтения данного события счетчик как раз будет равен нулю и мы выйдем из цикла чтения блока.
  3. В свое время тоже пришлось разбираться с MIDI. Использовал вот эту статью: www.muzoborudovanie.ru/articles/midi/midi5.php.
    Спасибо за ссылку, но данная серия статей уже имеется в последнем абзаце (в пункте «Используемые источники»).
  4. set tempo и key signature
    Данные мата-события, как правило, не встречаются в простых нотных произведениях. Но конкретно set tempo иногда встречается и задает тот же темп, который и так указан в заголовке MIDI файла. Пока что не было глюков со сменой темпа в процессе. Впоследствии, конечно, расширю программу и добавлю данные пункты. Как вы могли заметить, я еще не учел команду второго уровня «сбросить все ноты на канале». В подобных MIDI файлах так же редко встречается. Но в будущем обязательно планирую добавить (с данной командой довольно много заморочек, а данная программа будет в итоге лишь основой для следующей статьи о российских микроконтроллерах).
Так же хочу сказать, что в оркестровых произведения «эксклюзивные мета-события» все же используют, так что я обязательно добавлю их игнорирование.
Полностью согласен. Но ради интереса в одной из следующих статей постараюсь использовать в прерывании сначала CMSIS, а потом SPL. В каком-нибудь очень критичном ко времени примере.

Information

Rating
Does not participate
Location
Красноярск, Красноярский край, Россия
Date of birth
Registered
Activity

Specialization

Software Developer, Embedded Software Engineer
Lead
From 250,000 ₽
C++
STM32
Linux
Circuitry
Python
Assembler
Programming microcontrollers
Embedded system
Software development
Object-oriented design