Страница 50 из 82

Re: Stm32 с чего начать изучение...

Добавлено: Вс авг 10, 2025 11:50:58
КотПротон
Я имел ввиду не какие-то конкретные решения, не правильность/неправильность работы с периферией микроконтроллера или окружения, а общие принципы построения, структуру кода.
Некоторые несложные принципы я изложил ранее. Это не только мое мнение, это мнение множества грамотных, образованных программистов, которые не только умеют битики в регистрах щелкать. Эти и другие принципы изложены в книгах и учебниках, обсуждаются на тренировочных задачах (кейсах).

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

Принцип единственной ответственности - программный модуль (класс, функция) затрагивает только то, для чего предназначен.
Для примера, функция WritePort(data) не должна делать ничего, кроме записи в выходной порт переменной data. Она не должна вызывать внутри себя никаких там Dma, никаких посторонних обращений к какой-то PingMain(). Если такие обращения нужны по алгоритму работы, то сделайте эти вызовы ВНЕ функции WritePort(). Если нужны какие-то доп.условия выполнения, запишите их вне функции. Если нужны вычисления посторонних переменных, вычислите их снаружи.
С другой стороны, если для записи в порт нужно прибегнуть к помощи иных функций, таких как WritePin(value), то эти функции могут вызываться, поскольку цель у них та же самая. Так же внутри WritePort(data) можно например разложить переменную data побитно для WritePin(value). Это нормально. Но НЕ нормально накладывать посторонние условия и вычисления, типа if(data==3) PingMain() и тому подобное.
И тогда это функцию вы сможете использовать в другом проекте или даже в другом контексте этого же проекта.
В показанном ранее примере кода нарушен принцип единственной ответственности, поэтому я и написал, что сиё поделие пишется либо новичками, либо безграмотными погромистами, которые просто ничего не знают.

Есть другие принципы, они чуть более сложные и они ближе к объектно-ориентированному программированию.

Re: Stm32 с чего начать изучение...

Добавлено: Вс авг 10, 2025 12:31:14
Just_Fluffy
КотПротон, ну, я в микроконтроллерах вообще предпочитаю отделение мух от котлет, хоть это и более расточительно (иногда) для размера программы.
Все взаимодействие с периферией я стараюсь вынести в отдельный модуль. Из которого наружу торчат интерфейсы уже не уровня "записать бит в порт Х", а "отправить N байт в дисплей", "получить состояние кнопок"...
А уже как подключены кнопки, дисплей и т.д. никого не волнует. Делить отправку данных в дисплей на отдельные под-функции - не вижу смысла. Под капотом - 2 функции - инициализация периферии, обслуживающей дисплей - GPIO/SPI/I2C/DMA, и отправка данных - засылка массива в дисплей. Причем, как это будет, DMA, блокирующий цикл, отправка по байту из буфера по таймеру - дело внутреннее, в основной программе это не должно быть видно и должно быть без разницы. Я отправила из основной программы блок данных и должна забыть, как оно там дальше... Точно так же опрос кнопок - не волнует, как они подключены, на выходе я должна получить их состояние. Если в основной программе что то таймерное - то в модуль железа должна быть передана коллбек-функция... И никаких обработчиков прерываний в основной программе. Либо флаги, либо коллбеки.

Это позволяет легко мигрировать проекты между разными МК и даже между разными семействами. И делать реюз кода в других проектах.

Ну и в основной программе тоже нужно все структурировать. Но в МК несколько сложнее, нежели на ПК. Событийность нужно делать ручками.
И, по большому счету , получается либо один большой суперцикл, в котором или структурно, или отдельными функциями реализован функционал, либо какой то менеджер очереди событий с обработчиками.
Ну или накатывать какую то RTOS, которая на себя возьмет всю "борьбу под одеялом".... Но зачастую RTOS - несколько расточительно, особенно для мелких МК.

Но вот такой подход может увеличить объем кода - те же коллбеки, например.... Но удобство написания/отладки - несоизмеримо выше. (Сейчас из темы про АВРки прибегут взрослые люди и скажут, что простым переписыванием сишного кода на ассемблере они добились оптимизации размера в 270%.... Вот только в том асме, скорее всего, сам черт ногу сломит...)

Re: Stm32 с чего начать изучение...

Добавлено: Вс авг 10, 2025 13:02:32
КотПротон
При включении оптимизации -O3 исключаются излишние вызовы функций, заменяясь на непосредственное встраивание кода функций. Код ускоряется в несколько раз при сохранении структурированности исходника. И не надо писать ничего на ассемблере.
Под капотом - 2 функции - инициализация периферии, обслуживающей дисплей - GPIO/SPI/I2C/DMA,
Если по правилам, то в функции работы с дисплеем не должно быть функции инициализации GPIO/SPI/I2C. Почему? Да потому, что например на один физический I2C можно повесить несколько самых разных устройств, это нормально. (На один SPI так же можно повесить разные устройства, снабдив разными CS каждое).
А у вас инит I2C зависит от дисплея. Нелогично. Либо писать один и тот же инит I2C и в дисплее, и во всех остальных устройствах, либо обращаться к иниту дисплея, чтобы настроить I2C, либо просто вынести инит I2C за пределы модуля дисплея. Об этом и говорят приведенные ранее принципы - программный модуль дисплея не должен делать ничего более, кроме как общаться с дисплеем. Настройка интерфейсов ввода/вывода - это не забота модуля дисплея. Ничего не изменится, если настройку I2C и пинов сделать вне модуля дисплея. Зато модуль дисплея станет чище, и другие модули, зависящие от I2C, перестанут зависеть от модуля дисплея.

Задача стоит не столько в "мигрировании" между разными МК, сколько в построении логики взаимодействия на одном МК в рамках одного проекта. И когда логика будет верно выстроена, задача мигрирования и повторного использования кода решится сама собой.
То есть, когда в программном модуле дисплея не будет непосредственно прописан какой-то конкретный I2C, а будет лишь отсылка к функциям модуля интерфейса дисплея, тогда этот модуль дисплея вы можете без изменений перенести на другой микроконтроллер и даже на другой интерфейс - SPI вместо I2C.
На чистом Си это решается чуть хуже, чем на С++ с его шаблонами и абстрактными классами.
Но в МК несколько сложнее, нежели на ПК.
Ничуть! Если из ПК выкинуть операционку с её драйверами, то вы получите оооочень большой микроконтроллер. Однако, разработчики операционки позаботились о программистах прикладного ПО, написав стандартные функции ввода-вывода и установив правила выделения ресурсов в рамках ОС.

Re: Stm32 с чего начать изучение...

Добавлено: Вс авг 10, 2025 13:53:38
КРАМ
[uquote="КотПротон",url="/forum/viewtopic.php?p=4737573#p4737573"]При включении оптимизации -O3 исключаются излишние вызовы функций, заменяясь на непосредственное встраивание кода функций. Код ускоряется в несколько раз при сохранении структурированности исходника.[/uquote]
Даладна...
Без явного inline?

Re: Stm32 с чего начать изучение...

Добавлено: Вс авг 10, 2025 14:15:34
КотПротон
Да точнаааа...

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

