Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Re: Литература для stm32

Ср май 18, 2022 18:35:57

Это обсуждение я, видимо, пропустил. Хотя stm32 ведь равнодушна к выравниванию, разве нет?
В линейке микроконтроллеров STM32 применяются ядра Cortex M0, M0+, M3, M4F, M7 - это из того что я знаю. Младшенькие из них невыровненый доступ не поддерживают вообще. И даже у тех которые поддерживают есть инструкции, которые не поддерживают (коряво сказано, но оно так и есть). Теперь накладываем на это дело разные компиляторы (GCC, IAR, ARMClang) и у каждого куча уровней оптимизации. Получается несчитанное количество комбинаций. Поверь, это не мои фантазии, я получал Hard Fault по невыровненому доступу на Cortex-M4F.

Или там просто потеря скорости?
Дело не в скорости. Данный макрос просто не даст компилятору в этом месте применить опасную инструкцию доступа к памяти.

Начиная с какого количества ног это становится выгоднее?
Смотря с чем сравнивать. С моим кодом уже на одном пине разница может быть. C HAL-ом не знаю, никогда не было желания исследовать его.
Последний раз редактировалось VladislavS Ср май 18, 2022 18:37:59, всего редактировалось 1 раз.

Re: Литература для stm32

Ср май 18, 2022 18:37:23

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

:)))) И как раз в вашем случае из C++ взята только возможность прямой двоичной записи числа.
То есть, вот я например на память не помню, как в F1 идут биты в CRL(H) регистре - сначала MODE, потом CNF или наоборот, хэзэ. Но зато я помню, что сброс обеих CNF и установка обеих MODE - это пин на выход в ПП-режиме. Так же я против дополнительных дефайнов, еще больше утяжеляющих текст по числу строк. Настройка ног в принципе то выполняется один раз. А если где и требуется переключение режимов по ходу дела, то логичнее тогда уж писать макросы в виде DATAPORT_OUTPUT() и DATAPORT_INPUT(), в которых в одном месте простым коротким текстом выполняется настройка режимов.
То есть, принцип разумной достаточности и непложения (от слова "плодить") сущностей. Принцип "не плодите сущности" - один из основополагающих принципов программирования. То есть, не надо пересказывать своими словами уже ранее придуманную сущность. Это добавляет коду неочевидности, загромождает текст лишними сущностями, создает налет проприетарности, да и в целом уводит от принятого стандарта CMSIS в описании.
А на стадии освоения вообще нужно избегать писать какие-либо долгосрочные библиотеки. По мере наработки опыта изменится взгляд на уже написанное. И вот такие "улучшения" будут просто слишком тяжеловесными. По мере освоения программист упрощает все эти тонны портянок и в конечном счете приходит к самой короткой записи, то есть к тому, что уже было предложено в сопроводительных документах. Там же люди тоже не дураки сидят, и если они разработали микроконтроллер, то именно они лучше всего и знают его работу.

Re: Литература для stm32

Ср май 18, 2022 18:54:52

Вы не представляете какой кайф при программировании ничего не знать о внутреннем устройство GPIO-порта, а просто оперировать стандартными методами и режимами. Особенно, когда в работе их целый зоопарк. Когда вижу на форуме примеры кода с MODER-ами, CNF-ами аж передёргивает.

Re: Литература для stm32

Ср май 18, 2022 19:02:15

Кайф "ничего не знать"? Хм. А я вот например предпочитаю знать даже то, какие транзисторы приводятся в работу в том или ином режиме работы порта. И это например помогло мне в свое время понять, почему в стоп-режиме потребление тока в несколько раз превышало документированные цифры. А всё потому, что не были выключены триггеры шмитта в режиме цифрового входа, и для их отключения нужен режим аналогового входа.

Re: Литература для stm32

Ср май 18, 2022 19:07:59

Не надо передёргивать. "Ничего не знать, когда пользуешься". Пользуешься результатами своего труда. Когда сделано так, чтобы не думать о том что внутри когда тебе это не надо.

