STM32 новичку в ARM что к чему

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="ARV",url="/forum/viewtopic.php?p=3906150#p3906150"]вот убейте - это уже переходит грань... делать брейнфак, чтобы вместо двух строк написать одну?![/uquote]
Их как бы не всегда две получается. Пример настройки режима для 7-ми пинов из твоей FlexMenu:
Спойлер

Код: Выделить всё

if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
  && ( &LCD_RS_PORT == &LCD_DATA0_PORT) && ( &LCD_RW_PORT == &LCD_DATA0_PORT) && (&LCD_E_PORT == &LCD_DATA0_PORT)
  && (LCD_DATA0_PIN == 0 ) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) 
  && (LCD_RS_PIN == 4 ) && (LCD_RW_PIN == 5) && (LCD_E_PIN == 6 ) )
{
    /* configure all port bits as output (all LCD lines on same port) */
    DDR(LCD_DATA0_PORT) |= 0x7F;
}
else if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
       && (LCD_DATA0_PIN == 0 ) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) )
{
    /* configure all port bits as output (all LCD data lines on same port, but control lines on different ports) */
    DDR(LCD_DATA0_PORT) |= 0x0F;
    DDR(LCD_RS_PORT)    |= _BV(LCD_RS_PIN);
    DDR(LCD_RW_PORT)    |= _BV(LCD_RW_PIN);
    DDR(LCD_E_PORT)     |= _BV(LCD_E_PIN);
}
else
{
    /* configure all port bits as output (LCD data and control lines on different ports */
    DDR(LCD_RS_PORT)    |= _BV(LCD_RS_PIN);
    DDR(LCD_RW_PORT)    |= _BV(LCD_RW_PIN);
    DDR(LCD_E_PORT)     |= _BV(LCD_E_PIN);
    DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN);
    DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN);
    DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN);
    DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN);
}
Даже какие-то попытки оптимизации присутствуют, но если из 7-ми пинов 6-ть находятся на одном порту, кроме одного пина данных, то все семь будут иниться отдельно. Для остальных функций получается похожая картина, а в начале еще нужно несколько десятков строк с определением пинов и вспомогательными макросами добавить.
А могла быть одна строка с определением класса, включая все пины, плюс одна строка инициализации всех пинов сразу, перебирающая любые возможные варианты:

Код: Выделить всё

PinList<Data, RS, RW, E>::template mode<PinMode::PushPull>();
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="ARV",url="/forum/viewtopic.php?p=3906162#p3906162"]поэтому написав вот такую вашу свертку-лямбду-ксяу вы будете непрерывно трястись над своим кодом, чтобы не дай бог в новой инкарнации стандарта это не стало вести себя иначе...[/uquote]Это одна из основных задач комитета по стандартизации, чтобы нововведения не поломали старый код. Поверь, если есть хоть малейшая вероятность "сломать", то нововведение не будет принято с вероятностью 99%. За частую, именно это является и основным тормозом в развитии языка.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18789
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Reflector писал(а):Их как бы не всегда две получается.
согласен. но вопрос в том, как две или не две строки воспринимаются: если алгоритм виден, можно понять любому, а если алгоритм скрыт в библиотеке ли, в стандарте ли, в шаблоне ли и т.п. - тобоооольшой вопрос, сможет ли любой профи разобраться. данная дискуссия тому подтверждение: несколько явных профессионалов не могут друг друга понять, чего там говорить о самоучках, вроде меня?! foreach где-то в недрах тоже является простым for, но вот запись с foreach многих вводит в ступор, в отличие от for
Reflector писал(а):из твоей FlexMenu
нет, это из библиотеки Питера Флури (или как он произносится) поддержки ЖКИ
Reflector писал(а):А могла быть одна строка с определением класса
да, могла бы... но если развернуть эту строку - вряд ли получится более понятно, чем в библиотечке Питера...

для меня, в конечном итоге, важно не добиться супероптимального результата по коду, а добиться легкости в написании с предельно сохраняемой понятностью написанного. и вот с понятностью С++-ый вариант пока меня страшит...
VladislavS писал(а):является и основным тормозом в развитии языка
вообще говоря, стандарт - это эквивалент догмы. если стандарт непрерывно меняется, то чем это отличается от отсутствия стандарта?! перфекционизм - это хорошо, но перфекционистов на работу лучше не брать - ни одно дело не будет завершено, любой пустяк будет непрерывно улучшаться...

нет ли у вас статистики, которой можно доверять: сколько в мире всего строк кода написано на С++ разных стандартов? имхо, мне кажется, если вначале "развития" между версиями стандарта были написаны миллиарды строк, то между последними и миллиона не наберется.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

