- 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, полностью)
- Народ. Тест я позорно слил, поэтому могу спокойно заняться
самообразованием. Мне нужен STM32 + "Си". Понятно, что в случае
языка высокого уровня архитектура уже не так важна, а работа с
периферией требует простого знакомства с документацией, поэтому
вопросы будут по языку, а не по ARM. Могу я их здесь задавать или
как? - teap0t(09.09.2020 20:08, ARM, полностью)
- Не проблема, думаю. У Компела серия достаточно качественно
переведенных статей вышло по STM32, стоит ознакомиться. - Visitor(14.09.2020 19:21)
- Не надо знать периферию и архитектуру ? :-) - OlegPowerC(10.09.2020 18:03)
- Тебе не нужен STM32 + "Си". Тебе нужен Си отдельно и STM32, если
вообще нужен, отдельно. Кусочно-выборочно процитирую сам себя: дело
не только в C. Нужен некий кругозор на тему "как работает
компьютер". Лучше читать Роба Пайка "Практику программирования" --
она не даёт примеры в отрыве от компьютера, а в тесной связке с ОС,
ближе к практике. И принципиально полезно было бы поставить linux,
научиться в нём хоть как-то работать из командной строки и
выполнить примеры из книги fk0(4553 знак., 10.09.2020 00:46, ссылка, ссылка)
- Ждём с нетерпением. - SciFi(09.09.2020 20:12)
- #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)
- Доктор, где вы такие картинки берёте? Сколько лет пишу на 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)
- Использовать или нет - тут ещё могут быть разные мнения. Но не зная
брода языка Си учиться на примере этих индусов... мазохизм какой-то. - йцyкeн(17.09.2020 20:22)
- Я вообще не пойму, зачем DISABLE/ENABLE. Чем не устраивает
true/false? "bool megadevice_disabled = true, protection_enabled =
false;" - SciFi(17.09.2020 11:58)
- Лайфхак: !!(что-то) даёт ноль, если (что-то) равно нулю, и единицу
в противном случае. - SciFi(17.09.2020 10:58)
- Не правильно. enum - это набор чисел. DISABLE это число 0, !DISABLE
- это тоже какое-то число (компиляторозависимо), предположим (-1).
Тогда проверка превращается в (((STATE) == 0) || ((STATE) ==
(-1))). А тут, очевидно, STATE=2 не пройдет проверку - AlexBi(17.09.2020 10:07)
- #7 Детский, прошу прощения. Вопрос об обращении к 16-разрядному
значению, т.е. Big/Little endian. Есть структура teap0t(611 знак., 16.09.2020 11:28)
- #6 В Си порядок следования битов в битовых полях определён
стандартом или где-то задаётся? teap0t(574 знак., 14.09.2020 18:12)
- #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)
- Неправильно. Всё неправильно. Компилятор это видит так: представь,
что 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)
- Если бы CR_LCDEN_BB был указателем НУЖНОГО типа, то преобразование
типа (__IO uint32_t *) не потребовалось бы. Скорее всего это просто
константа - адрес. Чтобы по этому адресу записать 32-битное
значение, необходимо преобразование типа - сказать компилятору, что
это именно указатель и именно на 32-битное значение. - il-2(11.09.2020 18:05)
- #4 Детский. Я объявил в "*.c" функцию "int foo(){};" (а
точка-с-запятой тут по делу?). В этом же *.c до объявления я
задекларировал "ing foo(void);" и вдобавок в *.h написал то же "ing
foo(void);". Вопрос: чем различаются прототипы в *.c и *.h. Если в
*.h нет объявления, то функция внешним файлам не видна? - teap0t(11.09.2020 15:21)
- #3 "static const" от "static" чем отличается? Простите. - teap0t(09.09.2020 20:43)
- #2 По ссылке очень приятный пример работы с выводами, а есть ли
какие примеры обработчиков прерываний? - teap0t(09.09.2020 20:27, ссылка)
- NVIDIA объявила о покупке компании Arm за $40 млрд - Evgeny_CD(14.09.2020 09:53, ARM, ссылка, полностью)
- startup-файлы и вопросы по ним: evgeniy1294(1014 знак., 11.09.2020 18:06, ARM, ссылка, ссылка, полностью)
- В стартапе инициализация стека так как не все отладчики автоматом
его выставляют при загрузке как это делает ядро. По хорошему, под
условную компиляцию на дебаг её надо. - VladislavS.(16.09.2020 07:18)
- Забыл что хотел: стартап можно написать на C, на ограниченном его
подмножестве, которое не полагается на библиотеку вообще, не
полагается на инициализацию неавтоматических (статических,
глобальных) переменных. Нужно смотрет дизассемблер когда пишешь,
чтоб не наткнуться на библиотечные функции. Их запросто вызовет
простое деление. С библиотечными функциями проблема потому, что они
могут требовать инициализации чего-либо и при проверке CRC это
будет глупо выглядеть (весь fk0(53 знак., 11.09.2020 18:45)
- Стартап делает гораздо больше вещей. Вообще отчасти это задача
операционной системы: как-то разместить в памяти аргументы
программы, переменные окружения, и передать указатели на них. И
заодно сделать доступной в адресном пространстве программу
(загрузить её, библиотеки, релоцировать...), стек, настроить
регистры... C-стартап должен подготовить "рантайм" к работе и
инициализировать C-библиотеку.... fk0(2374 знак., 11.09.2020 18:42, ссылка, ссылка)
- 1. У GCC для TI TM4C так было уже хз сколько времени как.
Собственно у ARMа нет ничего, что нужно было бы обязательно делать
через асм в инициализации. lloyd(139 знак., 11.09.2020 18:18)