Re: Литература для stm32

Ср май 18, 2022 19:21:47

COKPOWEHEU писал(а):Немалым, но не возьмусь сказать, что он обязательно будет больше и сложнее, чем на Си

Меньше, в разы. Проверено на практике. Не забывай про наследование, которое уменьшает дублирование кода.
COKPOWEHEU писал(а):Все-таки отсутствие мощного препроцессора вынуждает либо выдумывать хитрые извращения, либо плевать на эффективность и делать все в рантайме

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

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

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

Re: Литература для stm32

Ср май 18, 2022 19:32:34

Теперь накладываем на это дело разные компиляторы (GCC, IAR, ARMClang) и у каждого куча уровней оптимизации.
Надо будет проверить. Хотя у меня сейчас только L151 под рукой. Но это же "младшее семейство"?
И как раз в вашем случае из C++ взята
Как раз в моем случае С++ нет вообще.
То есть, вот я например на память не помню, как в F1 идут биты в CRL(H) регистре - сначала MODE, потом CNF или наоборот, хэзэ. Но зато я помню, что сброс обеих CNF и установка обеих MODE - это пин на выход в ПП-режиме.
А в L1 деление не "вдоль", а "поперек", вместо разбиения по 8 ног на регистр делят на "режим" и "скорость", MODER и OSPEEDR. И лично я не помню какой режим за что отвечает. Лучше уж писать так, чтобы из текста было понятно, чего ты хочешь добиться, а не какие биты выставить.
А на стадии освоения вообще нужно избегать писать какие-либо долгосрочные библиотеки. По мере наработки опыта изменится взгляд на уже написанное. И вот такие "улучшения" будут просто слишком тяжеловесными. По мере освоения программист упрощает все эти тонны портянок и в конечном счете приходит к самой короткой записи, то есть к тому, что уже было предложено в сопроводительных документах. Там же люди тоже не дураки сидят, и если они разработали микроконтроллер, то именно они лучше всего и знают его работу.

Вот та библиотека, которая переживет два - три разных контроллера, уже и может использоваться как основная. Примерно поэтому же у меня до сих пор нет библиотек под АЦП или таймеры: не могу найти общий функционал, который бы стоило абстрагировать.
А библиотеки вроде HAL выбывают из этого списка еще на предварительном этапе: слишком сложные.
Кайф "ничего не знать"?
Вероятнее всего, имелось в виду "не держать в голове подробностей". Знать-то, понятное дело, надо. Но если я хочу нарисовать на дисплее линию, я предпочту оперировать функциями рисования точек или областей, но не командами конкретного дисплея, регистрами SPI или поворотом плоскости поляризации жидкими кристаллами.
Меньше, в разы. Проверено на практике. Не забывай про наследование, которое уменьшает дублирование кода.
Не могу ни подтвердить, ни опровергнуть. Я под контроллеры на С++ не писал.
Во-первых, препроцессор никуда в С++ не делся. А, во-вторых, он там и не нужен особо.
Еще раз: в Си нет достаточно удобного препроцессора чтобы реализовывать компил-тайм алгоритмы по-человечески, поэтому приходится извращаться. В С++ такого тоже нет, зато есть constexpr'ы, которые решают ту же задачу, но другим способом. Насколько я понимаю, это позволяет на С++ при должном умении (которого у меня нет) писать более читаемый код, чем на Си. Быстродействия-то там примерно одинакового можно достичь.

Re: Литература для stm32

Ср май 18, 2022 19:49:52

Хотя у меня сейчас только L151 под рукой. Но это же "младшее семейство"?
Насколько помню, L1 это Cortex-M3, то есть "средненькие". На Cortex-M0(M0+) это L0, F0, G0. Но, как раз таки когда знаешь, что контроллер не поддерживает невыровненый доступ, то за такими моментами строже следишь. А тут расслабишься "типа М4F умеет невыровненый" и тут тебе плюха такая хлобысь!

