Как стать автором
Обновить

Комментарии 37

Но нарисовать туда не получится, поскольку функция setDataInGivenPosition хоть и constexpr, но не константная и меняет состояние объекта и вызывать её у самого constexpr объекта нельзя - но это и логично.

Разве эта проблема не решается возвратом буфера через возвращаемое значение, а не через входные параметры?

Да, рисование круга так и сделано в DrawLibrary::DrawCircle. Там входной параметр как раз буфер, но всё должно быть в самом constexpr обьекте. Т. Е нельзя создать буфер вне такого объекта и передать функцию объекта. Он должен быть частью этого объекта.

Я это к тому, что если буфер не принимать по ссылке в DrawLibrary::DrawCircle, а вместо этого создать его в автоматической памяти внутри функции, он не будет константным и вы сможете его модифицировать, передав по ссылке в setDataInGivenPosition

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

Да согласен. Уже не помню зачем, так сделано было.

P. S. Вспомнил, это же буфер иконки, она должна быть доступна для отрисовки. Общий метод рисования иконок подразумевает, что в метод передастся иконка, у которой есть свой буфер. Некоторые иконки трудно нарисовать математическими функциями и они всё таки генерятся из внешних тулов в массив. Но функция рисования иконок одна и ей нужен этот константный массив, в который уже ничего рисовать не надо.

Но с рисованием круга согласен, надо убрать внутрь.

Кажется что без-знаковые тут только мешают. Какой правильный вариант в итоге я так и не понял :)

Да, все верно, правильно сразу задать x и y знаковые. Беззнаковые нужны только при установке точки в буфере, но только надо быть уверенным, что они беззнаковые - это как раз IAR компилятор и на этапе компиляции constexpr объекта отлавливает, потому что такое скомпилировать не может.

Теоретически оно конечно прикольно, спору нет.

Но на практике генерировать более-менее сложные статические данные удобнее и проще внешней программой. Вызывать ее можно в make, или в скрипте сборки.

Хотя мне часто в си для полного счастья в не хватало прагмы для вставки вывода внешней программы в компилируемый текст.

Согласен, внешние генерилки хорошая вещь, главное, чтобы генерила все правильно без всяких закладок и в нужном формате. Вот в С++ 20 завезут consteval, возможно чисто теоретически можно будет лазить к ресурсам в проекте (например в bmp файл) на этапе компиляции и самому оттуда вытаскивать все.

consteval уже есть, но файлы афаик читать всё равно нельзя.

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

У меня подход с генерацией или конвертацией имеющихся данных на этапе компиляции используется во множестве мест, от форматирования текста до компиляции программ на ассме для модулей PIO входящих в состав Raspberry Pi Pico. Более удобная генерация при помощи внешних программ - это про какие-то исключительные случаи, лично я избавился от всех своих скриптов на C# которыми что-то генерил раньше.

Таблицу синусов для табличных вычислений, или битмапы из jpeg вы как делаете?

И как вы делаете это кроссплатформенно и независимо от IDE?

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

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

Таблицы синусов генерятся элементарно, любого размера и точности, примерно как и круг в данной статье рисуется, т.е. будет класс с constexpr конструктором внутри которого массив и из конструктора вызываются constexpr методы заполняющие этот массив, который в итоге оказывается во флеше. Генерация битмапов из jpeg - это все же не совсем то, тут нужны достаточно сложные утилиты которые обычно уже существуют и писать их аналоги на С++ не имеет смысла, хотя легко можно представить, допустим, шрифт в виде массива в неком промежуточном формате, при этом можно указать компилятору, что хочу этот шрифт увеличенный вдвое, повернутый на 90гр., с обрезанными пустыми полями, кодировка чтоб была КОИ-8 и вот строка с текстом, найди в ней все уникальные символы и добавляй только их. Не так и сложно такое написать, явно проще компилятора. Но таблица синусов более показательный пример, потому что обычно генерятся разного рода таблицы и тогда проще написать класс на С++ который будет частью проекта, чем написать его на другом языке и таскать вместе с проектом.

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

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

Э-э-э, а внешние утилиты — они тоже платформонезависимы? Да ещё и сборка без проблем на любой платформе идёт?

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

Под target, всё-равно, нужно собирать кросс-компилятором. Это позволяет на host собрать в staging всё, что нужно, пропатчить исходники таблицами/константами и т.п.

Конечно, если у вас утилита не собирается в вашей рабочей системе — это проблема. Но тут уже не до проблем с другими платформами.

По большей части да. Или это генератор каких то специфичных таблиц к которому тут же есть исходники для генератора. Очень часто это скрипт + линуксовые утилиты, тогда в винде через Cygwin. Всякие сложные аудио-видео конверторы и кодеки я делаю на QT, т. е. оно тоже кроссплатформенно средствами QT. Довольно часто текстовые, или cvs, или xml файлы которые нужно как то обработать и преобразовать.

Но признаюсь, есть и непереносимые. Это мутные-старинные, и-или написаные на экзотичных языках,типа фортрана. Сделать их кроссплатформенными можно только полностью их переписав.

Полагаю, половину, если не больше, можно переработать и в предлагаемом тут стиле. Но я тут следую первому правилу программиста - "работает, не трогай!"

Что бы гарантировано без закладок, можно и генерилки собирать в рамках того же проекта из исходников.

У меня простой вопрос. Чем вообще хорош компилятор от IAR? Чем он лучше GCC и Keil?

Насколь я понимаю, осталось два вида компиляторов, Clang и GCC. И всё остальные компиляторы это просто надстройки, возможно со своей реализацией стандартной библитнки и всяких там доп фич и возможностями оптимизации т. Д.