VladislavS писал(а):чем собираешь с какими ключами компиляции? Версию языка бы поднять для начала. Для GCC вот так "-std=gnu++1z".
походу дела проблема с версией
Спойлер

Код: Выделить всё

gcc version 4.8.4 20140725 (release) [ARM/embedded-4_8-branch revision 213147]
Изображение
Что синим выделено на том и пытаюсь проект собирать.
Пробовал выставить -std=gnu++1z - он даже собирать не пытается, какую-то ошибку сразу вываливает.
Реклама
Эиком - электронные компоненты и радиодетали
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="ARV",url="/forum/viewtopic.php?p=3906180#p3906180"]но если развернуть эту строку - вряд ли получится более понятно, чем в библиотечке Питера...[/uquote]Зачем его разворачивать? Это же не макрос! Это функция! Она берёт на вход параметры (пусть даже непривычные для вас) и выполняет над ними действия. Удачное название позволяет не ошибиться в том что функция выполняет. Тот же foreach - "для всех что-то сделать". Выбираешь для "кого" и "что сделать" - вуаля! Для понимания кода даже не надо знать, что это вариативный шаблон.
СпойлерЯ как-то приводил уже этот код от Reflector. Всё просто, к каждому параметру из списка Ts применить функцию f(). Просто же? Да ещё и в constexpr контексте.

Код: Выделить всё

  template <typename F, typename...Ts>
  constexpr void foreach(TypeList<Ts...>, F f) 
  { 
     (f(Ts{}), ...); 
  }
Осталось только передать на вход список параметров "для кого" и лямбду "что сделать" в качестве функции.
Последний раз редактировалось VladislavS Вт окт 13, 2020 16:15:04, всего редактировалось 2 раза.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18789
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

VladislavS писал(а):Зачем его разворачивать?
а зачем Reflector развернул функцию lcd_init()? если не разворачивать, то все лаконично-понятно, аж слеза накатывает :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3906185#p3906185"]походу дела проблема с версией[/uquote]Конечно. Мой пример С++17 хочет. Обновите компилятор.
https://developer.arm.com/tools-and-sof ... /downloads

Добавлено after 1 minute 17 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3906195#p3906195"]
VladislavS писал(а):Зачем его разворачивать?
а зачем Reflector развернул функцию lcd_init()? если не разворачивать, то все лаконично-понятно, аж слеза накатывает :)[/uquote]Затем, что вы внутренности этой функции ручками начирикали, а Reflector вместо неё одну строку написал. Вот и получается, что ему всё равно что внутри, а вам пришлось разворачивать.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18789
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

VladislavS писал(а):Вот и получается, что ему всё равно что внутри, а вам пришлось разворачивать
наоборот: чтобы доказать простоту его кода, ему пришлось разворачивать "мою" функцию. без этого мой вариант выглядит куда лаконичнее :)

зато нет проблемы
VladislavS писал(а):С++17 хочет
так же "мой" вариант понятен даже начинающим. и крайне маловероятно, что спустя 20 лет и 100500 версий стандарта он перестанет собираться.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3906152#p3906152"]Скажем, я сейчас запросто могу скомпилировать сишный код 40-летней давности. И я без проблем пойму, что там написано и при необходимости смогу его изменить. А вот в случае с С++ все совершенно не так! И мало того, что нужно выучить текущую версию С++ (в отличие от С, где достаточно почитать K&R, а потом ради интереса полистать, что там нового в С99, но и без этого легко обойтись), так еще и всегда надо следить за обновлениями![/uquote]Что за глупости? Точно так же можно любой код скомпилировать. На крайний случай есть ключ компилятора, выбирающий поддерживаемый стандарт.

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3906152#p3906152"]Ну нафиг оно нужно? 20 лет назад я выучил С и пишу на нем по сей день. И мне нет нужды читать дебильные стандарты каждые несколько лет, чтобы знать, что там какие-то мудаки нового наворотили![/uquote]Разве этим можно гордиться? Настоящий разработчик всю свою жизнь что-то новое изучает. 20 лет назад AVR-ки были модны, не сидеть же на них до пенсии.

Добавлено after 15 minutes 12 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3906223#p3906223"]наоборот: чтобы доказать простоту его кода, ему пришлось разворачивать "мою" функцию. без этого мой вариант выглядит куда лаконичнее :)[/uquote]Легко поставить вас в равные условия

Код: Выделить всё

void SuperInit() 
{
  // Охрененно_сложный_супер_шаблон<>()
}
И хоть обрыдайся.

[uquote="ARV",url="/forum/viewtopic.php?p=3906223#p3906223"]зато нет проблемы
VladislavS писал(а):С++17 хочет
[/uquote]А в чём проблема? Как минимум, три мэинстримовых компилятора для ARM поддерживают C++17. Хочешь в Keil, хочешь в IAR, хочешь на чём угодно GCC-ном собирай.

[uquote="ARV",url="/forum/viewtopic.php?p=3906223#p3906223"]так же "мой" вариант понятен даже начинающим.[/uquote]Вы код на конкурс начинающих Си-чтецов пишете или чтобы он работал в контроллере?

[uquote="ARV",url="/forum/viewtopic.php?p=3906223#p3906223"]и крайне маловероятно, что спустя 20 лет и 100500 версий стандарта он перестанет собираться.[/uquote]То же самое скажу про код, написанный по стандарту С++17. Нет той силы, которая запретит собрать его через 20 лет.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

VladislavS писал(а):Конечно. Мой пример С++17 хочет. Обновите компилятор.
Обновил, подменил папочки.
Поставил в настройках -std=gnu++1z
Теперь собирает, но с такими предупреждениями
Спойлер

Код: Выделить всё

../system/include/cmsis/cmsis_gcc.h: In function 'uint32_t __get_PSP()':
../system/include/cmsis/cmsis_gcc.h:150:21: warning: ISO C++17 does not allow 'register' storage class specifier [-Wregister]

Код: Выделить всё

../system/include/cmsis/cmsis_gcc.h: In function 'uint32_t __get_MSP()':
../system/include/cmsis/cmsis_gcc.h:175:21: warning: ISO C++17 does not allow 'register' storage class specifier [-Wregister]

Код: Выделить всё

../src/main.cpp:143:9: warning: typedef 'using TestPort = class TSimplePort<1073809408>' locally defined but not used [-Wunused-local-typedefs]
еще раз, куда я это

Код: Выделить всё

using TestPort = TSimplePort<uint32_t(GPIOA_BASE)>;
должен поместить? В основную функцию main или как?
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Dimon456, Файлы CMSIS тоже бы обновить. using TestPort = ... поместить в любом месте, где вы typedef обычно пишете. Это по сути то же самое определение типа. Вызов функции toggle() там где он нужен, хоть в main.
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="ARV",url="/forum/viewtopic.php?p=3906180#p3906180"]согласен. но вопрос в том, как две или не две строки воспринимаются: если алгоритм виден, можно понять любому, а если алгоритм скрыт в библиотеке ли, в стандарте ли, в шаблоне ли и т.п. - тобоооольшой вопрос, сможет ли любой профи разобраться.[/uquote]
Библиотека наоборот должна скрывать детали реализации, наружу торчит только интерфейс из которого должно быть понятно как ей пользоваться, а не как оно там внутри все реализовано. Профи, если нужно, залезет внутрь и разберется, иначе он не профи :)
ARV писал(а):для меня, в конечном итоге, важно не добиться супероптимального результата по коду, а добиться легкости в написании с предельно сохраняемой понятностью написанного. и вот с понятностью С++-ый вариант пока меня страшит...
Столько людей на форумах годами пишут, что С++ не понятный, а что они ради его понимания сделали? Ардуинщики с околонулевыми знаниями пишут на C++, пусть и без шаблонов, а более опытные программисты страшаться. Видимо все дело в неспособности отринуть свой предыдущий опыт программирования, насколько бы порочным он ни был :)
Друг Кота
Аватара пользователя
Сообщения: 3386
Зарегистрирован: Пн окт 11, 2010 19:00:08

Сообщение Мурик »

Dimon456 писал(а):Обновил, подменил папочки.Поставил в настройках -std=gnu++1z
Теперь собирает, но с такими предупреждениями
Нормально все собирается.

Код: Выделить всё

int main(void)
{
    using TestPort = TSimplePort<uint32_t(GPIOA_BASE)>;
    TestPort::toggle();

    while(1)
    {
    }
}

Код: Выделить всё