Re: Литература для stm32

Чт май 19, 2022 05:56:14

Быстродействия-то там примерно одинакового можно достичь.
На каком-то небольшом участке кода да. Но в реальном проекте соревноваться с шаблонами и constexpr умумукаешься. Плюсовой код легко пишется в заголовочных файлах, а значит хорошо инлайнится и оптимизируется. Плюсовой код можно инстанцировать под конкретные данные, выбирая оптимальные алгоритмы под них на этапе компиляции. И это будет делать компилятор, а не программист. А компилятор не устаёт.

Вот чтобы далеко не ходить, у тебя есть макрос установки режимов пинов. Давай установим, к примеру, на каком-нибудь PA13 режим Analog для любого контроллера (за исключением F1 серии, там GPIO другой).

1. На православном С. (попросим форумчан поучаствовать в этом процессе).
2. Твоим макросом.
3. На С++. Тут я могу показать листинг от PA13<PinMode::Analog>::mode();

Re: Литература для stm32

Чт май 19, 2022 07:37:23

Дядьки из комитета по стандартизации давно провели сравнения большого количества кода, выполняющего одно и то же, но написанного на С и С++. Можете порыться в Инете, там все подробности есть. Результат таков: программы на С++, в среднем, на 10-20% короче, но расходуют на 10-20% больше ОЗУ. За счёт оптимизации кода под данные при использовании шаблонов разница в скорости лежит в диапазоне 10-150 раз. И вывод дядьки сделали такой, что нет объективных причин отказываться от использования С++ на МК с его ограниченными ресурсами.

Re: Литература для stm32

Чт май 19, 2022 08:33:17

На каком-то небольшом участке кода да. Но в реальном проекте соревноваться с шаблонами и constexpr умумукаешься.
Если пытаться адаптировать плюсовый код под Си - да. Но такой задачи ведь не стоит. Я не мыслю в терминах С++, соответственно и костылить тамошний подход нужды нет. А на Си подход другой, и описанных вами проблем не возникает.
Давай установим, к примеру, на каком-нибудь PA13 режим Analog для любого контроллера (за исключением F1 серии, там GPIO другой).

1. На православном С. (попросим форумчан поучаствовать в этом процессе).
2. Твоим макросом.
3. На С++. Тут я могу показать листинг от PA13<PinMode::Analog>::mode();

1. Лично в моем случае будет то же, что 2 - либо макросом, либо тем, во что он разворачивается. Я ведь его именно так и писал - сворачивал обычный код.
2.
Код:
#define ADC_IN  A,13,8,GPIO_ADC
GPIO_config( ADC_IN );

Разворачивается это в
Код:
#define GPIO_ADC 0b0000
#define mode GPIO_ADC
do{
  uint32_t temp = GPIO ## A -> CR ## H; //для тех, кто не знаком с препроцессором, ## это объединение строк, то есть GPIO ## A превращается в GPIOA
  temp &=~(0b1111<<(((13-8)&0x07)*4));
  temp |= ( mode <<(((13-8)&0x07)*4));
  GPIO ## A -> CR ## H = temp;
}while(0);

Немного причесал код и выкинул лишние подстановки, но оставил общую суть.
3. Вам бы тоже не помешало показать во что разворачивается ваш шаблон.
4. Еще ждем от форумчан реализации на HAL, CMSIS и тот код, который из него получается - вызовы функций и т.п.
И вывод дядьки сделали такой, что нет объективных причин отказываться от использования С++ на МК с его ограниченными ресурсами.
Именно с этим никто не спорит, хотя бы потому, что на С++ почти всегда можно компилировать напрямую Си-шный код. То есть на С++ достичь ровной той же производительности, что на Си можно просто по определению.
Но вот дальше начинаются сложности, поскольку фичи С++ могут упрощать код (constexpr), усложнять (полиморфизм), могут делать и то и другое одновременно (наследование, шаблоны). Соответственно, и знаний языка и специфики его применения в МК, требуется гораздо больше, чтобы хотя бы не навредить.
Тут даже фанатичный Эдди признает, что С++ учить надо, там действительно есть фичи, упрощающие код. Вот только предпочитает оставить это дело молодым. Но, заметьте, таки пропагандирует, а не отговаривает.
Ну а лично мне просто не нравится переусложненность С++. Туда напихали слишком много и бессистемно. Но, может, и придется его осваивать. Посмотрим.

Re: Литература для stm32

Чт май 19, 2022 09:25:52

Разворачивается это в
Ну я же просил не F1. Какой интерес с его одним регистром?

Добавлено after 44 minutes 8 seconds:
Немного причесал код и выкинул лишние подстановки, но оставил общую суть.
3. Вам бы тоже не помешало показать во что разворачивается ваш шаблон.
Хоть это и не так просто, но могу немного причесать, выкинуть лишние инстанциации, но оставить общую суть и показать. Только чуть попозже, иначе это будет большой подсказкой.

Re: Литература для stm32

Чт май 19, 2022 09:42:03

COKPOWEHEU писал(а):Туда напихали слишком много и бессистемно

А зачем этим всем многим пользоваться? Уже наследование и полиморфизм дают очень много для упрощения программирования больших проектов. Я до последнего года писал с оглядкой на возможность сборки проекта под х86-16 с помощью Борланд С++ 5.02, поэтому умышленно избегал использования современных фич С++. Похоже, что 80186/80188 окончательно уйдут от нас, поэтому буду осваивать новые фичи С++, так сказать, не обременённый оглядкой на совместимость со старыми компиляторами.

Re: Литература для stm32

Чт май 19, 2022 10:49:04

А я для удобства работы с GPIO простые макросы накатал. Скажем, для F303:
Код:
// clear MODER: ~GPIO_MODER_MODERXX_Msk, you should AND these
#define MODER_CLR(n)    (~(3<<(n*2)))
// _AI - analog inpt, _O - general output, _AF - alternate function
// these should be OR'ed
#define MODER_I(n)      (0)
#define MODER_O(n)      (1<<(n*2))
#define MODER_AF(n)     (2<<(n*2))
#define MODER_AI(n)     (3<<(n*2))
 
// AFR field: afr - AFR number, pin - pin (0..15)
TRUE_INLINE uint32_t AFRf(uint8_t afr, uint8_t pin){
    if(pin > 7) pin -= 8;
    return (afr << (pin * 4));
}

Например:
Код:
    GPIOA->MODER = (GPIOA->MODER & (MODER_CLR(11) & MODER_CLR(12) & MODER_CLR(15))) |
            (MODER_AF(11) | MODER_AF(12) | MODER_O(15));
    // USB - alternate function 14 @ pins PA11/PA12
    GPIOA->AFR[1] = (GPIOA->AFR[1] & ~(GPIO_AFRH_AFRH3_Msk | GPIO_AFRH_AFRH4_Msk)) |
            AFRf(14, 11) | AFRf(14, 12);

Для F103:
Код:
// MODE:
#define MODE_INPUT      0
#define MODE_NORMAL     1  // 10MHz
#define MODE_SLOW       2  // 2MHz
#define MODE_FAST       3  // 50MHz
// CNF:
#define CNF_ANALOG      (0 << 2)
#define CNF_PPOUTPUT    (0 << 2)
#define CNF_FLINPUT     (1 << 2)
#define CNF_ODOUTPUT    (1 << 2)
#define CNF_PUDINPUT    (2 << 2)
#define CNF_AFPP        (2 << 2)
#define CNF_AFOD        (3 << 2)
 
#define CRL(pin, cnfmode)  ((cnfmode) << (pin*4))
#define CRH(pin, cnfmode)  ((cnfmode) << ((pin-8)*4))