int Sum(int a, int b)
{
	return a + b;
}
int main(void)
	volatile int s1 = Sum(2, 3);
	volatile int s2 = Sum(4, 5);
	volatile int s3 = Sum(s1, s2);

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

	volatile int s1 = Sum(2, 3);
 2da:	2205      	movs	r2, #5
	volatile int s2 = Sum(4, 5);
 2dc:	2309      	movs	r3, #9
	volatile int s1 = Sum(2, 3);
 2de:	9201      	str	r2, [sp, #4]
	volatile int s2 = Sum(4, 5);
 2e0:	9302      	str	r3, [sp, #8]
	volatile int s3 = Sum(s1, s2);
 2e2:	9b01      	ldr	r3, [sp, #4]
 2e4:	9a02      	ldr	r2, [sp, #8]
	return a + b;
 2e6:	4413      	add	r3, r2
Константные выражения вообще вычисляются во время компиляции, а для переменных выкинут не имеющий смысла вызов функции.
Решение о встраивании кода или вызове функции принимается компилятором на основе его правил.

Re: Stm32 с чего начать изучение...

Добавлено: Вс авг 10, 2025 15:59:29
Just_Fluffy
КотПротон писал(а):Если по правилам, то в функции работы с дисплеем не должно быть функции инициализации GPIO/SPI/I2C. Почему? Да потому, что например на один физический I2C можно повесить несколько самых разных устройств, это нормально. (На один SPI так же можно повесить разные устройства, снабдив разными CS каждое).
Не, у модуля работы с периферией (условный HAL) один инит на всё. Который дергает иниты каждой периферии. И ясное дело, если SPI или I2C шарится между несколькими периферийными устройствами, то инит у него отдельный... А если еще и разные конфиги, то их смена возможна, например, в функции активации того или иного девайса, перед поднятием CS, например.
Ваша парадигма мне понятна и близка. Я давно стараюсь ее придерживаться.
КотПротон писал(а):При включении оптимизации -O3 исключаются излишние вызовы функций
Да то понятно, что лесенку вызовов компилятор срежет...

Re: Stm32 с чего начать изучение...

Добавлено: Вс авг 10, 2025 18:37:54
sc0rpy
[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4737542#p4737542"]sc0rpy, а про какую мееостанцию речь? Можно ссылочку, глянуть код на предмет читаемости? ну и на станцию посмотреть, мож идеи какие можно будет в копилку отложить...[/uquote]
https://radiokot.ru/forum/viewtopic.php?f=25&t=173058
многіе вещи реализованы отлично, но под свою плату не смог скомпилировать

Добавлено after 3 minutes 34 seconds:
КотПротон, часто в начале пути не видно что на финишэ, а код нужэн вчера. и жыть хочеца сейчас и не только красивыми теориями.

Re: Stm32 с чего начать изучение...

Добавлено: Вс авг 10, 2025 19:24:08
КотПротон
Говнокод (быстрое решение "в лоб") мы все хоть раз писали. Но это - одноразовый код, не предполагающий дальнейшего сопровождения.
А для того, чтобы видеть, что на финише, для этого существует планирование - постановка целей и задач и поиск алгоритмов их решения. И чем больше у программиста есть готового багажа, который ПРАВИЛЬНО написан, с возможностью повторного использования без изменения, тем быстрее программист приходит к цели.

[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4737599#p4737599"]условный HAL[/uquote]
Да это не условный. HAL - Hardware Abstraction Level (Layer) - это совершенно реальный уровень взаимодействия внутри программы, отвечает за работу с хардваром, с железом то есть. И это совершенно нормально.

В представлении STM структурная организация демо-проектов выглядит вот так:
Изображение

Таким образом, функционал работы с дисплеем относится к подуровню BSP, и работает через функционал LL или HAL. STM предлагает два варианта низкоуровневых драйверов - LL и HAL, отсюда и такое задвоение.

Re: Stm32 с чего начать изучение...

Добавлено: Пн авг 11, 2025 07:25:51
КРАМ
[uquote="КотПротон",url="/forum/viewtopic.php?p=4737586#p4737586"]Да точнаааа...[/uquote]
Это фуфло. Синтетический код.
Очевидное подталкивание компилятора примитивной функцией с одним арифметическим выражением. Фактически мимикрия под простейшие функции HAL.

Re: Stm32 с чего начать изучение...

Добавлено: Пн авг 11, 2025 08:21:39
JackSmith
[uquote="КотПротон",url="/forum/viewtopic.php?p=4737573#p4737573"]При включении оптимизации -O3[/uquote]
-O3 никто не пользуется, она нестабильна. это чисто для школьников.

Re: Stm32 с чего начать изучение...

Добавлено: Пн авг 11, 2025 08:45:26
Just_Fluffy
JackSmith писал(а):-O3 никто не пользуется
Я блондинко™, я иногда я пользуюсь.... Когда атмегу8 уже запаяла, а код при -О1 немножко не влазит...
Да, знаю, это неправильная оценка ресурсов и выбор камня..... Но после восьмой меги в таком корпусе у меня следующая есть только мега328 - ее жалко ставить.... их у меня уже мало осталось.... Они еще нормальные, доковидные, по низким ценам куплены...

А под STM-ки таки да, -О1, не приходилось в них код "трамбовать", как в атмеги...

Re: Stm32 с чего начать изучение...

Добавлено: Пн авг 11, 2025 09:09:41
JackSmith
[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4737742#p4737742"]
JackSmith писал(а):-O3 никто не пользуется
Я блондинко™, я иногда я пользуюсь.... Когда атмегу8 уже запаяла, а код при -О1 немножко не влазит.[/uquote]
Чем "-Os" не угодил?

Re: Stm32 с чего начать изучение...

Добавлено: Пн авг 11, 2025 10:29:48
Alex-lab
JackSmith писал(а):-O3 никто не пользуется, она нестабильна.
Откуда такие новости?

Re: Stm32 с чего начать изучение...

Добавлено: Пн авг 11, 2025 11:01:02
JackSmith
Alex-lab, спросите меня еще, почему дважды два четыре.

Re: Stm32 с чего начать изучение...

Добавлено: Пн авг 11, 2025 11:47:01
Alex-lab
JackSmith, я слышал только что отладка под -ОЗ не идет.

Стэковерфлоу говорит, что никаких фундаментальных проблем нет, это байки из прошлого.
На заре gcc (2.8 и т.д.), а также во времена egcs и RedHat 2.96 -O3 иногда был довольно глючным. Но это было более десяти лет назад (пост 2012 года), и -O3 не сильно отличается от других уровней оптимизации (по уровню глючности).

Однако он, как правило, выявляет случаи, когда разработчики полагаются на неопределённое поведение, поскольку более строго следуют правилам языка (языков), и особенно его граничным случаям.

От себя могу сказать, что я уже много лет использую -O3 для разработки программного обеспечения в финансовом секторе и ещё не встречал ни одной ошибки, которая бы отсутствовала при использовании -O2.
https://stackoverflow.com/questions/115 ... erous-in-g

Re: Stm32 с чего начать изучение...

Добавлено: Пн авг 11, 2025 11:59:32
JackSmith
[uquote="Alex-lab",url="/forum/viewtopic.php?p=4737784#p4737784"]JackSmith, я слышал только что отладка под -ОЗ не идет.[/uquote]
для отладки надо собирать с "-Og"

Re: Stm32 с чего начать изучение...

Добавлено: Пн авг 11, 2025 12:06:32
Nranddek
Отладка возможна на всех уровнях оптимизации, другое дело, что можно, например, удивиться невозможности поставить breakpoint - это место может исчезнуть в результате оптимизации. Да и вообще, мне кажется странным отлаживание в одном уровне, а затем его изменить и получить иную версию кода.

Re: Stm32 с чего начать изучение...

Добавлено: Пн авг 11, 2025 12:37:38
JackSmith
https://developer.arm.com/documentation ... ion-levels
The default optimization level is -O2.
странно, что на сайте arm рекомендуют использовать "-O2", вместо "прогрессивного -O3", да?

в качестве эксперимента, собрал USB CDC драйвер для F1 с "-O3", и он даже работал, но прошивка весила 8 КБ вместо 7 КБ при сборке с флагом "-Os".
я в свое время дизассемблировал код получаемый с "-O2" и "-Os", и решил для себя что последний дает самый лучший результат.
но какбы не навязываю.

Re: Stm32 с чего начать изучение...

Добавлено: Пн авг 11, 2025 12:50:32
Alex-lab
JackSmith писал(а):с "-O3", и он даже работал, но прошивка весила 8 КБ вместо 7 КБ
Так и должно быть, вызовы заменяются инлайном, что в некоторых случаях, позволяет повысить быстродействие. Никакого криминала тут нет.
JackSmith писал(а):на сайте arm рекомендуют использовать "-O2", вместо "прогрессивного -O3", да?
Да вроде нет? Только для Отладки, рекомендуется более низкий уровень оптимизации (то что я выше писал), для работы можно использовать любой, подходящий под задачу. Не надо демонизировать -O3. Реальных причин для этого нет. Особенно на МК, особенно в real-time приложениях.
-O3

Maximum optimization. When debugging is enabled, this option typically gives a poor debug view. Arm recommends debugging at lower optimization levels.

Re: Stm32 с чего начать изучение...

Добавлено: Пн авг 11, 2025 14:18:27
КотПротон
Отладка на всем, что отлично от None - работает, но специфисиссськи, и нужно переключить режим "шагания" на Instrucrion Stepping Mode, хотя это не всегда помогает в отладке.
И вообще, я не говорил об отладке при включенной оптимизации. Я говорил о том, что без оптимизации получается весьма медленный код из-за того, что генерируется он "топорно" - что написано, то и делается, без всяких там сокращений.
Отсюда и родился миф, что якобы написание на ассемблере дает лучший код, нежели на С/С++.
Поэтому, рабочий код очень желательно включать на оптимизацию, иначе он будет тормознутым. Конечно, для этого надо знать, как правильно писать, чтобы оптимизация не повыбрасывала всю ту писанину, которую вы так гордо писали :)

PS. Кстати, мало кто знает, но разным файлам и разным функциям можно назначать разные уровни отладки. Это прописывается через флаги компилятора и атрибуты ф-ций.