-
- #8 Есть объявление teap0t(358 знак., 17.09.2020 09:45)
- Эк вас разбирает. Чувствую, хорошие у меня вопросы. Вон какая куча умников собралась. Это всё код STшных библиотек "STM32L1xx_StdPeriph_Driver" teap0t(727 знак., 17.09.2020 19:33)
- Я конечно не такой спец по сям, как тут присутствуют, но как я
понимаю, !DISABLE будет только в одном случае, который еще, в
добавок ко всему, может зависеть от некоторых сторонних факторов,
которые иногда могут вылезти боком в самых неожиданных случаях.
Согласно булевой парадигмы в сях логично было бы указать, что
ENABLE != DISABLE, тогда ENABLE может иметь любое значение отличное
от DISABLE и в этом случае ваш вопрос по поводу того, что "условие "= !DISABLE" выполняется ir0407(366 знак., 17.09.2020 17:42)
- А вот я тоже инстиктивно не доверяю assert_param, только я бы
написал попроще: enum (DISABLE=0, ENABLE, EN_QTY); #define
IS_VALID_STATE(state) ((uint8_t)state < EN_QTY) - VLLV(17.09.2020 18:01)
- И чему будет равно IS_VALID_STATE(1025)? - йцyкeн(17.09.2020 19:19)
- Ок, unsigned int - VLLV(17.09.2020 20:50)
- Вы все дураки и не лечитесь, один я... #define IS_BOOLEAN(b) ((b)
== !!(b)) - SciFi(17.09.2020 18:06)
- 1) Элегантно-омерзительно 2)boolean это ваще новодел - VLLV(17.09.2020 18:18)
- Boolean -- это слово в английском языке, и оно там было задолго до появления сей. - SciFi(17.09.2020 21:07)
- 1) Элегантно-омерзительно 2)boolean это ваще новодел - VLLV(17.09.2020 18:18)
- И чему будет равно IS_VALID_STATE(1025)? - йцyкeн(17.09.2020 19:19)
- А вот я тоже инстиктивно не доверяю assert_param, только я бы
написал попроще: enum (DISABLE=0, ENABLE, EN_QTY); #define
IS_VALID_STATE(state) ((uint8_t)state < EN_QTY) - VLLV(17.09.2020 18:01)
- Доктор, где вы такие картинки берёте? Сколько лет пишу на C/C++ -
никогда такого не видел. Ну почему не написать {DISABLE = 0, ENABLE
= 1} или {DISABLE = 0, ENABLE}? - йцyкeн(17.09.2020 11:41)
- Это код STшных библиотек "STM32L1xx_StdPeriph_Driver". - teap0t(17.09.2020 19:37)
- Этот код как бы говорит "видишь, не надо меня использовать". - SciFi(17.09.2020 19:49)
- Ну, блин! Это же главное в Си - чужие библиотеки, которые позволяют
всё делать гораздо быстрее. Я в них разбираюсь сейчас, чтобы
привыкнуть к виду сишного текста, оборотам языка, идиомам и т.д. И
положа руку куда-нибудь, а чего плохого-то? Определили базовое
значение и определили условие несоответствия базе, которое будет
работать везде, хотя может отличаться в разных системах. Понятно
как определили, и как проверяют тоже понятно. Нормальный код. Мне
сама идея чужих teap0t(146 знак., 17.09.2020 20:48)
- Давайте отделим мух от котлет. Если библиотека работает, почему бы её не использовать? Но отсюда никак не следует, что полагается учиться языку программирования, глядя в её код. Есть представления о хорошем стиле программирования, которые более-менее совпадают у бывалых товарищей, и эти же бывалые товарищи называют программную продукцию STM индусским говнокодом. - SciFi(17.09.2020 20:58)
- Использовать или нет - тут ещё могут быть разные мнения. Но не зная
бродаязыка Си учиться на примере этих индусов... мазохизм какой-то. - йцyкeн(17.09.2020 20:22)- Выяснение "как неправильно" - это тоже обучение. Этот код работает. Ошибок в нём нет. Предупреждения я исправил (осталось только одно, но там адресная арифметика, которую надо осторожно разбирать). Ошибку в программе исправил. Температуру она теперь кажет правильно. Дальше хочу попробовать без IAR расширений языка. Каждое исправление или ответ на вопрос, закрывающий тему - это шаг вперёд. Приходится же исправлять ошибки. Для этого надо понимать что мне говорит компайлер и т.д teap0t(333 знак., 17.09.2020 20:40)
- Ну, блин! Это же главное в Си - чужие библиотеки, которые позволяют
всё делать гораздо быстрее. Я в них разбираюсь сейчас, чтобы
привыкнуть к виду сишного текста, оборотам языка, идиомам и т.д. И
положа руку куда-нибудь, а чего плохого-то? Определили базовое
значение и определили условие несоответствия базе, которое будет
работать везде, хотя может отличаться в разных системах. Понятно
как определили, и как проверяют тоже понятно. Нормальный код. Мне
сама идея чужих teap0t(146 знак., 17.09.2020 20:48)
- Этот код как бы говорит "видишь, не надо меня использовать". - SciFi(17.09.2020 19:49)
- Я вообще не пойму, зачем DISABLE/ENABLE. Чем не устраивает true/false? "bool megadevice_disabled = true, protection_enabled = false;" - SciFi(17.09.2020 11:58)
- Это код STшных библиотек "STM32L1xx_StdPeriph_Driver". - teap0t(17.09.2020 19:37)
- Лайфхак: !!(что-то) даёт ноль, если (что-то) равно нулю, и единицу в противном случае. - SciFi(17.09.2020 10:58)
- Не правильно. enum - это набор чисел. DISABLE это число 0, !DISABLE
- это тоже какое-то число (компиляторозависимо), предположим (-1).
Тогда проверка превращается в (((STATE) == 0) || ((STATE) ==
(-1))). А тут, очевидно, STATE=2 не пройдет проверку - AlexBi(17.09.2020 10:07)
- Схерали -1? Вообще-то !0 == 1. В остальном справедливо. - SciFi(17.09.2020 10:49)
- (-1) было очень давно, когда еще встроенного типа bool не
существовало, а было только самодельное BOOL. Сейчас согласен,
операция ! применяется к bool, и стандарт требует превращения true
в 1. Т.е. записывая !0 имеем неявное (int)-(bool)-(!)-(int) - AlexBi(17.09.2020 11:14)
- Кстати, операция ! применяется к арифметическим типам (можно и к
float, например) и указателям. Результат этой операции имеет тип
int. Так что не надо нас путать, мы и сами запутаемся. - SciFi(17.09.2020 12:21)
- Мне кажется там идет двойное/тройное преобразование
(что-то)-(int)-(bool)-(! bool)-(int). Т.е. должен подойти любой
тип, умеющий превращаться в int - AlexBi(17.09.2020 12:44)
- Типы преобразовываться могут только один раз. A->B->C...
невозможно. Если А непосредственно не конвертируется в C -- не
заработает. - fk0легенда(17.09.2020 14:58, ссылка)
- Это интересно, но здесь даже нет преобразования. Оператор ! -- это сравнение с нулём, и если аргумент целое, плавучка или указатель, всё это работает немного по-разному. У целого -- простое сравнение с нулём, у плавучки -- сравнение с 0.0 (там уже может играть режим округления и т.п.), у указателя -- сравнение с нулевым указателем (который на какой-нибудь экзотической архитектуре может иметь ненулевое двоичное представление). - SciFi(17.09.2020 18:02)
- Да, я поторопился, встроенный во встроенный должны преобразовываться за один шаг. - AlexBi(17.09.2020 15:56)
- !0.1 == 0, !(int)0.1 == 1. - SciFi(17.09.2020 14:31, ссылка)
- Убедил. Мое представление о bool оказалось не правильным - AlexBi(17.09.2020 16:00)
- Типы преобразовываться могут только один раз. A->B->C...
невозможно. Если А непосредственно не конвертируется в C -- не
заработает. - fk0легенда(17.09.2020 14:58, ссылка)
- Мне кажется там идет двойное/тройное преобразование
(что-то)-(int)-(bool)-(! bool)-(int). Т.е. должен подойти любой
тип, умеющий превращаться в int - AlexBi(17.09.2020 12:44)
- Когда было !0 == -1? Хочу всё знать. - SciFi(17.09.2020 11:22)
- У борланда, из прошлого века. Но могу и ошибаться, давно это было,
почему-то (-1) записалось в моей памяти и всплыло первым. - AlexBi(17.09.2020 12:38)
- (int32t) -1 = 0xFFFFFFFF... - Гyдвинволшебник(17.09.2020 12:45)
- проверил на компиляторе от мелкомягких 89 года !0 == 1. Может еще давнее :) - abivan(17.09.2020 12:14)
- У борланда, из прошлого века. Но могу и ошибаться, давно это было,
почему-то (-1) записалось в моей памяти и всплыло первым. - AlexBi(17.09.2020 12:38)
- Кстати, операция ! применяется к арифметическим типам (можно и к
float, например) и указателям. Результат этой операции имеет тип
int. Так что не надо нас путать, мы и сами запутаемся. - SciFi(17.09.2020 12:21)
- (-1) было очень давно, когда еще встроенного типа bool не
существовало, а было только самодельное BOOL. Сейчас согласен,
операция ! применяется к bool, и стандарт требует превращения true
в 1. Т.е. записывая !0 имеем неявное (int)-(bool)-(!)-(int) - AlexBi(17.09.2020 11:14)
- OK - teap0t(17.09.2020 10:14)
- Схерали -1? Вообще-то !0 == 1. В остальном справедливо. - SciFi(17.09.2020 10:49)
- #7 Детский, прошу прощения. Вопрос об обращении к 16-разрядному
значению, т.е. Big/Little endian. Есть структура teap0t(611 знак., 16.09.2020 11:28)
- Вообще не понял, какое отношение индейцы имеют к приведённому
примеру. А адрес всегда берётся нижний, т.е. если 16-разрядная
переменная сидит в адресах 4-5, то её адрес -- это 4 при любых
индейцах. Ну и адрес функции -- это 5, но это не из-за индейцев, а
из-за покусанного большого пальца (thumb bit). - SciFi(16.09.2020 12:18)
- Я проверял самого себя (не доверяю себе пока). Вдруг при
неправильном обращении в младшем полуслове очутился бы блок
Reserved0. С адресом функции не понял, но это пока рано. - teap0t(16.09.2020 12:58)
- В сях (да и не только в сях) надо всегда понимать, где какие типы,
и как они преобразуются явно или неявно при различных действиях. SciFi(321 знак., 16.09.2020 13:28)
- Э, нет. Последняя строка должна выглядеть teap0t(219 знак., 16.09.2020 13:31)
- Вопрос на самом деле возник из-за того, что при компиляции
появляется туча отметок "Remark[Pa091]: operator operates on value
promoted to int (with possibly unexpected result)" возле кода вида teap0t(103 знак., 16.09.2020 13:36)
- Нужно так: SciFi(603 знак., 16.09.2020 14:06)
- Вопрос на самом деле возник из-за того, что при компиляции
появляется туча отметок "Remark[Pa091]: operator operates on value
promoted to int (with possibly unexpected result)" возле кода вида teap0t(103 знак., 16.09.2020 13:36)
- Э, нет. Последняя строка должна выглядеть teap0t(219 знак., 16.09.2020 13:31)
- В сях (да и не только в сях) надо всегда понимать, где какие типы,
и как они преобразуются явно или неявно при различных действиях. SciFi(321 знак., 16.09.2020 13:28)
- Я проверял самого себя (не доверяю себе пока). Вдруг при
неправильном обращении в младшем полуслове очутился бы блок
Reserved0. С адресом функции не понял, но это пока рано. - teap0t(16.09.2020 12:58)
- У вас TIMx ничем не инициализирован, так что поведение этого кода
непредсказуемо. Но если дать TIMx осмысленное значение, tmp32_2 и
tmp32_1 будут равны. Адрес переменной - это меньший из адресов её
байтов. То есть в Little endian - адрес младшего байта, в Big
endian - старшего. - йцyкeн(16.09.2020 11:54)
- ОК. Это фрагмент кода. Разбираюсь, как чего. - teap0t(16.09.2020 12:06)
- Поведение предсказуемо. Процессор перейдет на вектор Hard Fault Error. :-) Ну и STM32, вроде все little endianness - BlackMordaмудак(16.09.2020 12:44)
- ОК. Это фрагмент кода. Разбираюсь, как чего. - teap0t(16.09.2020 12:06)
- Вообще не понял, какое отношение индейцы имеют к приведённому
примеру. А адрес всегда берётся нижний, т.е. если 16-разрядная
переменная сидит в адресах 4-5, то её адрес -- это 4 при любых
индейцах. Ну и адрес функции -- это 5, но это не из-за индейцев, а
из-за покусанного большого пальца (thumb bit). - SciFi(16.09.2020 12:18)
- #6 В Си порядок следования битов в битовых полях определён
стандартом или где-то задаётся? teap0t(574 знак., 14.09.2020 18:12)
- 1412 The order of allocation of bit-fields within a unit
(high-order to low-order or low-order to high-order) is
implementation-defined. - йцyкeн(14.09.2020 18:44, ссылка)
- Торможу. Ссылка на стандарт языка - это намёк, что я тут всем
немного надоел? - teap0t(14.09.2020 20:19 - 22:21)
- В чём вы увидели намёк? А по поводу битфилдов - если вас смущает implemetation-defined, просто не пользуйтесь ими, пользуйтесь масками. - йцyкeн(14.09.2020 20:50)
- Это намек, что не нужно пользоваться битовыми полями - lloyd(14.09.2020 20:47)
- ОК. Учту. Но мне просто надо было понять. В статье про ХардФолт на Хабре использовалась диагностическая структура teap0t(1461 знак., 14.09.2020 22:28, ссылка)
- КМК, они были придуманы немного для другого. Но и для железных регистров их используют, я сам видел в каких-то яровских хедерах, если мне не изменяет склероз. Там есть оговорки, конечно, но с ними можно жить. - SciFi(14.09.2020 20:58)
- Боже, какой ужас. И как в этом c0x жить? Спасибо. - teap0t(14.09.2020 19:11)
- Торможу. Ссылка на стандарт языка - это намёк, что я тут всем
немного надоел? - teap0t(14.09.2020 20:19 - 22:21)
- 1412 The order of allocation of bit-fields within a unit
(high-order to low-order or low-order to high-order) is
implementation-defined. - йцyкeн(14.09.2020 18:44, ссылка)
- #5 Объявление "*(__IO uint32_t *) CR_LCDEN_BB =
(uint32_t)NewState;". Правильно я понимаю, что CR_LCDEN_BB -
указатель на 32-разрядное слово в пространстве ввода-вывода? Т.е.
скобки в (__IO uint32_t *) используются для создания "композитного"
определения - "указатель на слово в памяти В/В"? - teap0t(11.09.2020 17:49)
- У ARM плоское адресное пространство, там нет "пространства
ввода-вывода" (ну, кроме фактического диапазона адресов). __IO -
это макрос для volatile в CMSIS. lloyd(245 знак., 11.09.2020 18:08)
- Т.е. это всё же не просто память, а с особым свойством, отмеченным
"__IO", и "композитное определение" - "указатель на слово в памяти
со свойством volatile"? - teap0t(11.09.2020 18:15)
- Для процессора - это именно что "просто память". У него нет
отдельной IO-шины (поэтому обработчики прерываний из RAM могут
работать медленнее, чем из FLASH, потому что для последнего есть
кеш у процессора). lloyd(268 знак., 11.09.2020 18:22)
- ОК - teap0t(11.09.2020 18:24)
- Для процессора - это именно что "просто память". У него нет
отдельной IO-шины (поэтому обработчики прерываний из RAM могут
работать медленнее, чем из FLASH, потому что для последнего есть
кеш у процессора). lloyd(268 знак., 11.09.2020 18:22)
- Т.е. это всё же не просто память, а с особым свойством, отмеченным
"__IO", и "композитное определение" - "указатель на слово в памяти
со свойством volatile"? - teap0t(11.09.2020 18:15)
- Неправильно. Всё неправильно. Компилятор это видит так: представь,
что CR_LCDEN_BB -- указатель на тип "_IO uint32_t" и по адресу,
куда указывает этот указатель (для чего нужна первая звёздочка)
запиши значение полученное путём преобразования NewState в тип
uint32_t... Ни про какие вводы-выводы компилятор ни сном ни духом.
У него нет таких абстракций. Настоятельно рекомендую "практику
программирования" опять же. - fk0легенда(11.09.2020 18:06)
- Ну, я же говорю о "модификаторе", который сообщает компилятору, что
у памяти есть дополнительный атрибут, отличающий её от прочих
ячеек. Мы-то не компиляторы, нам можно синонимы употреблять. Книгу
читаю. - teap0t(11.09.2020 18:22)
- Вот какой-нибудь индусский говнокодер наковыряет из носа _IO, и
начинающий ымбеддер начинает искать там тайные смыслы. Надо было
написать volatile, и точка. - SciFi(11.09.2020 18:29)
- Я с начала написал: нужно учиться программировать абстрактный
компьютер, а не AVR на IAR, или ARM на Keil. Но вот эта мысль
почему-то встречает гигантское сопротивление. Абстрактный компьютер
не хотят. - fk0легенда(11.09.2020 18:48)
- Может Кнута посоветовать. Он как раз сперва и говорит о абстрактной ЭВМ, а потом переходит к алгоритмам. - Xитpый Kитaeц(12.09.2020 12:16)
- Речь всё же не о каком-то чипе какой-то фирмы, а о вполне
абстрактной форме записи (__IO uint32_t *). Я, как человек в теме
свежий, естественно, интересуюсь на предмет детали "__IO" в записи.
В говорите, что она не нужна, но зачем-то же она там присутствует.
Должен я понять зачем или нет?! Абстракции вещь понятная, когда
понятА уже. Скажем, дифференциальное счисление штука абстрактная, но
становится откровенно понятнее и интереснее, если знать, как с
помощью teap0t(68 знак., 12.09.2020 09:43)
- #define __IO volatile il-2(103 знак., 12.09.2020 09:52)
- Включил листинг препроцессора и тутже узрел "*(volatile uint32_t *)
(((uint32_t)0x42000000) + ((((...." - teap0t(13.09.2020 12:03)
- И где вы только такие страшные слова откапываете :), С - предельно
простой язык. - Kceния(13.09.2020 15:34)
- Я вот тоже не понимаю - зачем сразу лезть в самые тёмные углы? Это
всё равно что увидев строчку printf("Hello, world\n"); смотреть
сорсы функции printf. Да там чёрт ногу сломит, многие этих сорсов в
глаза не видели, но прекрасно принтфом пользуются. Так и здесь -
напишите #include "stm32f10x.h", и без нужды внутрь не
заглядывайте. Зато вы сможете написать что-нибудь вроде
USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_TCIE; и
нужные биты попадут в нужный регистр йцyкeн(1 знак., 13.09.2020 16:27)
- Я так не умею. Понятно, что надо доверять коду IAR или ST, но в
данном случае я получаю HardFault при полном отсутствии ошибок и
предупреждений. Плюс, попробовал попереключать опции компилятора, и
всё завертелось... - teap0t(13.09.2020 16:41)
- Так не начинайте с того, что не работает. Начните с того, что
работает, неужели такое нельзя найти? Я бы вам сам что-нибудь
подкинул, но я с L не работал, только с F. Ну там светодиодом
мигните, или пресловутые два байта переслать через UART. - йцyкeн(13.09.2020 17:38)
- Это проект из STM32L-Discovery_FW_Pack, который можно взять у ST,
но плата MB963B - старенькая с 152RBT (без "A"). На шабаше у
Компела давно тому всё работало. Сейчас компилирую - ошибок нет, но
получаю HF и всё. Про светодиод понятно, но интересно же в чём
дело. Я же не первый год программизмом занимаюсь, просто на Си этим
не страдал. Полностью перезалил проект - работает, хотя и не вполне
корректно. Я сам дурак. - teap0t(13.09.2020 19:18 - 20:20)
- в свое время, если склероз не изменяет fk0 подсказал быстрого выяснения места выпада в HF Aleksey_75(242 знак., 13.09.2020 19:23)
- Это проект из STM32L-Discovery_FW_Pack, который можно взять у ST,
но плата MB963B - старенькая с 152RBT (без "A"). На шабаше у
Компела давно тому всё работало. Сейчас компилирую - ошибок нет, но
получаю HF и всё. Про светодиод понятно, но интересно же в чём
дело. Я же не первый год программизмом занимаюсь, просто на Си этим
не страдал. Полностью перезалил проект - работает, хотя и не вполне
корректно. Я сам дурак. - teap0t(13.09.2020 19:18 - 20:20)
- Компилятор принципиально не может предупредить о некоторых вещах,
например об обращении к выключенной периферии. С таким подходом
можно загнать себя в угол. Есть конкретный проект, или "изучение
ради изучения"? - VLLV(13.09.2020 17:19)
- Спасибо за наводку. Удалил весь проект и установил из архива
заново. Работает, но температура -218 градусов. Приятно сознавать,
что сам дурак, а мир светел и прекрасен. - teap0t(13.09.2020 20:19)
- Народ, есть ли какой способ подключиться к плате отладчиком IAR?.
Плата живая и с прошивкой, не защищена (STM Discovery). Хочется
глянуть в память с заводскими значениями термодатчика и опорника на
предмет сохранения. - teap0t(15.09.2020 15:40)
- JLinkExe или JLink.exe VVB(233 знак., 15.09.2020 16:09)
- jlink.exe работать не хочет. Ладно позже вернусь к этому вопросу. teap0t(1 знак., 15.09.2020 16:25, картинка)
- Для сброса дампа flash нужно использовать j-flash - BlackMordaмудак(15.09.2020 16:43)
- Проще через savebin (команда в JLink.exe). VVB(53 знак., 15.09.2020 17:43)
- Для сброса дампа flash нужно использовать j-flash - BlackMordaмудак(15.09.2020 16:43)
- jlink.exe работать не хочет. Ладно позже вернусь к этому вопросу. teap0t(1 знак., 15.09.2020 16:25, картинка)
- в настройках отладчика включить подключение без ресета - Aleksey_75(15.09.2020 15:44)
- Пытался сделать так. Взял левый проект, скомпилял, установил отказ
от заливки и попытался запустить отладку. Шыш. Tue Sep 15, 2020
15:58:17: ELF/DWARF Error: Unknown teap0t(2 знак., 15.09.2020 16:05, картинка, картинка)
- На плате распаян огрызок ST-LINK/V2 у которого есть только SWD, а JTAG-а нет. ЫЫyкпy(654 знак., 15.09.2020 22:17, ссылка, ссылка)
- Нужно еще J-link/J-trace сконфигурировать. Выбрать JTAG/SWD,
Ethernet/USB - BlackMordaмудак(15.09.2020 16:47)
- С USB он не хочет. И вообще у меня такого железа нет. У меня только ST-Link на демоплате. - teap0t(15.09.2020 20:34)
- Пытался сделать так. Взял левый проект, скомпилял, установил отказ
от заливки и попытался запустить отладку. Шыш. Tue Sep 15, 2020
15:58:17: ELF/DWARF Error: Unknown teap0t(2 знак., 15.09.2020 16:05, картинка, картинка)
- JLinkExe или JLink.exe VVB(233 знак., 15.09.2020 16:09)
- Народ, есть ли какой способ подключиться к плате отладчиком IAR?.
Плата живая и с прошивкой, не защищена (STM Discovery). Хочется
глянуть в память с заводскими значениями термодатчика и опорника на
предмет сохранения. - teap0t(15.09.2020 15:40)
- Спасибо за наводку. Удалил весь проект и установил из архива
заново. Работает, но температура -218 градусов. Приятно сознавать,
что сам дурак, а мир светел и прекрасен. - teap0t(13.09.2020 20:19)
- Так не начинайте с того, что не работает. Начните с того, что
работает, неужели такое нельзя найти? Я бы вам сам что-нибудь
подкинул, но я с L не работал, только с F. Ну там светодиодом
мигните, или пресловутые два байта переслать через UART. - йцyкeн(13.09.2020 17:38)
- Я так не умею. Понятно, что надо доверять коду IAR или ST, но в
данном случае я получаю HardFault при полном отсутствии ошибок и
предупреждений. Плюс, попробовал попереключать опции компилятора, и
всё завертелось... - teap0t(13.09.2020 16:41)
- Я вот тоже не понимаю - зачем сразу лезть в самые тёмные углы? Это
всё равно что увидев строчку printf("Hello, world\n"); смотреть
сорсы функции printf. Да там чёрт ногу сломит, многие этих сорсов в
глаза не видели, но прекрасно принтфом пользуются. Так и здесь -
напишите #include "stm32f10x.h", и без нужды внутрь не
заглядывайте. Зато вы сможете написать что-нибудь вроде
USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_TCIE; и
нужные биты попадут в нужный регистр йцyкeн(1 знак., 13.09.2020 16:27)
- И где вы только такие страшные слова откапываете :), С - предельно
простой язык. - Kceния(13.09.2020 15:34)
- Включил листинг препроцессора и тутже узрел "*(volatile uint32_t *)
(((uint32_t)0x42000000) + ((((...." - teap0t(13.09.2020 12:03)
- #define __IO volatile il-2(103 знак., 12.09.2020 09:52)
- Я с начала написал: нужно учиться программировать абстрактный
компьютер, а не AVR на IAR, или ARM на Keil. Но вот эта мысль
почему-то встречает гигантское сопротивление. Абстрактный компьютер
не хотят. - fk0легенда(11.09.2020 18:48)
- Вот какой-нибудь индусский говнокодер наковыряет из носа _IO, и
начинающий ымбеддер начинает искать там тайные смыслы. Надо было
написать volatile, и точка. - SciFi(11.09.2020 18:29)
- Ну, я же говорю о "модификаторе", который сообщает компилятору, что
у памяти есть дополнительный атрибут, отличающий её от прочих
ячеек. Мы-то не компиляторы, нам можно синонимы употреблять. Книгу
читаю. - teap0t(11.09.2020 18:22)
- Если бы CR_LCDEN_BB был указателем НУЖНОГО типа, то преобразование типа (__IO uint32_t *) не потребовалось бы. Скорее всего это просто константа - адрес. Чтобы по этому адресу записать 32-битное значение, необходимо преобразование типа - сказать компилятору, что это именно указатель и именно на 32-битное значение. - il-2(11.09.2020 18:05)
- У ARM плоское адресное пространство, там нет "пространства
ввода-вывода" (ну, кроме фактического диапазона адресов). __IO -
это макрос для volatile в CMSIS. lloyd(245 знак., 11.09.2020 18:08)
- #4 Детский. Я объявил в "*.c" функцию "int foo(){};" (а
точка-с-запятой тут по делу?). В этом же *.c до объявления я
задекларировал "ing foo(void);" и вдобавок в *.h написал то же "ing
foo(void);". Вопрос: чем различаются прототипы в *.c и *.h. Если в
*.h нет объявления, то функция внешним файлам не видна? - teap0t(11.09.2020 15:21)
- int foo(){}; - просто ошибка. Здесь функция имеет пустое тело {}, а
должна возвращать int, то есть тело должно как минимум содержать {
return 0; }. Нужно различать declaration (прототип) и definition
(определение). int foo(); - прототип, точка с запятой нужна. int
foo() { return 0; } - определение, точка с запятой после } не
нужна. - йцyкeн(12.09.2020 23:36)
- OK - teap0t(13.09.2020 11:57)
- *.c и *.h -- это просто соглашение. Бывает же .cpp, .cxx, .hpp и
т.д. Советую заучить, что делает #include "filename", без этого
знания жить нельзя. - SciFi(11.09.2020 15:32)
- Не, это знаю, но все ведь включают хедеры а не исходник. Значит,
если хедера нет, то функция не видна, даже если объявлена в "*.c" ? - teap0t(11.09.2020 15:35)
- Есть как минимум 2 аспекта "видимости функции". 1) Прототип функции
(обычно содержится во включенном заголовочном файле) позволяет
компилятору сверять типы аргументов и возвращаемого значения при
вызове. 2) Видимость при линковке (наличие функции в одном из
объектных файлов, включенных в процесс линковки). Функцию можно
вызывать и без прототипа (с оговорками). - SciFi(11.09.2020 15:52)
- ОК - teap0t(11.09.2020 15:57)
- можно Nikolay801_(269 знак., 11.09.2020 15:47)
- Есть как минимум 2 аспекта "видимости функции". 1) Прототип функции
(обычно содержится во включенном заголовочном файле) позволяет
компилятору сверять типы аргументов и возвращаемого значения при
вызове. 2) Видимость при линковке (наличие функции в одном из
объектных файлов, включенных в процесс линковки). Функцию можно
вызывать и без прототипа (с оговорками). - SciFi(11.09.2020 15:52)
- Не, это знаю, но все ведь включают хедеры а не исходник. Значит,
если хедера нет, то функция не видна, даже если объявлена в "*.c" ? - teap0t(11.09.2020 15:35)
- int foo(){}; - просто ошибка. Здесь функция имеет пустое тело {}, а
должна возвращать int, то есть тело должно как минимум содержать {
return 0; }. Нужно различать declaration (прототип) и definition
(определение). int foo(); - прототип, точка с запятой нужна. int
foo() { return 0; } - определение, точка с запятой после } не
нужна. - йцyкeн(12.09.2020 23:36)
- #3 "static const" от "static" чем отличается? Простите. - teap0t(09.09.2020 20:43)
- const он как бы и африке const, RO переменная ) - Aleksey_75(09.09.2020 20:45)
- У эмбеддеров RO разный. static const кладется во флэш а просто
const размещается в RAM но компилятор следит чтобы в него не
писали. Это в gcc для stm32. - 3m(09.09.2020 21:41)
- Keil и const пихает во флешь! Но за инфу спасибо! (Просю простить,
был неправ ...) )))) - Aleksey_75(09.09.2020 21:50 - 10.09.2020 13:24)
- __flash -- это про AVR. Здесь же речь идёт об STM32. Не путайте нас, мы и сами запутаемся. - SciFi(10.09.2020 13:01)
- Вредный совет детектед. У переменных бывает такая штука "static
storage duration", если к этому добавить const, то переменная
попадёт в флеш. Если переменная объявлена внутри функции без
static, то это "automatic storage duration", и она не попадает в
флеш, даже если приписать const. - SciFi(10.09.2020 01:03)
- Вопрос. У Кернигана Ричи этой херни про "static storage duration",
значит это чья-то самодеятельность. Чья? Компиляторописателей, ИАР,
МПЛАБ, Кейл? Есть где-нибудь окончательный мандат, как у профессора
Преображенского, в котором это всё описано? - Kpoк(10.09.2020 09:49)
- Стандарт же. И я заглянул в K&R, там написано "static storage
class" и "automatic variables", такшта занудничать изволите. - SciFi(10.09.2020 09:59, ссылка)
- Ну не нравится мне С вот из-за этих художеств. Другое дело -
Фортран! - Kpoк(10.09.2020 10:02)
- Это FORTRAN-66 был прост, а нынче он (Fortran-2018) таков, что черт
ногу сломит. - Kceния(10.09.2020 19:08)
- Даже для 66-го никто не сделал для ПИКов транслятора :-( - Kpoк(11.09.2020 11:31)
- В фортране есть common blocks. - fk0легенда(10.09.2020 12:32)
- Нормальные такие блоки. Отлично с ними играли - Kpoк(11.09.2020 00:02)
- Не так. Другое дело -- С++, после него С покажется венцом творения. - SciFi(10.09.2020 10:05)
- 20 стандарт все исправил - OlegPowerC(10.09.2020 18:06)
- Это FORTRAN-66 был прост, а нынче он (Fortran-2018) таков, что черт
ногу сломит. - Kceния(10.09.2020 19:08)
- Ну не нравится мне С вот из-за этих художеств. Другое дело -
Фортран! - Kpoк(10.09.2020 10:02)
- Стандарт же. И я заглянул в K&R, там написано "static storage
class" и "automatic variables", такшта занудничать изволите. - SciFi(10.09.2020 09:59, ссылка)
- Вопрос. У Кернигана Ричи этой херни про "static storage duration",
значит это чья-то самодеятельность. Чья? Компиляторописателей, ИАР,
МПЛАБ, Кейл? Есть где-нибудь окончательный мандат, как у профессора
Преображенского, в котором это всё описано? - Kpoк(10.09.2020 09:49)
- Кажется, это не совсем верно. Sergey_N(77 знак., 10.09.2020 00:55)
- Ага. Посмотрю. - teap0t(10.09.2020 13:07)
- +1. - fk0легенда(10.09.2020 01:06)
- Keil и const пихает во флешь! Но за инфу спасибо! (Просю простить,
был неправ ...) )))) - Aleksey_75(09.09.2020 21:50 - 10.09.2020 13:24)
- У эмбеддеров RO разный. static const кладется во флэш а просто
const размещается в RAM но компилятор следит чтобы в него не
писали. Это в gcc для stm32. - 3m(09.09.2020 21:41)
- const он как бы и африке const, RO переменная ) - Aleksey_75(09.09.2020 20:45)
- #2 По ссылке очень приятный пример работы с выводами, а есть ли
какие примеры обработчиков прерываний? - teap0t(09.09.2020 20:27, ссылка)
- ))) Смотря с какими ))) если EXTI то у меня так Aleksey_75(2223 знак., 09.09.2020 20:29 - 21:09)
- Таймер какой-нибудь простенький. - teap0t(09.09.2020 20:34)
- Ну таймер всетаки более узко заточен , но и для него думаю можно накропать нечто подобное ) Aleksey_75(1255 знак., 09.09.2020 20:39)
- Таймер какой-нибудь простенький. - teap0t(09.09.2020 20:34)
- Всю жизнь "работаю с выводами" напрямую через регистры без
каких-либо обёрток, неудобств почему-то не испытываю. Что в
указанном примере должно вдохновить на более лучший порядок
организации обработчиков прерываний? - SciFi(09.09.2020 20:34)
- это хорошо для AVR где адекватные порты, c STM32 сложнее там
отдельно тянется номер пина и порта, поэтому оформил именно так!
кстати в set_pin_active(LED1); Aleksey_75(650 знак., 09.09.2020 20:44)
- В цикле "for" перед переменной цикла стоит указатель типа (если я
правильно понял) uint8_t, а зачем? А не проще инициализировать не
циклом, а записью констант в регистры? - teap0t(09.09.2020 20:54)
- uint8_t i = объявление переменной совмещено с ее первым использованием - VLLV(09.09.2020 21:01)
- не очень понял о чем речь, i счетчик цикла , а по сути указатель на
элемент массива с настройками конкретного пина! - Aleksey_75(09.09.2020 20:59)
- Зачем ограничивается размер переменной? Без модификатора, как я
понимаю, она будет 32- (или 16-) разрядной, уместится в регистре и
будет себе увеличиваться, пока дело до END_PIN_ARR не дойдёт. А в
чём смысл сокращать счётчик до байта? - teap0t(09.09.2020 21:20 - 21:27)
- а нафиг ? лютомноголапых мк у меня нет, да и править от проекта к проекту bsp_gpio.c нет желания, не для того она писалась Aleksey_75(91 знак., 09.09.2020 21:31)
- хм, ну эт привычка с 8битников, каждый байт на счету, можно былоб
поставить uint32_t но uint8_t за глаза , не использую мк более 200
выводов - Aleksey_75(09.09.2020 21:24)
- Я в таких местах пишу uint_fast8_t. Хорошо для архитектуры любой
разрядности. Да и вообще все локальные переменные стараюсь
объявлять через xxx_fastX_t. Это ИМХО дает некоторую гарантию
самого оптимального кода для архитектуры любой разрядности. Но есть
нюансы, которые надо держать в уме. - il-2(10.09.2020 08:26)
- Самый выпуклый нюанс -- имя uint_fast8_t длинное и уродливое. - SciFi(10.09.2020 09:13)
- typedef uint_fast8_t ufast8_t; Костыль конечно, но что делать. :-) - il-2(10.09.2020 12:14)
- Самый выпуклый нюанс -- имя uint_fast8_t длинное и уродливое. - SciFi(10.09.2020 09:13)
- Я в таких местах пишу uint_fast8_t. Хорошо для архитектуры любой
разрядности. Да и вообще все локальные переменные стараюсь
объявлять через xxx_fastX_t. Это ИМХО дает некоторую гарантию
самого оптимального кода для архитектуры любой разрядности. Но есть
нюансы, которые надо держать в уме. - il-2(10.09.2020 08:26)
- Зачем ограничивается размер переменной? Без модификатора, как я
понимаю, она будет 32- (или 16-) разрядной, уместится в регистре и
будет себе увеличиваться, пока дело до END_PIN_ARR не дойдёт. А в
чём смысл сокращать счётчик до байта? - teap0t(09.09.2020 21:20 - 21:27)
- В цикле "for" перед переменной цикла стоит указатель типа (если я
правильно понял) uint8_t, а зачем? А не проще инициализировать не
циклом, а записью констант в регистры? - teap0t(09.09.2020 20:54)
- Работаю с обертками для выводов, но как это может вдохновить на
обертки для прерываний? :) - VLLV(09.09.2020 20:37)
- Я вообще в самом начале пути. Речь не об обёртках, а о примерах работы. - teap0t(09.09.2020 20:40)
- Это, наверно, индивидуальность восприятия. Я тоже всегда прямо
работал, но на ассемблере. - teap0t(09.09.2020 20:36)
- После работы на ассемблере лучше в совершенстве освоить обычный С,
а уже потом заниматься извращениями. К этому лишнему слою
абстракций нужно привыкать, ошибки в нем ищутся тяжело. - VLLV(09.09.2020 21:13)
- я боюсь что касается армов, все родные либы это лютая абстракция,
причем не всегда очевидная.. - Aleksey_75(09.09.2020 21:17)
- Я бы так не утверждал. - VLLV(09.09.2020 21:40)
- я боюсь что касается армов, все родные либы это лютая абстракция,
причем не всегда очевидная.. - Aleksey_75(09.09.2020 21:17)
- После работы на ассемблере лучше в совершенстве освоить обычный С,
а уже потом заниматься извращениями. К этому лишнему слою
абстракций нужно привыкать, ошибки в нем ищутся тяжело. - VLLV(09.09.2020 21:13)
- это хорошо для AVR где адекватные порты, c STM32 сложнее там
отдельно тянется номер пина и порта, поэтому оформил именно так!
кстати в set_pin_active(LED1); Aleksey_75(650 знак., 09.09.2020 20:44)
- ))) Смотря с какими ))) если EXTI то у меня так Aleksey_75(2223 знак., 09.09.2020 20:29 - 21:09)
- #8 Есть объявление teap0t(358 знак., 17.09.2020 09:45)