Пример:
Код:
    // Set led as opendrain output
    GPIOC->CRH |= CRH(13, CNF_ODOUTPUT | MODE_SLOW);
    // USB pullup (PA15) - pushpull output
    GPIOA->CRH = CRH(15, CNF_PPOUTPUT | MODE_SLOW);

У F0 все достаточно просто, так что я лишь сделал дополнительные макросы на флаги, чтобы более понятно было (MODER_AI, MODER_O и т.п.), но надо бы переделывать все так же, как под 303: более понятно.

Re: Литература для stm32

Чт май 19, 2022 13:44:15

Ну я же просил не F1. Какой интерес с его одним регистром?

Ну будет MODER + OSPEEDR с масками по 2 бита, не вижу принципиальной разницы.
Лучше свой выхлоп покажите.
Можем еще дизасмом померяться.
А зачем этим всем многим пользоваться?
Как минимум чтобы читать чужой код.
А я для удобства работы с GPIO простые макросы накатал. Скажем, для F303:
Но они же не добавляют абстракции и не упрощают перенос с f0 на f1, f3 и т.д.

Re: Литература для stm32

Чт май 19, 2022 13:59:31

Блин, пасаны, ну вы зарубились с этими пинами, блин. :))) Всё равно, быстрее, чем запись числового значения напрямую или в текстовом виде вы не сделаете. Пины - это не та тема, на которую следует защищать докторскую диссертацию.

Re: Литература для stm32

Чт май 19, 2022 14:05:53

COKPOWEHEU писал(а):Но они же не добавляют абстракции и не упрощают перенос с f0 на f1, f3 и т.д.

Вот-вот. А потом окажется, что для одного пина активный уровень "1", а для другого- "0". А в другом исполнении девайса они могут быть другими. И как вычислять большие логические выражения, когда то "1", то "0"? А ведение логов при изменении уровня на каком-то пине? И как контролировать, что по запарке ты не присваиваешь результат вычисления логического выражения входному сигналу? Я видел макросы на 5 экранов для подобных случаев, но как такое отлаживать и быть уверенным в правильности работы?

Re: Литература для stm32

Чт май 19, 2022 14:28:58

А я для удобства работы с GPIO простые макросы накатал. Скажем, для F303:
Код:
// clear MODER: ~GPIO_MODER_MODERXX_Msk, you should AND these
#define MODER_CLR(n)    (~(3<<(n*2)))
// _AI - analog inpt, _O - general output, _AF - alternate function
// these should be OR'ed
#define MODER_I(n)      (0)
#define MODER_O(n)      (1<<(n*2))
#define MODER_AF(n)     (2<<(n*2))
#define MODER_AI(n)     (3<<(n*2))
Скобки натыканы просто бездумно. :facepalm:
Подумайте что будет с вашими макросами когда например: MODER_O(1 + 2) ?
Правильно писать: #define MODER_O(n) (1<<(n)*2)

PS: И везде одна и та же ошибка.... :dont_know:

Re: Литература для stm32

Чт май 19, 2022 15:13:12

не вижу принципиальной разницы.
Плохо.
Лучше свой выхлоп покажите.
Ну раз остальным слабо. После работы всех классов на этапе компиляции будет вот так
Код:
*((volatile uint8_t *)&GPIOA->MODER+3) |= 3<<2;

Можем еще дизасмом померяться.
А просто листинг посмотреть не судьба? Контроллер G431.
Код:
        LDR.N    R0,??DataTable1_1
        LDRB     R1,[R0, #+0]   
        ORR      R1,R1,#0xC     
        STRB     R1,[R0, #+0] 
           
??DataTable1_1:
        DC32     0x48000003

Re: Литература для stm32

Чт май 19, 2022 15:18:24

Но они же не добавляют абстракции и не упрощают перенос с f0 на f1, f3 и т.д.

Я не собираюсь очередное подобие кала писать. Мне нужно лишь упростить написание и чтение кода.
Подумайте что будет с вашими макросами когда например: MODER_O(1 + 2) ?

Скрипты для такого рукожопия не предназначены.
Ответить