IAR начиная с 8 версии основан на Clang, со всеми вытекающими. Основное его преимущество, наличие Functional Safety версии

https://www.iar.com/safety

Что даёт возможность его использования для разработки Functional Safety устройств.

Насчёт более безопасен, не знаю. По моему опыту, что IAR 8.40.2, что IAR 8.40.3FS генерят абсолютно одинаковый код и имеют абсолютно одинаковые баги.

Но без сертифицированного компилятора, вы не сможете получить сертификат безопасности для устройства для которого вы пишите софт. А таких я знаю пока только два: IAR и Green Hill

https://www.ghs.com/products/compiler.html

Он аж на SIL4 сертифицирован.

По тексту можно подумать, что ошибка с переполнением в коде с Википедии. Но это не так, там вообще не указан размер буфера куда рисовать. И исправление тоже странное, при уменьшении радиуса на 1 слева и вверху, либо справа и внизу, останутся пустые полоски в 1 пиксель. А по честному, нужно либо рисовать в буфер нечетного размера 2R+1 x 2R+1, либо рисовать окружность нецелого радиуса в точку с нецелыми координатами, чтобы она красиво легла в квадрат с четной стороной.

Да там действительно будет 1 пиксель пустых полосок, я написал, что это самое быстрое :), чтобы показать, что ошибка переполнения ушла.

НЛО прилетело и опубликовало эту надпись здесь

Про span ещё не читал, C++20 пока в embedded нет. У меня вопрос.

Разумеется, где-то будет операция обращения к элементу по-индексу (operator[]), логику которого следует изменить, чтоб при обращении к несуществующему индексу было исключение, возврат ошибки, static_assert наконец

Кидать исключения в ембед не принято, слишком накладно, проверять выход за границу каждый раз при обращении тоже, а вот про static_assert не понял. Если, я индекс передаю как параметр оператора, то значит предполагается, что этот индекс можно передаваться не только в compile-time, но и runtime и значит static_assert там не проканает. Я же хочу использовать свой буфер в любом времени исполнении.

Идея, описанная здесь заключается в том, что мы можем с имитировать рантайм поведение объекта в компайлтам, и проверить это на этапе компиляции. Ну скажем так, возможно это похоже на контракты, которые проверяются в компайлтам тайме.

C++20 пока в embedded нет

немцы в Segger Embedded studio завезли поддержку, что странно. Так как они вроде делают свою "реплику" arm-toolchain (версию свою ставят поверх оригинальной, хотя может и правят что-то).

обидно только то, что стандартную либу завезли только под clang.

Не знаю как сейчас, но последний раз я ковырялся в SES 2 года назад и тогда там даже банального std::array и трейтов из С++11 не было, более того разрабы на форуме писали, что все эти stl отнюдь не приоритетное направление... В то же время до конца года должен выйти gcc 11 для ARM, а бетка gcc 10 с неплохой поддержкой С++20 еще в начале лета прошлого года была.

На wiki написано, что C++ library добавила хедеры для exception, new, typeinfo, плюс обертки типа cmath для math.h. Я даже не поленился и установил SES, скачал ARM libcxx library и действительно хедеры для exception, new и typeinfo видит, а array, functional, type_traits и другие уже нет. И это типа прогресс, потому что STLport который использовался до этого был еще хуже. Ну и сама IDE похоже не особо поменялась, даже чтобы переименовать main.c в main.cpp мне пришлось удалять его из проекта, переименовывать вручную и добавлять заново...

а array, functional, type_traits и другие уже нет.

#include <stdio.h>
#include <stdlib.h>

#include <array>
using namespace std;

array<int, 8> testArray;

int main(void) {

  testArray.at(0) = 0;
  testArray[5] = 7;

  for(;;){
  }
}

в опциях проекта вкладка "Libraries" нужно включить "libcxx Library". просто это такой очевидный факт (на самом деле нет).

Ну и сама IDE похоже не особо поменялась, даже чтобы переименовать main.c в main.cpp мне пришлось удалять его из проекта, переименовывать вручную и добавлять заново...

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

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

держит на ней только бесплатная лицензия под NRF и легаси проекты.

Понятно, так действительно работает, но вообще странно, что нужно дополнительно указывать, что хочешь использовать основную стандартную библиотеку, ведь STLport теперь легаси. А RTT у меня класс в одном файле и копируется он в новый проект вместе с десятками других подобных файлов, одним каталогом, так что сишная либа RTT в С++ проекте еще и со своим отдельным форматированием - это сомнительное преимущество. И лично меня раздражают стартапы на ассме, зачем тащить целых три ассм файла в проекты на ARM, когда на C/C++ можно сделать то же самое, но гораздо проще...

 И лично меня раздражают стартапы на ассме, зачем тащить целых три ассм файла в проекты на ARM, когда на C/C++ можно сделать то же самое, но гораздо проще...

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

 А RTT у меня класс в одном файле и копируется он в новый проект вместе с десятками других подобных файлов, одним каталогом,

пока ещё не оброс подобным добром, а хочется)

когда на C/C++ можно сделать то же самое, но гораздо проще...

у меня эти вопросы возникают как претензия к HALам. Да и тот же CMSIS, и либы к нему, вполне можно было бы перевести на ++

Интересная технология, спасибо. А нет ли возможности совсем избавиться от буфера в ОЗУ? В приведенном коде всегда создается буфер на стеке, куда копируется сгенерированное при компиляции изображение.

Ну если у вас строго статический буфер, то да. Вы можете не копировать сгенерированное изображение, а сразу выводить его, например передав указатель на буфер в ПЗУ в DMA

Действительно, при статическом буфере memcpy не вызывается, а обращение к буферу заменяется на загрузку заранее подсчитанного значения.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории