|
|
  |
Библиотеки для STM32 |
|
|
|
Apr 19 2017, 17:43
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 15-07-06
Пользователь №: 18 836

|
Цитата(AHTOXA @ Apr 19 2017, 20:27)  Так уберите. Я понимаю, памяти вам не жалко. Но быстродействие-то вам наверняка не помешает?  Кстати, касательно volatile... Forger, как думаешь что происходит, когда ты в своем классе делаешь так? Код port->MODER &= ~(((UNSIGNED32)0x03) << (pinIndex * 2)); port->MODER |= (((UNSIGNED32)0x01) << (pinIndex * 2)); Компилятор видит, что MODER имеет квалификатор volatile, потому в каждой строке он читает из MODER и потом сохраняет полученное значение обратно. Объедини строки, сэкономишь две команды  Код port->MODER = port->MODER & ~(((UNSIGNED32)0x03) << (pinIndex * 2)) | (((UNSIGNED32)0x01) << (pinIndex * 2));
Сообщение отредактировал Reflector - Apr 19 2017, 17:47
|
|
|
|
|
Apr 19 2017, 17:50
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Цитата(Reflector @ Apr 19 2017, 20:43)  Кстати, касательно volatile... Forger, как думаешь что происходит, когда ты в своем классе делаешь так?.... Я так понимаю, оптимизация для многих тут - это как позавтракать: не поел с утра нормально, весь день на смарку )) Цитата Объедини строки, сэкономишь две команды  Так сильно ухудшается читаемость, а для меня она гораздо важнее ничтожной экономии объема кода (уже повторяюсь). Исходник я выложил, экспериментируйте, дерзайте, выкладывайте тут итоговые результаты.
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Apr 19 2017, 19:06
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Forger @ Apr 19 2017, 22:41)  Чистый код - это прежде всего код, который хорошо понятен для того, кто его пишет и сопровождает. Да. И не всегда его сопровождает тот, кто писал изначально. Цитата(Forger @ Apr 19 2017, 22:41)  Но, если удастся себя переучить под большинство, это будет только на пользу коду. Да. Цитата(Forger @ Apr 19 2017, 22:41)  Убежден, что "общепринятый стандарт" придуман для тех, у кого нет своих правил и стандартов. У меня есть свой стандарт, долго его формировал из чужого кода и книжек. Это не "общепринятый стандарт", это стандарт языка. Цитата(Forger @ Apr 19 2017, 22:41)  Мне ломает глаз эта uint32_t, мне лично удобнее U32 Понятно. То есть, вам не удалось "переучить себя под большинство". Чем же тут гордиться? Цитата(Forger @ Apr 19 2017, 22:41)  Буду рад если найдете баги или еще более лучшие решения, но придирки к оформлению и мелочам предлагаю все же оставить за кадром. Это не мелочи. Вы же сами тут выше в теме много рассуждали о "чистом коде", учили всех, как надо. А когда привели пример - оказалось, что пример ваш - совсем не образчик чистого кода. Вот именно на этом я и хотел акцентировать внимание. А так - конечно, он у вас работает, он вас устраивает, это всё нормально. Но это - не образец чистого кода.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 19 2017, 19:39
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Цитата(AHTOXA @ Apr 19 2017, 22:06)  Да. И не всегда его сопровождает тот, кто писал изначально. Именно, поэтому я сопровождаю код, если его приходится отдавать на сторону, неким readme, где указано что и как именуется в моем коде (см. чуть ниже). Цитата Это не "общепринятый стандарт", это стандарт языка. Не путайте мух с котлетами: некие "стандарты" именования, принятые когда-то негласно в неких библиотеках и Стандарты Языка - абсолютно разные вещи! Ничто не мешает использовать свои типы. Лишь бы все подчинялось некой единой принятой программистом идеологии, а не выглядело, как сборная солянка чужих и своих типов. Именно поэтому для себя я принял четыре простых правила именования: 1) Типы, классы, структуры, перечисления - ColorIndex2) Поля и методы классов/структур, экземпляры классов/структур, методы классов, локальные переменные функций и методов классов - colorIndex, getColorIndex()3) Макросы, замены “магических” чисел, поля перечислений - STARTUP_DELAY_MS4) Элементарные (платформозависимые) типы - UNSIGNED16, FLOAT32 - возможно, буду сокращать такие длинные имена, например: U16, F32 ... но пока это под вопросом. Цитата Чем же тут гордиться? Гордится? Это где ж я озвучивал подобные потребности? Цитата Но это - не образец чистого кода. Где я сказал, что этот кусок кода именно такой? У меня код постоянно эволюционирует. Есть старые куски кода, которые внешне прекрасно выполняют свою функцию, но внутренне содержимое требует допила. Например, код Pin, который я привел выше, именно такой - функционалом я пока что доволен, а внутренне содержание под сомнением. Как дойдут руки до него, допилю.
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Apr 19 2017, 21:33
|
Знающий
   
Группа: Участник
Сообщений: 825
Регистрация: 16-04-15
Из: КЧР, Нижний Архыз
Пользователь №: 86 250

|
Цитата(Forger @ Apr 19 2017, 20:41)  Мне ломает глаз эта uint32_t Хе-хе... Forger, надо тебе букву 't' добавить. И забыть как о страшном сне! Вообще полное деление на нуль!
Сообщение отредактировал Эдди - Apr 19 2017, 21:34
|
|
|
|
|
Apr 19 2017, 21:41
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Forger @ Apr 20 2017, 00:39)  Не путайте мух с котлетами: некие "стандарты" именования, принятые когда-то негласно в неких библиотеках и Стандарты Языка - абсолютно разные вещи! Это не "некие стандарты, принятые в неких библиотеках", а стандартный (прописанный в стандарте языка) заголовок из стандартной (прописанной в стандарте языка) библиотеки. Типы из которого безо всяких дополнительных readme понятны всем программистам. То, что вы используете вместо этих стандартных типов какие-то свои - усложняет сопровождение. Вместо int вы тоже что-то используете? А то у него буковки маленькие, не вписывается в ваш способ наименования  Цитата(Forger @ Apr 20 2017, 00:39)  Где я сказал, что этот кусок кода именно такой? Ну, это подразумевалось. После стольких лекций про чистый код вы выкатили пример. Или это был "антипример", и я просто не понял идеи? Цитата(Forger @ Apr 20 2017, 00:39)  Например, код Pin, который я привел выше, именно такой - функционалом я пока что доволен, а внутренне содержание под сомнением. Это слабо сказано - "под сомнением". Я бы сказал - так себе код. Очень неоптимальный, с какими-то самопальными типами, с нелогичной иерархией классов.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 19 2017, 21:46
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Цитата Вместо int вы тоже что-то используете? Разумеется! Но причина не в буковках, а в том, что в разных платформах int имеет различную разрядность - в PIC/AVR/STM8 он 16-битный, во ARM - 32-битный Более того, в различных компиляторах по-умолчанию int - знаковый, а в некоторых - нет. float тоже может иметь различную разрядность на разных платформах, поэтому я явно указываю в платформозависимых типах разрядность типа числом, это оказалось очень полезным. выдержка из википедии: Цитата Реальный размер целочисленных типов зависит от реализации. Стандарт лишь оговаривает отношения в размерах между типами и минимальные рамки для каждого типа:
Так long long не должен быть меньше long, который в свою очередь не должен быть меньше int, который в свою очередь не должен быть меньше short. Так как char — наименьший из возможных адресуемых типов, другие типы не могут иметь размер меньше него.
Минимальный размер для char — 8 бит, для short и int — 16 бит, для long — 32 бита, для long long — 64 бита.
Желательно, чтобы тип int был таким целочисленным типом, с которым наиболее эффективно работает процессор. Это позволяет достигать высокой гибкости, например, все типы могут занимать 64 бита. Однако, есть популярные схемы, описывающие размеры целочисленных типов.[7]
На практике это означает, что char занимает 8 бит, иshort 16 бит (также, как и их беззнаковые аналоги). int на большинстве современных платформ занимает 32 бита, а long long 64 бита. Длина long варьируется: для Windows это 32 бита, для UNIX-подобных систем — 64 бита. Цитата Это слабо сказано - "под сомнением". Я бы сказал - так себе код. Очень неоптимальный, с какими-то самопальными типами, с нелогичной иерархией классов. Я не буду спрашивать, что вы понимаете под "нелогичной иерархией классов", уже неинтересно, поэтому отвечу проще - не нравится мой код, пишите по-своему. Мне приходилось пробовать разные решения, и похожее как у вас, но оказалось - не моё. Вам не годится мой подход, мне - ваш. Врядли дальнейшая наша болтовня полемика это как-то изменит  Поэтому предлагаю переключить внимание на что-то другое .... Вот до кучи мои типы данных (платформа ARM Cortex-M) Код typedef unsigned UNSIGNED1; typedef unsigned char UNSIGNED8; typedef unsigned short UNSIGNED16; typedef unsigned int UNSIGNED32; typedef unsigned long long UNSIGNED64; typedef signed char SIGNED8; typedef signed short SIGNED16; typedef signed int SIGNED32; typedef signed long long SIGNED64; typedef float FLOAT32; typedef double FLOAT64; Вот эти макросы считаю очень полезными (макросы применяю крайне редко, вообще, стараюсь их заменять функциями, если это возможно): Код #define MAKE_UNSIGNED32(high,low) ((((UNSIGNED32)high) << 16) + low) #define LOW_UNSIGNED16(unsigned32) ((UNSIGNED16)((UNSIGNED32)(unsigned32) & 0x0000FFFF)) #define HIGH_UNSIGNED16(unsigned32) ((UNSIGNED16)((UNSIGNED32)(unsigned32) >> 16))
#define MAKE_UNSIGNED16(high,low) ((((UNSIGNED16)high) << 8) + low) #define MAKE_SIGNED16(high,low) ((SIGNED16)MAKE_UNSIGNED16(high,low)) #define LOW_UNSIGNED8(unsigned16) ((UNSIGNED8)((UNSIGNED16)(unsigned16) & 0x00FF)) #define HIGH_UNSIGNED8(unsigned16) ((UNSIGNED8)((UNSIGNED16)(unsigned16) >> 8)) Еще раз на всякий случай повторюсь для потомственных "танкистов": не нравится моя реализация, не пользуйтесь, обещаю, что настаивать не буду
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Apr 20 2017, 03:50
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(AHTOXA @ Apr 19 2017, 19:18)  Насчёт быстрее - вряд ли, скорее будет паритет. Насчёт удобнее - всяко. Сравните: Код #define csOn() (GPIOA->BSRR = (1<<4)) #define csOff() (GPIOA->BSRR = (1<< (4 + 16))) #define csCpl() (GPIOA->ODR ^ (1<<4)) vs Код using CS = Pin<'A', 4>; CS::On(); CS::Off(); CS::Cpl(); АНТОХА... не путайте мухи с котлетами.... вы сравниваете определение vs использование. Вот использование vs использование Цитата csOn(); csOff(); //или CS::On(); CS::Off(); при использовании с дефайнами даже объявление не нужно, т.е. нет строки using CS = Pin<'A', 4>; давайте сравним опеределение vs определение Цитата #define csOn() (GPIOA->BSRR = GPIOA_BSRR_BR4) #define csOff() (GPIOA->BSRR = GPIOA_BSRR_BS4) //или ..... 2Forger Цитата Более того, в различных компиляторах по-умолчанию int - знаковый, а в некоторых - нет. пруфлинк? Стандарт строго оговаривает, что int - знаковый. Цитата float тоже может иметь различную разрядность на разных платформах пруф? Стандарт оговаривает 4 байта в формате IEEE754 Цитата Код typedef unsigned UNSIGNED1; wtf? Это bool чтоли? Цитата signed int SIGNED32; я высказывался за свой вкус про всякие SIGNED32, U32.... тут даже не вкус. почему мне не нравиться: если скописастить кусок кода из другово проекта, то не соберётся, нужно тащить до кучи мои типы данных. Это напрегает. в коде могут быть заимствования из 3-х 4-х проектов. получается для каждого стиля до кучи нужно тащить типы данных. В одном проекте можно увидеть весь зоопарк определений. во вторых.... Forger я понял, что для вас литералы - это магические цыфры.... 0x10 или 0b1010110- это что-то плохое, что мешает чтению кода. есть стандартный uint32_t. А использование своих типов взамен стандартных - вы считаете это тру стиль? в третих.... ну даже если там глаз режет uint32_t. вам милее U32. Дело вкуса. Но, у вас в тайпдефе мина. например typedef signed int SIGNED32; вы пишете какойнибудь код.... допусим расчет CRC на ARM. Один раз написал и забыл. Но встала задача посчитать CRC на Atmega. там int не 32. Вы/коллега/ученик перенёс на АВР ваш код... и упс!!! почему бы не определить так? typedef int32_t SIGNED32; Цитата Здорово, но раз есть csOn(), то как минимум должен быть и csOff() естественно.... так же как и в шаблонах/классах Цитата потом захочется записать битик и дополнительно придется делать проверки... чего? Цитата А инициализация, она ведь тоже нужна? Итого сколько всего будет таких макросов для одного пина? я затронул только переключение бита. инит нужен. его можно и функцией, и макросом, можно классом...можно сразу хором весь порт GPIOA проинитить.... это как вам угодно. Я просто хочу сказать, что не нужно думать бинарно.... у вас либо 0, либо 1. Либо С++ с ООП в полный рост безоговорочно.... с оверинженерингом, либо если один макрос или литерал воткнут - то это непрофессионализм. Использование стандартного литерала х и b - это фу фу фу, магическая цифра.... зато SIGNED32 (при чем с миной) - это круть!!!!
|
|
|
|
|
Apr 20 2017, 05:22
|
Профессионал
    
Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882

|
Цитата(juvf @ Apr 20 2017, 08:50)  Либо С++ с ООП в полный рост безоговорочно.... с оверинженерингом, либо если один макрос или литерал воткнут - то это непрофессионализм. Использование стандартного литерала х и b - это фу фу фу, магическая цифра.... зато SIGNED32 (при чем с миной) - это круть!!!! +1 еще я улыбнулся над миной Код class PinBase { public: .... inline void toggle(void) { port->ODR ^= pinMask; } C++ это круто, но про многопоточность мы не слышали.
|
|
|
|
|
Apr 20 2017, 05:57
|
Знающий
   
Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515

|
Цитата(Reflector @ Apr 19 2017, 20:43)  Кстати, касательно volatile... Forger, как думаешь что происходит, когда ты в своем классе делаешь так? Код port->MODER &= ~(((UNSIGNED32)0x03) << (pinIndex * 2)); port->MODER |= (((UNSIGNED32)0x01) << (pinIndex * 2)); Компилятор видит, что MODER имеет квалификатор volatile, потому в каждой строке он читает из MODER и потом сохраняет полученное значение обратно. Объедини строки, сэкономишь две команды  Код port->MODER = port->MODER & ~(((UNSIGNED32)0x03) << (pinIndex * 2)) | (((UNSIGNED32)0x01) << (pinIndex * 2)); Независимо от читабельности и эффективности первый вариант крайне не рекомендуется к использованию, так как он порождает промежуточные состояния аппаратуры, каждое из которых должно быть тщательно проверено на отсутствие побочных эффектов. В процитированном примере возможен следующий сценарий: некий пин переключается между режимами output и alternate. Первый вариант на некоторое время поставит пин в input mode. Если между двумя записями в MODER произойдёт прерывание, то пин зависнет в input mode надолго, и подтяжка может переключить его в неожиданное для разработчика состояние - здравствуй, трудноуловимый глюк! Кстати, в стандартном HAL такого ляпа с MODER нет.
|
|
|
|
|
Apr 20 2017, 06:14
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Цитата(Alechek @ Apr 20 2017, 08:22)  +1 еще я улыбнулся над миной Код class PinBase { public: .... inline void toggle(void) { port->ODR ^= pinMask; } C++ это круто, но про многопоточность мы не слышали. А вот я слышал и не по наслышке, т. к. практически везде, где используется с++, у меня стоит rtos. Что по-вашему в этом куске кода не так? Цитата(AHTOXA @ Apr 20 2017, 09:08)  Ну это всё, приплыли. Это было сделано для обозначения битовых полей различной ширины в структурах, осталось в наследство, в настоящее время практически не используется.
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Apr 20 2017, 06:16
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(juvf @ Apr 20 2017, 08:50)  давайте сравним опеределение vs определение Вот определение vs определение: Код #define csOn() (GPIOA->BSRR = (1<<4)) #define csOff() (GPIOA->BSRR = (1<< (4 + 16))) // или using CS = Pin<'A', 4>; Вот использование vs использование: Код csOn(); csOff(); //или CS::On(); CS::Off();
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 20 2017, 06:22
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Цитата(juvf @ Apr 20 2017, 06:50)  пруфлинк? Все было указано выше. Читайте внимательнее. Цитата Стандарт строго оговаривает, что int - знаковый. пруф? Стандарт оговаривает 4 байта в формате IEEE754 По факту все иначе, читайте внимательнее. Цитата wtf? Это bool чтоли? НЕТ, читайте стандарт. Цитата почему бы не определить так? typedef int32_t SIGNED32; Потому что в самом голом компиляторе нет такого типа, он создан в виде одного из typedef в одном из библиотечных инклклудов. Т.е. нужно еще и подключать некий библиотечный файл, где этот тип описан. В целом это все придирки.
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Apr 20 2017, 06:36
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(AHTOXA @ Apr 20 2017, 11:16)  Вот определение vs определение: Код #define csOn() (GPIOA->BSRR = (1<<4)) #define csOff() (GPIOA->BSRR = (1<< (4 + 16))) // или using CS = Pin<'A', 4>; где определение шаблона Pin<>? ещё 100500 строк!!! Цитата Что по-вашему в этом куске кода не так? ну вы не видите, что ваш тогл, при "одновременном" переключении разных бит, в одном порте из разных потоков не будет работать? Цитата(Forger @ Apr 20 2017, 11:22)  Потому что в самом голом компиляторе нет такого типа, он создан в виде одного из typedef в одном из библиотечных инклклудов. Т.е. нужно еще и подключать некий библиотечный файл, где этот тип описан. В целом это все придирки. Т.е. вы не оспариваете что у вас мина в коде, вам предлагают её разминировать, на что ответ - это придирки. ))) Профессиональный подход, чистый код, легкочитаемый и переносимый .... ну ну .. ))) Цитата читайте внимательнее. 225 постов.... не увидел где была ссылка или упоминание на стандарт, в котором int беззнаковый. Не могли бы вы меня ткнуть носом, плииз.... приходится унижаться, чтоб получить знания, ДОЖИЛИ!!!И о каком стандарте вы говорите, в котором всё иначе? может мы на разных языках пишем? Я думал мы тут делимся опытом, а не писками меримся. Просто отказ подкрепить свои слова пруфлинком выглядит как пустые слова... у меня длиньше, но я не покажу
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|