(43)      using TestPort = TSimplePort<uint32_t(GPIOA_BASE)>;
(44)      TestPort::toggle();
080001E8	ldr	r2, [pc, #8]	; (0x80001f4 <main()+12>)
080001EA	ldr	r3, [r2, #12]
080001EC	mvns	r3, r3
080001EE	str	r3, [r2, #12]

Код: Выделить всё

bin\Release\cpp.map|1|Program size (bytes):     612|
||Data size    (bytes):       8|
||BSS size     (bytes):      28|
||             ----------------|
||Total size   (bytes):     648   (R/W Memory: 36)|
|||
||=== Сборка закончена: 0 errors, 0 warnings (0 minutes, 0 seconds) ===|
Вложения
cpp.zip
(143.94 КБ) 224 скачивания
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

VladislavS писал(а):Вызов функции toggle() там где он нужен, хоть в main.
Исходя из листинга

Код: Выделить всё

using TestPort = TSimplePort<uint32_t(GPIOA_BASE)>;
using TestPort2 = TSimplePort<uint32_t(GPIOA_BASE), (1<<2)>;
using TestPort3 = TSimplePort<uint32_t(GPIOA_BASE), (1<<2)|(1<<1) >;

  TestPort::toggle();
  TestPort2::toggle();
  TestPort3::toggle();
вроде как три раза обратился к функции toggle, потратив на это 14 16 и 12 байт, в отладчике трудно это проследить, не видно откуда он в функцию toggle попадает.

Ну ладно, хорошо, давайте светодиодом поморгаем, развивайте дальше мысль.
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Ну попробуйте аналогично toggle добавить методы set, clear, write. Потом сравним.
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3906226#p3906226"]Точно так же можно любой код скомпилировать. На крайний случай есть ключ компилятора, выбирающий поддерживаемый стандарт.[/uquote]
Зато человеку, изучавшему 20 лет назад С++, невозможно будет понять современные портянки на псевдокрестах! А вот с С все нормально!!!
Настоящий разработчик всю свою жизнь что-то новое изучает. 20 лет назад AVR-ки были модны, не сидеть же на них до пенсии.
Я и изучаю: сейчас вот с пусироботовскими драйверами ШД вожусь. Написал для них управлялку, теперь надо веб-морду на libonion делать (сама библиотека сыровата, пришлось повозиться с нормальной аутентификацией и безопасной работой с веб-сокетами). Ну и параллельно вожусь с будущими роботелескопами. Там вообще еще конь не валялся: пока наблюдаем одну поляну всю ночь, хватает баш-скрипта, но писать еще очень много кода, авось, года через три дойду до планировщика. Думаю идею у Кубанека из его RTS2 спереть, но реализацию придется писать с нуля (у Кубанека на С++ написано - не годится так).
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18789
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Reflector писал(а):Библиотека наоборот должна скрывать детали реализации, наружу торчит только интерфейс из которого должно быть понятно как ей пользоваться, а не как оно там внутри все реализовано.
с точки зрения непрофессионала, никакой разницы между вашим классом-шаблоном или вызовом библиотечной функции нет. что понятнее - то и лучше.
Reflector писал(а):Видимо все дело в неспособности отринуть свой предыдущий опыт программирования, насколько бы порочным он ни был
ну, как бы дело не в неспособности, а в отсутствии мотивации, я уже объяснял это не раз. когда мне потребовались шаблоны в Pascal-е, я достаточно быстро с ними разобрался. во всяком случае в необходимом для моих целей объеме. а вот С++ я даже с базовым синтаксисом не хочу начинать разбираться - слишком все запутанно и неоднозначно, а держать в голове лишнюю информацию - нет мотивации.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

ARV, просто охота сравнить, какие затраты на вызов функции, если ее и так представить и эдак.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18789
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Dimon456 писал(а):просто охота сравнить
это уже сравнивали не один раз: с этими хитрыми классами-шаблонами в среднем получается заметно оптимальнее, чем напишет ручками неуч вроде меня, и лишь совсем чуток хуже, чем профессионал сделает на ассемблере. т.е. овчинка выделки стоит с точки зрения быстродействия и объема кода, но это если выделка вообще не требуется (в смысле - уже есть знание С++ на уровне гуру средней руки).
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3906363#p3906363"]ARV, просто охота сравнить, какие затраты на вызов функции, если ее и так представить и эдак.[/uquote]Когда делаешь шаблонами в том стиле как я показал, то с большой вероятностью вызова функций вовсе не будет. Всё просчитается, оптимизируется и заинлайнится. Это если на скорость оптимизировать. При оптимизации на размер бутут вызовы функций, но такова плата за размер. В любом случае, когда делаешь шаблонами, то намного больше кода находится в одной единице трансляции и самих единиц трансляции меньше получается. Отсюда и степень оптимизации выше, чем при классическом проекте. А если учесть, что эмбэддинг это в основном работа с volatile сущностями, то компилятор связан по рукам и ногам и программисту приходится ему помогать, если хочешь получить хороший результат.
Ответить

Вернуться в «ARM»