- наткнулся на от iar. смутило Confusing implicit casting: Bit shift an unsigned 32 bit object 15 times Constantin24(167 знак., 28.10.2020 13:10, ARM, ссылка, полностью)
- Наткнулся на код. в чем сокральный смысл сего? Constantin24(207 знак., 26.10.2020 13:28 - 14:29, ARM, полностью)MBedder
- У STM32H7 в SPI есть FIFO и доступ к нему через TXDR посредством 8,
16 или 32 битного доступа вызывает запись соответствующего
количества бит. Для любого вменяемого компилятора VladislavS.(333 знак., 28.10.2020 08:22)
- большая просьба ! опубликуйте плиз определение регистра TXDR! - Aleksey_75(26.10.2020 22:28)
- Не хватает типа TxData. Предположу что он 16битный, тогда это
конструкция заставляет gcc исползовать 16битную команду записи, а
не расширить вначале TxData и затем уже записать 32 битный блок.
Для некоторых странных переферий это может быть важно. На другом
компиляторе видимо этого расширения не происходит (что само по себе
довольно сильное предположение). - Kabdim(26.10.2020 18:31)
- похоже опять 50.4.13 Data packing . Возможно гнусь и другие
компиляторы по разному организуют доступ к регистру, когда регистр
описан как 32битный, а переменная 16битная. - Andreas(26.10.2020 14:45)
- Автор не смог написать "*((__IO uint16_t *)&SPIx->TXDR) =
TxData" ? - fk0(26.10.2020 14:09)
- и на какой адрес ссылается spitxdr ??? я так понял при записи в
SPIx->DR реальная запись идет в TXbuf, а при чтении с
SPIx->DR с RXbuf! А вот адресацию я найти так и не смог! Aleksey_75(1 знак., 26.10.2020 13:57, картинка)
- Надо уметь воспринимать мир со всеми его противоречиями, и не
искать смысла там, где его нет :-) Спроси у автора. Ставлю бутылку,
что не услышишь вразумительного ответа :-) il-2(58 знак., 26.10.2020 13:56)
- скорее всего это связано с настройками SPI (количество байт),
недавно эта тема косвенно затрагивалась - VLLV(26.10.2020 13:43)
- возможно, какая то ручная оптимизация кода. - ASDFS(26.10.2020 13:36)
- Stm32f0 настройка CAN на 125 kbps Balda(71 знак., 22.10.2020 18:36, ARM, картинка, полностью)
- stm32 чтот непонятки, создал массив в раме volatile uint8_t
__attribute__ ((at (ADR))) tmp_buf[22528] = { 0 }; Смотрю
отладчиком а но вообще и не обнулен, мусор... принудительное
обнуление через memset на ПО не влияет, т.е. почему то не инитится,
вопрос почему ? - Aleksey_75(21.10.2020 01:03, ARM, полностью)
- Как и обещал, сделаю развернутое пояснение. Для начала стоит
обратить внимание на выхлоп компилятора, для чего скормим файл
прошивки программе readelf (в качестве примера я взял пример blink
из своей либины): evgeniy1294(3147 знак., 21.10.2020 21:56)
- 1. Проверка if (dl != ds) не нужна. На этапе компиляции значения dl
и ds неизвестны, их линкер подставляет. Поэтому оптимизация тут не
сработает. А дальше while и без этой проверки всё правильно
сделает. VladislavS.(1485 знак., 22.10.2020 08:32)
- Спасибо за развернутый ответ! А вы уверены что ZI-дата обнуляется
именно так а не копируется напрямую с флеши ? мелкие массивы
копируются напрямую точно знаю! - Aleksey_75(21.10.2020 22:12)
- У тебя же не gcc? Мешаете тёплое и мягкое. - SciFi(21.10.2020 22:28)
- не gcc... вопрос! а с gcc можно собирать без установки пакета? ну
т.е. бросил два екзешника компилер и линкер в репозиторий и на
любом компе собрал ? - Aleksey_75(22.10.2020 00:22)
- Почему-то многие думают, что gcc — это просто экзешник, который к
тому же умеет все архитектуры (опен соус жеж!). GCC — это проект с
большим деревом исходников, который рождает множество разных
компиляторов. А на самом деле тебе интересен тулчейн (его тоже
часто называют gcc), и туда кроме компилятора входит, например,
такая немаловажная часть, как стандартная сишная библиотека, и это
уже не gcc, а другой проект, но кому это интересно... - SciFi(22.10.2020 09:20)
- Ну не два экзешника, но просто распаковать toolchain в отдельную
папку, прописать к нему пути и собирай make. - VladislavS.(22.10.2020 08:00)
- Нужно завести секцию .bss_RAM<что-то> по нужному адресу и
соответственно размещать в секции. Тогда будет нормальная
инициализация. - Kabdim(21.10.2020 12:26)
- Потому что обнуляемые значения покоятся в секции bss, а у вас
массив черт знает где (ADR). Секция bss обнуляется в стартапе, вам
придётся либо разместить массив в ней, либо обнулять вручную. evgeniy1294(144 знак., 21.10.2020 01:11)
- Знатоки STM32 и читатели даташитов! SPI сконфигурирован на 1 байт,
нужно ли приводить SPI->DR к одному байту? Если записать, как
есть, сколько байт передаст SPI? - VLLV(09.10.2020 04:31, ARM, полностью)
- stm32 сильно разные, например на L4 я пару часов потратил на бубен,
там надо было не только DR приводить к одному байту, но еще
периферию нетривиально настраивать. В других обходилось без бубна. - AVF(13.10.2020 12:48)
- Из даташита на STM32F10x: il-2(460 знак., 09.10.2020 15:29)
- При передаче всё просто. Само собой будет 1 байт. Если задан байт.
А вот при приеме да, надо смотреть наличие ФИФО. Я 3 года назад
накувыркался с STM32L476. :-) - Лaгyнoв(09.10.2020 08:38)
- Вот это читали? - teap0t(09.10.2020 07:56, ссылка)
- Спасибо! Теперь смотрите, в чем проблема - такое приведение убивает
признак volatile у DR! В IAR на максимальной оптимизации этот код
не работает. - VLLV(09.10.2020 09:00)
- Блин, да не выдумывайте проблемы на ровном месте. Всё проще пареной
репы. VladislavS.(452 знак., 09.10.2020 09:19)
- По поводу volatile эти примеры ничего не доказывают, т.к.
неизвестна оптимизация и прочие условия. По поводу размерности -
вот брошу все и сам проверю. - VLLV(09.10.2020 09:26)
- Чего? Вы видели определение регистров процессора в заголовочных
фалах? Там стоит __IO aka volatile. И ни один компилятор не имеет
права выкинуть/оптимизировать доступ к этим регистрам на любом
уровне оптимизации. Мои примеры скомпилированы на максимальной
оптимизации в IAR. Ну это же азы эмбеддерства, даже удивительно,
что такие вещи объяснять надо. - VladislavS.(09.10.2020 10:13)
- Имею интересные впечатления от компилятора cosmic для stm8. Он
просто не обращает внимания на volatile. Это логично, учитывая, что
код генерит на манер "что вижу, то и пишу", хитрых оптимизаций нет.
Но на код "var += 2;" выдаёт "INC mem INC mem", например. Зануды
скажут "какой же это volatile!", а я скажу "ну и что, зато код
компактный получается"... - SciFi(09.10.2020 10:26)
- Наверно, Вы не знаете перевода volatile - "летучая", то она есть,
то ее нет. В вашем случае есть, в моем - нет ;) - VLLV(09.10.2020 10:22)
- Какой такой "этот код"? Прячете? Снова военная тайна? - SciFi(09.10.2020 09:05)
- Это от контроллера зависит. Есть контроллеры с FIFO на SPI, у них
есть разница в поведении при байтовом или пословном доступе к DR.
Конкретно в RM на чип надо смотреть. - VladislavS.(09.10.2020 07:49)
- На сколько сконфигурирован, столько и передаст - il-2(09.10.2020 07:36)
- Несколько интервью по личным вопросам. Продолжение_5. Продолжение_4
по ссылке. - teap0t(04.10.2020 15:09, ARM, ссылка, полностью)
- Музыкальное сопровождение действа. - Evgeny_CD(04.10.2020 16:52, ссылка)
- #15 Разбирая библиотеки обнаружил такой вид адресной арифметики.
Насколько такой метод подходит/не_подходит под понятие "говнокод"?
Имеем такой фрагмент (коменты мои): (UPD подправил слегка) teap0t(2324 знак., 04.10.2020 15:21 - 16:05)
- Основная статья расходов это зарплата. STMicroelectronics -
огромная корпорация, отличительной чертой которой является найм
дешевой рабочей силы из Туниса, Морокко, Сингапура, Индии. (Также
как Microchip или Microsoft забиты ныне под завязку индусами).
Сейчас понятие "дешевый программист" включает девочек бывших
студенток (в основном не белых). Во всем этом легко убедиться, если
почитать ответы на ST форуме, посмотреть авторов комитов и
загуглить юмора ради имя. Так что RxTx(429 знак., 10.10.2020 16:00)
- Соглашусь. Впервые в жизни познакомился с "индусским кодом", и, что
характерно, сразу его узнал. Комменты - прямо феерия. Большую часть
можно просто удалить. Но у библиотек ST есть три очень серьёзных
достоинства. 1. Они работают. 2. Они хорошо документированы
(HAL/LL). 3. Они работают с железом, документация на которое
написана не слишком понятно (индусский текст), и являются отличным
дополнением к такому описанию. Да и вообще, периферия очень сложная
(и порождающая teap0t(211 знак., 10.10.2020 17:50)
- В ST же должны одни месье и д’Артаньяны работать :-) - OlegPowerC(10.10.2020 17:18)
- А потом мне говорят , чего ты пишешь велосипед. - OlegPowerC(10.10.2020 16:41)
- Если некое средство пользуется спросом, то со временем оно
допиливается. Скажем, IAR тоже когда-то был "поделкой финских
студентов" :). - Kceния(10.10.2020 16:08)
- Тупо не было в хедере на проц значений из enum. Извратились по
месту как умели - Vit(05.10.2020 18:24)
- В CubeMX всюду одна и та же система: пользователь выражает свои
требования путем заполнения полей соответствующий заданию структуры
предназначенными для этой цели мнемониками. Типа анкету заполняет.
А затем отсылает ее на исполнение соответствующей функции
XXXXX_Init(эта структура). После чего функция инициализации либо
выполнит требования пользователя, либо откажется, вернув ошибку. Те
случаи, когда внутри кода этой функции используется "косвенная
адресация" относятся Kceния(397 знак., 04.10.2020 19:39)
- Не, это уже другой уровень абстракции при написании софта. Я пока
поближе к железу. - teap0t(04.10.2020 20:43)
- йцyкeн прав - это не ради повышения уровня абстракции сделано. Но в
отличие от него я знаю зачем :). Во-первых, для контроля
устанавливаемых параметров: здесь все поля структуры имеют
свои/разные типы, а допустимые для них параметры определены через
enum, благодаря чему чужой параметр или произвольное число из
головы туда не подставишь. Но главное - второе, это особенность
архитектуры ARM, когда большинство периферийных регистров не имеют
жесткой специализации (как, Kceния(788 знак., 05.10.2020 14:56)
- Да в том-то и глупость, что это не другой уровень абстракции. Это
тот же уровень, только регистры периферии заменены на поля
структуры. Зачем - непонятно. - йцyкeн(04.10.2020 21:30)
- Затем, что один и тот же код должен одинаково работать на всех STM
микроконтроллерах. Используя прямую запись в регистры построить
такой код не удастся. - RxTx(10.10.2020 15:30)
- Такого даже ПИКи себе не позволяют, чего уж ожидать от СТМов. - Kpoк(11.10.2020 22:48)
- - Ну хорошо, вы не помните, как попали в самолёт. Но как вы вышли
оттуда, вы должны помнить? - Помнить должен. Но не помню. - йцyкeн(10.10.2020 16:56)
- Они решают это типичным паттерном "вызов API-функции". Программист
заполняет ряд параметров. Так как их много это поля структуры. Этим
высказывается абстрактное намерение. Затем вызывается API функция
инициализации. Функция находится в файле отвечающем за обслуживание
конкретного семейства, поэтому извне она черный ящик,
абстрагирующий параметры(поля структуры) от регистров и
особенностей инициализации семейства. - RxTx(10.10.2020 16:07)
- Не думаю, что о совместимости кода для всех STM-контроллеров кто-то
заботится. Уж который раз CubeMX перелицовывают - старые проекты
давно уже не компилируются его новыми версиями (хотя всегда можно
достать старую - она по согласию заливается, если на новую версию
переходить отказываешься). Хуже другое - меняются не только сами
структуры (например, у STM32F4 в структуре больше полей, чем у
STM32F1), но и многочисленные списки enum, которые в эти поля
подставляются. Например, Kceния(123 знак., 10.10.2020 16:05)
- Очень понятно. Потом исчезнуть библиотеки и "Reference manuals", и
АГА! Сначала примеры по применению, потом библиотеки в исходниках,
потом в бинарниках, потом без описания аппаратуры. "Здравствуй,
бабушка!". - teap0t(04.10.2020 22:05)
- Разве не это позволяет драйверу периферии работать с несколькими
группами регистров, например UART ? - VLLV(04.10.2020 21:47)
- +1. Я это называю "пустая абстракция". Лишняя сущность. - Cкpипaч(04.10.2020 21:35)
- Это не абстракция. Это "двое из ларца" для бедных, т.е. тех, у кого
нет денег на оплату услуг настоящих двоих из ларца. - SciFi(04.10.2020 20:54)
- Конструкция типа EXTI_InitStruct->EXTI_Mode это обращение к
полю структуры с именем EXTI_Mode, на которую указывает
EXTI_InitStruct, всё это эквивалентно (*EXTI_InitStruct).EXTI_Mode ЫЫyкпy(187 знак., 04.10.2020 16:47)
Это "библиотечная" реализация, видимо индус сделал так,
чтобы не зависить от именования регистров Interrupt и Event в CMSIS
для разных микроконтроллеров. Хотя не совсем, я ошибся. Там смысл такой: evgeniy1294(903 знак., 04.10.2020 15:32 - 15:55)
- Этот enum в приведённом коде вообще не используется. - ЫЫyкпy(04.10.2020 15:38)
- stm32... я где-то накосячил, не пойму где... POV_(1098 знак., 07.10.2020 09:43, , ARM, полностью)
- Были либы говенные I2C для F1xx.Пришлось попотеть конкретно пока
это говнище не заработало более-менее.От большого начальственного
ума внедрившего I2C в промоборудование. - PlainUser(08.10.2020 16:42)
- 1) Может быть проблема при MAX_SWITCH < 3. Если на платформе
NULL==0 то делать так: arhiv6(480 знак., 07.10.2020 11:53)
- Попробовать применить к структуре атрибут пакед? Чтобы везде была
упакована и размер был по месту? Nikolay_Po(36 знак., 07.10.2020 09:54)
- Отладчик в зубы и в бой. Современная техника позволяет отслеживать
значения переменных на лету. - SciFi(07.10.2020 09:47)
- Само исправилось.. Блядь, опять "Ленин в прошивку бомбу заложил" - POV_(07.10.2020 14:16, )
- Может быть дело в инкрементной компиляции, что-то не
пересобиралось? Какого-то криминала в коде я не увидел. Есть
замечательная утилиты nm/readelf в gnu binutils, умеют выводить
список всех символов с их адресами. Аналогичные утилиты есть в
любом приличном компиляторе, помогают отличить косяки с размещением
в памяти от ошибок времени исполнения. - evgeniy1294(07.10.2020 14:27)
- это самое страшное, если само исправилось, то может и само
сломаться))) надо искать что это было, иначе горя можно хапнуть по
самое не балуйся )) - Aleksey_75(07.10.2020 14:26)
- Ну тут еще накладываются косяки i2c в стм32ф1хх... POV_(1435 знак., 07.10.2020 23:19, )
- Да синей проблем не особо много - только нуженосцилограф/логический
анализатор , и все можно быстро понять - OlegPowerC(08.10.2020 08:01)
- Я использую программный I2C. Контролирую все подтверждения слэйвом
и ситуации, когда он притормаживает обмен. Иногда у меня на плате
на одной шине по 4-5 разных микрух. Всё работает нормально. Самое
главное, что полностью предсказуемо! И развести шину можно на любые
две ноги. - FDA(08.10.2020 07:36)
- "i2c в стм32 такой говённый или мои мозги" — ну ты уже
догадываешься, каков ответ на этот вопрос. i2c там не фонтан,
конечно, но косяки описаны в официальных доках. Нужно лишь
прочитать, осмыслить (обратите внимание на слово "осмыслить") и
применить на практике. И нет, раскидывание задержек по-пионерски в
разных местах таки не канает. - SciFi(08.10.2020 06:53)
- вот я тоже i2c не люблю никогда , одним словом "болгарин", поэтому
за i2c ничего говорить не буду! Да и по честному вешать флешку на
i2c это надо быть сам себе буратиной - Aleksey_75(07.10.2020 23:34)
- J-link ловит доступ к адресу памяти - VLLV(07.10.2020 11:06)
- Вот такое вот вроде начало шуршать... POV_(1363 знак., 08.10.2020 11:58, , ARM, картинка, полностью)
- stm32f1x Может попадалась кому или есть в наличии функция
табличного расчета crc как на stm32. Поделитесь плиз! Без таблицы у
меня есть, но она тормозная ... Aleksey_75(118 знак., 03.10.2020 22:27, ARM, полностью)
- Всем спасибо! Отдельная благодарность SciFi! Научился готовить hw
crc. унутри готовая функция, авось кому пригодится Aleksey_75(1590 знак., 03.10.2020 23:47)
- Вот тут есть online CRC Calculator, выдающий ещё и Lookup Table ЫЫyкпy(209 знак., 03.10.2020 23:39, ссылка, ссылка)
- Блин, ниже код от стм привёл ))... POV_(2023 знак., 03.10.2020 22:55, )
- Прям вот точно соответствует... POV_(236 знак., 03.10.2020 22:52, )
- Нагуглилось кое-что. А что блоками? Как это может быть
препятствием? Наверняка можно посчитать, как скормить аппаратному
вычислителю 1 слово, чтобы получить то же, что и от целого блока. - SciFi(03.10.2020 22:36, ссылка)
- В F1 не было возможности инициализировать блок CRC значением? Это
только в F0 появилось? lloyd(72 знак., 03.10.2020 22:29)
- Несколько интервью по личным вопросам. Продолжение_4. Продолжение_3
по ссылке. - teap0t(26.09.2020 07:50, ARM, ссылка, полностью)
- #1. (Повтор удалённого вопроса. Решил немного перекомпоновать
ветки, чтобы разделить темы). Как надо обходиться с проектом:
создавать локальную копию или пользоваться общим репозиторием IAR?
Я к тому, что есть понятие "говнокод", но может есть и понятие
"плохая практика". Ну, типа, хорошие мальчики не тащат всё к себе,
а учатся грамотно настраивать проект. - teap0t(25.09.2020 08:47 - 26.09.2020 07:58)
- Дальнейшее рассчитано только на то, если ты адекватный человек и
желаешь учиться и поступать профессионально. Из-за отсутствия опыта
ты пока не знаешь более высокоуровневых "так не надо". Именно эти
вещи я тебе и хочу сообщить. Если тебя устраивает "ну а чо такова,
у меня всё работает" - скажи. RxTx(3846 знак., 25.09.2020 16:16, ссылка)
- Уточню в п. 1, что конфиг мисра можно переписать поверх каждого
файла С, но не хэдэра. Проверку хэдэров у сторонних библиотек
выключить не получается из-за чего приходится отключать мисру всего
проекта если есть ссылки на библиотеку, которая мисру не
поддерживает. И для меня это проблема. - savram82(27.09.2020 11:00)
- В защиту библиотек ST. Я пока всех галок в опциях компилятора не
ставил (только дефолтные), но на таком уровне и со стандартом C99
(это нарушение, признаю) ошибок
нет совсем мало. С опцией C89 там Ад и Израиль, но я постепенно. Про
подходы к теме подумаю. Это как раз то, о чём я в #1 спрашивал, но
никто тогда не понял, о чём это я. Мне на самом деле обжиться в
коде надо, чтобы не смотреть на него, как на новые ворота.
Исправление ошибок для этого - teap0t(197 знак., 25.09.2020 20:14)
- Несколько интервью по личным вопросам. Продолжение_3. Продолжение_2
по ссылке - teap0t(23.09.2020 08:17, ARM, ссылка, полностью)
- #14 Сделал такой костыль, после чего ошибки компиляции исчезли. "Done. 0 error(s), 0 warning(s) ". Не откажите в любезности, гляньте, правильно ли? teap0t(753 знак., 24.09.2020 17:26)
- Можешь аргументированно объяснить, зачем ты стремишься к полной
поддержке MISRA ? - RxTx(23.09.2020 20:07)
- Уже пояснял, но повторю. Я учусь сейчас (в смысле "не
переучиваюсь"). У меня нет привычек и пристрастий, от которых
больно и неудобно отказываться. Я "чистый лист", на который можно
писать что угодно. Посему нет никаких оснований избегать правил
MISRA, потому что я, лично я, от этих ограничений ничего не теряю и
ни от чего не отказываюсь. Люди даже на браинфаке программируют, а
здесь просто некоторый набор вполне разумных правил. К тому же,
выясняя причины ошибок, teap0t(532 знак., 23.09.2020 21:11)
- Это понятно, но с другой стороны это как пробовать алкогольные
напитки сразу с неразведённого спирта - получишь отвращение или не
верное представление. symbions(13 знак., 24.09.2020 15:48)
- Если упарываться по анализу кода на всевозможные Rule-чекеры, то не
на одном только MISRA свет клином сошелся. Есть standalone версия
PVS-Studio (ее можно использовать free), она также как MISRA-чекер
чекает код на отсутствие потенциальных ошибок. Или есть Clang
Static Analyzer. RxTx(410 знак., 24.09.2020 01:54, ссылка, ссылка)
- Это очень хорошая мотивация. А спросил я потому что переживательно
на все это смотреть. (в полушутку) Ты как бы сам прищемляешь себе,
и потом от этого же страдаешь.... Некий такой (со стороны)
мазохизм... :)) Но окей, ладно. Каждый как говорится, д..чит как он
хочет. В C++ тебя ждут еще несколько тысяч правил, масса
cookbook'ов "так не делайте, а делайте так" (а через 5 лет
выясняется что делать надо было совершенно наборот) и всяких
занятнейших штук. - RxTx(24.09.2020 01:48)
- Кстати, по поводу заголовочных файлов - главное не забыть включить
заголовок в свой Сишный файл! Из трех месяцев один день можно
исключить ;) - VLLV(23.09.2020 22:55)
- #13 Народ, гляньте, у кого IAR есть, что написано в #define assert_param (в каком-то из заголовочных файлов) в вашей версии. В 5.20 код
выглядит так: teap0t(626 знак., 23.09.2020 20:01)
- IAR 7.40 VLLV(1043 знак., 23.09.2020 22:57)
- #12 MISRA. Имеется куча ошибок (кстати в библиотеке периферии, про
которую ST заявляет, что она совместима с сабжем). Error[Pm049]: all non-null statements shall have a side-effect
(MISRA C 2004 rule 14.2). Ругань идёт на следующий фрагмент: teap0t(414 знак., 23.09.2020 08:32)
- Несколько интервью по личным вопросам. Продолжение. Начало по
ссылке. На всякий случай, речь идёт о 32-разрядном контроллере
STM32, который предполагается использовать для работы со всяким
железом, т.е. на абстрактное программирование, а RAM, ROM, flash,
eeprom во весь рост в качестве контекста и шаблона. - teap0t(18.09.2020 10:30 - 11:31, ARM, ссылка, полностью)
- #10. Опять детский. Ткните носом где в стандарте написано как будет
выглядеть присвоение, например, 16-разрядному числу 8-разрядного
значения. Что происходит с мусором в старших разрядах. Про сдвиги
нашёл, а это никак. teap0t(210 знак., 19.09.2020 08:38)
- Вот: SciFi(938 знак., 19.09.2020 09:11 - 09:17)
- #9. Имеется объявление teap0t(254 знак., 18.09.2020 10:33 - 11:28)
- Второе объявление можно использовать в условных директивах
препроцессора #if . Первое - нельзя. За что пИсателям заголовочных
файлов для процессоров надо куда надо воткнуть, и там два раза
провернуть. - il-2(18.09.2020 20:17)
- Вообще не понимаю, что мешает просто написать "#define FLASH_SR_BSY
1". Можно было бы порассуждать на эту тему. Ну и табличка из
стандарта: SciFi(1 знак., 18.09.2020 10:48, картинка)
- Например - Evgeny_CD(18.09.2020 10:36, ссылка)
- Что-то странное по ссылке s_h_e(162 знак., 18.09.2020 10:48)
- ОК. Т.е. для 32-разрядной константы правильно писать teap0t(81 знак., 18.09.2020 10:43)
- Практически - да, но есть тонкости: uint32_t не одно и то же что и
unsigned long int : в памяти одинаковы, размер одинаков, а типы -
разные. Dingo(314 знак., 18.09.2020 10:56)
- Для 32-разрядной константы на 32-разрядном ядре. Иначе лучше писать
в скобках с приведением типа. - POV_(18.09.2020 10:45, )
- Ядро 32 разряда - STM32. Короче, правильно как в оригинале teap0t(92 знак., 18.09.2020 10:52)
- Какой смысл имеет типизация константы не по месту ее применения,
непонятно. А все непонятное неправильно. - VLLV(18.09.2020 10:56)
- Вопрос возник из-за такого кода (сразу предлагаю отвлечься от
оскорбительного национализма в определениях): teap0t(911 знак., 18.09.2020 11:45 - 16:55)
- Это говнокод. Не нужны там никакие приведения типа. Ну и регистр
FLASH->SR в хедерах объявлен 32-разрядным, поэтому
"допускающего по документации 8-, 16- и 32-разрядное обращение"
неведомо компилятору. - SciFi(18.09.2020 11:49)
- На SPI stm32f0 вляпался, что 16-битная запись выводит 2 байта, а 8
битная - один. Это описано в RM, но не очевидно. Andreas(118 знак., 18.09.2020 12:14)
- Разумеется, нужно приведение типа, если вы хотите обратиться к
части регистра, например отдельно к старшей и младшей половине
BSRR. Но если вы пишете в регистр целиком, это лишнее. А
(uint32_t)0 - совсем лишнее. И это лишнее не безобидно: компилятору
насрать, а человека, который взялся это читать, шум отвлекает. - йцyкeн(18.09.2020 12:27)
- Я, собственно, именно из-за пестроты кода полез со всем этим
разбираться. В тексте постоянно встречаются директивы указания
разрядности. Причём мне непонятно, зачем надо заводить 16-разрядную
переменную и постоянно указывать разрядность операций. Можно же
взять 32-разрядную, работать с ней и только перед самой записью в
регистр указать разрядность. Но я же должен убедиться, что всё
правильно понимаю? Поэтому задаю вопросы. Приятно осознавать, что
таки да, правильно понимаю. - teap0t(18.09.2020 15:22)
- Указание разрядности необходимо в целочисленной арифметике. - VLLV(18.09.2020 15:32)
- Всё так, только "перед самой записью в регистр указать разрядность"
не надо, это лишнее. - SciFi(18.09.2020 15:27)
- Раскройте мысль. Я, конечно, понимаю, что в 16-разрядный регистр 32
разряда не поместятся, и записаны будут только младшие биты.
Собственно, для того и берётся максимальный размер переменной,
чтобы приведение шло исключительно с обрезанием старших разрядов.
Но для компилятора это разве не имеет значения? Может будет
неправильная ассемблерная команда передачи использоваться (пример
условный)? - teap0t(18.09.2020 17:00)
- На всякий случай скажу банальность: побитные логические операции на
то и побитные, что разряды друг на друга не влияют. Сложение,
вычитание и умножение порождают переносы, при которых младшие биты
влияют на старшие, но никогда наоборот. Только деление и сдвиг
вправо приводят к влиянию старших разрядов на младшие. Поэтому,
если выражение не содержит деления и сдвига вправо, вычисления с
"лишней" разрядностью в соответствии с правилами integer promotion
не влияют на результат. йцyкeн(150 знак., 18.09.2020 18:33)
- Мне хочется минимизировать неоднозначность операций и снизить
вмешательство компилятора до минимально необходимого. (Пока не
освоился со всем этим). - teap0t(18.09.2020 18:42)
- Язык Си очень близок к
железу кремнию, вмешательство компилятора минимально. Если писать на
ассемблере, операции всё равно будут производиться над 32-битными
регистрам, операции над половинками и четвертинками отсутствуют за
исключением очень специальных команд. По крайней мере в Cortex-M3;
у M4 и M7 есть SIMD инструкции. - йцyкeн(18.09.2020 19:43)
- Ну да, вмешательство компилятора минимально. А потом он всё
оптимизирует, и погромист недоумевает "где мой код"? :-) - SciFi(18.09.2020 20:00)
- Язык Си - возможно, самый низкоуровневый из языков высокого уровня,
но это таки язык высокого уровня. Это не баг, а фичер. И
оптимизация - фичер. - йцyкeн(18.09.2020 21:50)
- Сижу в отладчике, ставлю останов, а он не ставится. Бля. Хорошо, я
не совсем нуб. Убрал всю оптимизацию нафиг. И всё равно на части
кода остановиться нельзя. В ассемблере-то я честно пишу, что надо
что-то в Rn положить. Всё просто и однозначно. Эх. - teap0t(18.09.2020 20:25)
- Сделай переменную volatile. Тогда место кода, где с ней идёт
работа, не будет выоптимизированно. Когда отладку завершишь,
уберёшь. - Nikolay_Po(19.09.2020 14:05)
- В нормальных компиляторах на минимальном уровне оптимизации нет
разницы между volatile и non-volatile. - SciFi(19.09.2020 14:14)
- Наверное, я всегда веду отладку с максимальной оптимизацией. Больше
ошибок и предупреждений вылазит сразу. Уже не понимаю, зачем
собирать код без оптимизации, даже для отладки. Просто прицеплю
volatile-переменную к параметру, в который хочу заглянуть.
Оптимизацию не выключаю. - Nikolay_Po(19.09.2020 14:19)
- gcc -Os -flto такое выдаёт, что отладчиком туда заглядывать
бесполезно, можно сразу шарить в дизассемблере... - SciFi(19.09.2020 14:58)
- По-моему, после LTO, и в дизассемблере бесполезно. Заглянуть в душу
оптимизатору может, пожалуй, только его разработчик. Отлаживаю
проверяя осциллографом на отладочный выход, на вывод UART, на
дисплей, если есть. Ну и само-собой, все предупреждения устраняю,
так как жизнь научила, что предупреждение компилятора - латентный
баг. - Nikolay_Po(23.09.2020 13:46)
- Нет никакой неоднозначности операций. Правила вычислений строго
изложены в стандарте. Вы можете пытаться структурировать выражения
так, чтобы действовали правила, которые вы знаете, и не действовали
те, которые вы не знаете. Но где гарантия, что вы не пропустите
какое-нибудь из неизвестных правил? Выход один -- знать правила. - SciFi(18.09.2020 19:03)
- Не волнуйтесь за компилятор, у него всё будет хорошо. Он сам
применит оптимальные инструкции. Ваша забота -- написать код без
ошибок в вычислениях. SciFi(110 знак., 18.09.2020 17:34, ссылка)
- Ессно, просто бывают случаи, когда приходится явно указывать
разрядность. И только тогда это надо делать в исходниках, чтобы
бросалось в глаза. Но такое бывает. - Andreas(18.09.2020 12:31)
- Да лааадно.. там же задается битность посылки при ините SPI - POV_(18.09.2020 12:21, )
- Можно цитату из RM? У меня не получается найти. - SciFi(18.09.2020 12:20)
- 27.5.8 Data transmission and reception procedures подраздел Data
packing - Andreas(18.09.2020 12:26)
- Да, кстати. Правильно ли я понимаю, что в этом случае надо
использовать что-либо подобное: (?) teap0t(51 знак., 18.09.2020 18:45)
- Нет, надо как йцукен написал. Но это редчайшее исключение, которое
подтверждает правило, что нечего постоянно явно разрядность менять. Andreas(573 знак., 18.09.2020 20:02)
- Нет, неправильно. У вас приведение типа применяется к результату
чтения из регистра, то есть читаются 16 бит, которые потом
обрезаются до 8. Чтобы читать 8, нужно делать так uint8_t data =
*((volatile uint8_t *)&SPIx_DR); - йцyкeн(18.09.2020 19:48)
- По логике - нет, приведение типов и так будет выполнено при
присвоении значения переменной. И дополнительное приведение типа
справа от знака присвоения значения смысла в этом выражении не
имеет. Другое дело если бы переменная была большего размера. Тут я
пока не представляю, как оно сработает. - Nikolay_Po(18.09.2020 19:19)
- Офигенно. Спасибо. - SciFi(18.09.2020 13:00)
- Если программисту платят за знаки, то вполне годный код. - VLLV(18.09.2020 11:59)
- Пример из жизни... POV_(546 знак., 18.09.2020 11:10, )
- Я протестую против слова "правильно" в этом контексте. Оно вообще
непонятно что означает. - SciFi(18.09.2020 10:54)
- Я хочу задать число, которое будет однозначно интерпретироваться
как 32-разрядная константа в любом контексте (и, скажем, в ПЗУ
будет занимать 4 байта). Если я правильно понял высказанное в
ветке, то объявление teap0t(125 знак., 18.09.2020 10:58)
- Попробуем разобрать высказанные заблуждения. SciFi(1069 знак., 18.09.2020 11:11, ссылка)
- Как я понял, вопрошавший собирался просто использовать константу в
выражениях. Она не будет напрямую присваиваться переменной и,
поэтому, будет храниться именно так, как указано в определении. - Nikolay_Po(18.09.2020 11:12)
- Вы все с ума посходили что ли? Константа нигде не хранится. Это
просто буковки и циферки в исходнике. Хранятся переменные. - SciFi(18.09.2020 11:14)
- Могу только напомнить, что я перехожу с ассемблера на Си, и для
меня числа с трудом отделяются от занимаемого ими места в памяти.
Плюс, речь всё же идёт о встраиваемых системах (да простит меня
fk0), где железо довольно близко. Я не могу к каждой вашей реплике
добавлять тег #ФилософияПрограммирования. Я предлагаю всё же ближе
к теме. Правильный подход виден в ответах VLLV, который просто
показывает ошибку в рассуждении и приводит примеры выявляющие
возможные пути развития teap0t(5 знак., 18.09.2020 11:26)
- Ну ОК. Речь о ПЗУ. Что если одной переменной присваивается значение
другой плюс эта константа? Компилятор по-любому положит эту
константу в память, пусть даже как операнд инструкции. Константы
могут быть удалены лишь при вычислениях во время компиляции. - Nikolay_Po(18.09.2020 11:22)
- Прошу пардону, а чо мы называем словом хранится? Я например храню
константы (которые первоначально были буковками и циферками в
исходнике) в теле программы, и если меня сильно припрет могу
переписать это тело вместе с этими константами средствами
процессора. Причем получить это новое тело хоть даже через уарт или
кнопочки. - Codavr(18.09.2020 11:21)
- Эт да, но иногда неплохо помочь компилятору намеком. Оба варианта
VLLV дадут варнинг и инфу для размышления программеру. Andreas(312 знак., 18.09.2020 11:21)
- Да. И нет смысла писать именно 0x00000001. Достаточно (uint32_t)1.
И скобки можно не ставить, нет более приоритетных операций, хотя и
не навредит. - Nikolay_Po(18.09.2020 11:09)
- uint16_t x = FLASH_SR_BSY; или uint64_t y = FLASH_SR_BSY : где тут
32 разряда? - VLLV(18.09.2020 11:07)
- Несколько интервью по личным вопросам. Продолжение_2. Продолжение_1
по ссылке - teap0t(21.09.2020 00:18, ARM, ссылка, полностью)
- ЦАП то работает, то нет. В чем причина? Kceния(1117 знак., 17.09.2020 03:26, ARM, полностью)
- Вот же от ST пояснение - Alt@ir(18.09.2020 15:02, ссылка)
- В линкере пропишите: lexxx-lexxx(250 знак., 17.09.2020 15:57)
- Приведение к (uint32_t *) доставляет - Vit(17.09.2020 09:17)
- Уже обращала внимание. Кубистам следовало выставить у функции
запуска тип указателя void*, т.к. подставляют туда указатели на
массивы с разной длиной элемента, а длина элемента задается в
параметрах DMA (DAC_ALIGN_8B_R или DAC_ALIGN_12B_R) в зависимости
от выбранной разрядности DAC. А так действительно код выглядит, как
ошибка. - Kceния(17.09.2020 10:41)
- Ставить void* не корректно в данном случае. Дело в том, что у dma в
stm32 есть такой параметр, как "размер транзакции", который может
быть равен 8, 16, 32 бита + есть ещё режим burst. Указатель на
uint32_t в параметрах может быть намеком на реализацию данной
функции. evgeniy1294(177 знак., 17.09.2020 11:30)
- Не поможет. В этом чипе DMA не может работать с этой областью
памяти. - VladislavS.(17.09.2020 13:21)
- Полагаю, что DMA тут ни при чём. Классический пример - memcpy -
намекает, что должен быть void*. - Vit(17.09.2020 11:43)
- Не нужно путать memcpy с копированием по dma, оно по разному
работает. Насколько мне известно, компиляторы умеют оптимизировать
memcpy, чтобы, например, копировать словами, а не байтами. evgeniy1294(67 знак., 17.09.2020 12:00)
- Не понял логики. Именно поскольку DMA может разный размер
транзакции иметь и разную разрядность входных данных, то лучше
void* , а еще лучше const void* , поскольку DAC и из флеша может
брать данные. - Andreas(17.09.2020 12:35)
- Логика в том, что автор функции подразумевает, что транзакция dma
настроена на 32 бита. Указатель на void может, например,
использоваться как указатель на контекст в колбэках. Потому что
автором колбэка являетесь вы, и вся ответственность за корректное приведение типов лежит на
вас, а не на авторе библиотеки. - evgeniy1294(17.09.2020 19:32)
- const void* имеет другой смысл, а именно, функция обязуется не
менять объект по этому указателю. И она таки не меняет, так что да,
можно добавить const. - SciFi(17.09.2020 12:50)
- Не нужно путать работу DMA с заданием формальных и передачей
фактических параметров в функцию. Сначала должно работать без
всяких оптимизаций. И если дальше кастится по-разному, да ещё и
аппаратное прибитие, то оно по-любому есть место для граблей, но
это не значит, что грабли нужно ещё и на входе расставлять.
HAL-о-строители ещё и, по идее, надеются на годный align, но они ж
смелые - им можно - Vit(17.09.2020 12:21)
- Данные могут быть до сих пор в кеше, а не в оперативке. Поставить
барьер данных пробовали? - lloyd(17.09.2020 09:01)
- Дополню, что там с выравниванием данных по секциям? Можно с ним
"поиграть". - Дoктyp77(17.09.2020 07:20, )
- На H7, во-первых, могут быть недоступные для DMA области.
Во-вторых, могут быть игры с кешированием. - VladislavS.(17.09.2020 07:18)
- Да, что-то в этом роде, т.к. тот же код работает на STM32F103 и
STM32F407, и только на STM32H743 у DMA пропадает доступ к ОЗУ.
Где-то в нем секьюрити зарыта, которую неясно, как отменить. - Kceния(17.09.2020 07:23)
- Проверила MPU (memory protection unit) - у меня он выключен. - Kceния(17.09.2020 09:11)
- Посмотрите в map-файле в какую SRAM линкер разместил этот массив.
Затем по RM в Table 3. Bus-master-to-bus-slave interconnect
проверьте может ли туда DMA добраться. Я бы с этого начал. - VladislavS.(17.09.2020 08:50)
- У меня одна SRAM - по адресу 0x2000. Да у меня и массивов-то кот
наплакал - 16 байт. - Kceния(17.09.2020 08:52)
- А теперь посмотрите Table 7. Memory map and default device memory
area attributes. 0x2000 это DTCM, до которой у DMA руки коротки
дотянуться. - VladislavS.(17.09.2020 09:26)
- Вот кстати да, в H7 перекроили memory map, классически SRAM идет с
адреса 0x2000'0000, а в H7 c 0x3000'0000. Сразу возникает вопрос,
"как оно туда попало?". Нужно в скрипте линкера смотреть, куда
релоцируется секция data. - evgeniy1294(17.09.2020 11:55)
- Ваша идея была хороша, но к сожалению она не проходит. Загрузчик
(читать память он тоже умеет) показывает наличие RAM лишь в области
0x20000000-0x2001FFFF и нигде больше. Даташит с этим согласен, с
той лишь разницей, что области, обведенные красным контуром,
загрузчик не читает. Кроме того, объем этих областей маловат, чтобы
размещать в них сегмент данных, а тем паче стек. Да и для самого
этого MK даже реклама больше, чем 128К RAM, не обещает. Причем, все
они находятся Kceния(116 знак., 18.09.2020 00:10, картинка)
- Почитать в reference manual про DMA. Предположу, может выравнивание
нужно? - Dingo(17.09.2020 07:11)
- Попробуйте volatile для буфера. - Dead_morose(17.09.2020 06:29)
- Задумали использовать STM32L010F4. Установил последнюю версию IAR.
Вроде как данный тип контроллера поддерживается, а соответствующего
заголовочного файла нет. Как быть? Спасибо! - Bill(18.09.2020 22:38, ARM, полностью)