STM32f4 USB HS DMA HAL. Как это было

Попросил меня как-то один уважаемый заказчик организовать ему передачу данных с контроллера (stm32f407) в компьютер. Всё бы ничего, но скорость ему требовалась аж 40 мегабит в секунду.

Надо сказать, что железка была уже готова, основной код написан, в качестве интерфейса передачи выбран USB High Speed с внешним PHY (USB3300). У программиста заказчика с USB что-то не заладилось, посему решили произвести усиление коллектива вашим покорным слугой. Для полноты картины следует добавить, что весь код контроллера был написан при помощи CubeMX, а программа на ПК — на Delfi.

Решив, что в чужой монастырь со своим уставом не лезут (ну не люблю я Куб), стал я прикидывать, как в такой ситуации можно решить проблему заказчика малой кровью.

Пример с Virtual Com Port из Куба заработал практически сразу, но, по опыту работы с VCP, я не ожидал от него каких-то рекордных скоростей. И точно, более 14 мегабит в секунду я получить не смог. Скорее всего, узкое место находилось в драйвере VCP, но разбираться с ним совершенно не хотелось. Писать свой полноценный драйвер для ПК я счёл нехорошим излишеством, поэтому выбор был сделан в пользу libusbK. Что касается libusb(которая просто, без «К»), то под Линуксом она божественна, а вот её работа под Windows порой вызывает недоумение. Кроме того, у libusbK есть бинд для так любимого заказчиком Delfi.

Zadig мне в помощь, и я написал тест, который по запросу с ПК гнал буфер с 16-разрядным счётчиком, программа на ПК синхронизировалась с ним и далее проверялась правильность принимаемых данных. По факту, я использовал endpoint 1 из примера VCP, цепляясь к ним напрямую из libusbK. Обмен происходил посредством bulk-transfer, что мне и было нужно, так как данные терять было нельзя.

Запустил, подкрутил размер буферов, получил скорость аж в 20 мегабит в секунду. Нужно было искать ещё резервы для повышения производительности.

До этого я пробовал включать в контроллере USB DMA и выделенные прерывания на endpoint 1, но любое из этих действий как по отдельности, так и вместе выводило USB из строя, так что устройство совсем не опознавалось компьютером. Гугление ни к чему не привело. Везде народ гонял по USB небольшие объёмы данных и с DMA совершенно не заморачивался, но именно в нём намечался источик дополнительной производительности.

Wireshark и usbpcap особой ясности не внесли, ибо даже контрольные пакеты ходить по шине отказывались напрочь.

Трассировка отладчиком тоже была малоэффективна, так как любое вмешательство в работу USB приводило к ошибке по таймауту, и приходилось перезапускать процесс, тыкать туда-сюда разъёмы, глядя на окошко диспетчера устройств.

Пришлось открыть Reference manual на контроллер и медитировать, сравнивая написанное там с тем, что реально происходит в коде.

Ошибка со включением DMA нашлась в функции USB_EP0StartXfer файла stm32f4xx_ll_usb.c. Внимательно следим за руками:

   /* EP enable, IN data in FIFO */
    USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
    
    if (dma == 1)
    {
      USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr);
    }
    else
    {
      /* Enable the Tx FIFO Empty Interrupt for this EP */
      if (ep->xfer_len > 0U)
      {
        USBx_DEVICE->DIEPEMPMSK |= 1U << (ep->num);
      }
    }

Как видно, сначала включается и запускается endpoint, а потом инициализируются регистры DMA. Харе Кришна, дорогие индусы! Я вижу, вы неплохо сэкономили на тестах.

Должно быть:

    if (dma == 1)
    {
      USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr);
    }
    else
    {
      /* Enable the Tx FIFO Empty Interrupt for this EP */
      if (ep->xfer_len > 0U)
      {
        USBx_DEVICE->DIEPEMPMSK |= 1U << (ep->num);
      }
    }
   /* EP enable, IN data in FIFO */
    USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
 


Чтобы править индусский код нужно думать как индус, поэтому войдя в соответствующее состояние, ошибку с выделенными прерываниями я нашёл уже достаточно быстро, на этот раз в файле stm32f4xx_hal_pcd.c.

Не буду здесь писать весь код, diff-файлы для HAL от CubeMX v 4.20.1 приаттачены к данному посту.

После исправления указанных ошибок и немного поигравшись с размерами буферов, я легко получил скорость обмена 50 мегабит в секунду. Заказчик был счастлив.

В припадке альтруизма я решил поделиться найденными ошибками с разработчиками из ST: написал сообщение на форуме, приложил файлы. Прошло уже несколько дней — никакой реакции. В принципе, я не удивлён. На форуме у них видел сообщение двухгодичной давности о дефайне в HAL, который нигде не используется. Администрация обещала передать всё разработчикам. Специально проверил: в текущей версии (неделю как обновилась) всё точно также, как и два года назад. Стабильность.

Не уверен, в каком блоге следует публиковать всю эту лирику, посему пишу здесь, надеюсь, кому-то эта информация будет полезна.
  • +12
  • 25 апреля 2017, 15:47
  • DeddXey
  • 1
Файлы в топике: STM32F4xx_HAL_Driver.zip

Комментарии (54)

RSS свернуть / развернуть
решили произвести усиление коллектива вашим покорным слугой.
Не берусь судить что и где этот специалист усилил, но язык программирования называется ObjectPascal, а IDE для его написания Delphi.
0
Не являюсь специалистом в данном вопросе, посему терминологией не владею. Последний раз писал на ТурбоПаскале 5.5 в лихие девяностые.

Саму программу на ПК я в глаза не видел. Сказали — Дельфи, ну и ладно. Использовал библиотеку, которая имеет бинд для Паскаля, что позволило использовать множество ранее написанного кода.

Что касается усиления, то брали меня для решения конкретной задачи, которую я выполнил. API программистам отдал, все счастливы. Надо будет сделать что-то ещё в пределах моей компетенции — сделаю, тем более, что заказчик хороший, работать с ним одно удовольствие.
+2
Язык уже полтора десятилетия как Delphi.
0
круто, интересно, но хотелось бы посмотреть чуть больше кода :)
0
Полностью проект выложить не могу — заказчик несколько специфичный.
Скажите, что именно вас интересует, постараюсь показать ключевые моменты.
0
тогда пока не надо, буду иметь в виду :) заказчиков нельзя нервировать :)
0
Всегда рад помочь :)
0
Спасибо, полезная статья. Если еще опишете работу с оным PHY и чем именно он хорош или плох будет еще лучше.
0
Главное его достоинство — это то, что его можно легко купить. Ну и в Терре отладочная платка продаётся недорого. Нареканий по работе у меня тоже нет.

Про подключение могу написать в отдельным постом, хотя каких-то сакральных знаний там нет. Соединил провода, проинициализировал пины контроллера, и всё заработало, по крайней мере на физическом уровне.
0
Самое полезное (кому-то, видимо HAL'о-говноCube'рам) в этой статье — это коротенький рассказ про Ctrl+X и затем Ctrl+V (перенос одной строки кода ниже на 12 строк).

Wireshark, ну туды-сюды, тык-тык, кстати, и референс мануал был стимул прочитать наконец-то полностью и внимательно, короче: "джентельмен в поисках десятки". Хотя самого себя автор представил, как некоего Мистера Вульфа в сфере MCU-електроники: серьезный и богатый заказчик, прибыл для усиления команды говнокодеров(видимо «дебилов»), не говоря уже о говнокодерах индусах.

Но судя по откликам — глупая и недалекая публика ждала чего-то большего.
-1
Боюсь разрушить вашу картину мира, но люди решают свои задачи теми способами, которые считают оптимальными. Заказчик весьма компетентен в своей области, и тот прибор, для которого всё делалось, достаточно интересный. Для него мой код всего лишь средство, а не цель.

Выбрали они в своё время Куб — значит сочли наиболее подходящим для себя. Для меня это был первый опыт работы с ним, и надо сказать, я ожидал внутри большего ужаса. На практике — достаточно юзабельная вещь, местами неоптимальная, но для быстрого подъёма железа вполне подходящая.

Заказчик в данном случае знал, чего хотел, и то, что я решил задачу в установленных им рамках, его полностью удовлетворило. Кстати, с чего вы взяли, что он богатый? Вменяемый и адекватный — да, хотя сейчас это дорогого стоит.

Про глупую и недалёкую публику вы это зря. Это не обучающий пост. Мне хотелось поделиться полученными патчами с обитателями сообщества, на сайте которого я нахожу много полезной информации. А рассказанная история просто в довесок, чтобы не было скучно. На сайте и так последнее время затишье.
0
Честно говоря, мне за индусов было обидно: у нас же как — индусы-говнокодеры, индусский код и т.п., ясно же, что у нас каждый «гигант мысли», но почему мы тогда в дерьме, а эти индусы(в том числе) двигают забугорный хайтек?

В коде Куба я, кстати, не нашел никакого лютого и конкретного именно говнокода. Просто многие считают, что такие прослойки сами по себе являются говнокодом, вне зависимости от качества его закодирования. А к Кубу я, на самом деле, отношусь чисто коммерчески.

А там просто ошибка(типа опечатки) — видимо красноглазят очень много — ну графики там, сроки, дедлайны… Чужие ошибки искать намного легче, чем выдавать на гора объемы по жесткому графику.
-1
индусы-говнокодеры, индусский код
Стереотип.
а эти индусы(в том числе) двигают забугорный хайтек?
Наши тоже двигают. Забугорный хайтек.
Чужие ошибки искать намного легче, чем выдавать на гора объемы по жесткому графику.
Хрен там. С точностью до наоборот.
+1
Хрен там. С точностью до наоборот

Обычно хватает просто прогнать и посмотреть в отладчике.

А в данном конкретном случае челу просто необходим был трассировщик J-Trace за 1-2 килобакса, хороший DSO (цифр.осцилл) или 100/200 МГц логич.анализатор. Возможно, что тогда можно было бы все сделать быстрее и даже без долгого медитирования над реф.мануалом.

Я даже год назад так вот решил проблему в 1С 8.3 (которую я нихуя не знаю — там только описание — 4 толстенных талмуда) одному «уважаемому и солидному челу». Нашел модуль/документ в конфигурации, с которым была проблема, и прогнал в отладчике — там просто оказалось, что не заполнена какая-то константа или поле в одном из справочников. Заполнили, и ошибка перестала вылетать и все стало считаться очень чудесно. Все сказали, что я «голова» и «гений», даже «заработал десятку» на один раз поесть в ресторане. А что там делается в этих портянках (а они там сотни и тысячи строк кода) я так и не понял и даже не смотрел, что смотреть, если ничего не понимаешь. Ну так-то все понятно: условия, циклы, свойства, методы, но что конкретно делают и для чего эти все объекты из объектной модели 1С — полный ноль понимания, только очень смутно, чисто по названию.
-1
Обычно хватает просто прогнать и посмотреть в отладчике.
Если бы…
0
Наши тоже двигают. Забугорный хайтек.
+100500
0
Рад, что мы достигли некоторого понимания.

Индусы — понятие скорее нарицательное, отражающее подход. Понятно, что ST зарабатывает не софтом. Спасибо, что раздаёт библиотеки и примеры бесплатно, ибо в том же референсе не всё всегда сразу понятно: желело сложное, протоколы тоже (это я всё про своё USB). Плохо то, что обратная связь, фактически, отсутствует. Завели бы багтрекер что ли. Думаю, и это, и отсутствие тестирования вина скорее менеджмента, нежели программистов.

Совершенно не хотелось казаться д'Артаньяном, который пришёл весь в белом и одной левой починил всё. Мне эти ошибки стоили неделю красноглазия. Печально, что библиотек для работ с USB было уже выпущено немеряно версий, а готового решения, работающего «из коробки», если сделать шаг в сторону от примеров всё ещё нет.

Например, нигде до сих пор не проверяется, открыт ли endpoint, в который вы собираетесь писать. Если данные шлются не по запросу, будет беда.
+1
А скорости при обычном (не DMA) обмене точно не хватало? Вроде 5 мБайт не так, чтобы запредельно при тактовой под сотню метров, или у Вас частота была зарезана?
0
Более 20 мбит/с не получал. Это на тактовой 168 МГц на железе, на котором больше ничего не крутилось. В реале там ещё сбор и предобработка данных с кучи АЦП, так что будет хуже.

Но надо понимать, что в текущей работе всё происходит по запросу от ПК. ПК шлёт запрос и ему в ответ приезжает блок данных. Потом опять запрос. Здесь сам ПК вносит задержку, поскольку код на нём крутится в user-mode, на него влияют переключения контекста задач.

Я, в своё время, пробовал непрерывно писать в bulk-endpoint на контроллере, а на ПК всё время вычитывал. Получал 26 МБайт/сек (с DMA на старой, до HAL-овской библиотеке), но данные периодически портились из-за переполнения буферов на ПК.

Если написать честный низкоуровневый драйвер с большими буферами, всё будет хорошо, но это задача несколько другого уровня.
+1
Человек нашел ошибку в библиотеке, которая делает невозможным определенны режим работы.
Это было нелегко, это Вам кажется что искать ошибки в чужом коде намного легче, чем выдавать на гора тонны мусора, на самом деле совсем наоборот — можете попробовать.
И вместо того, чтобы поблагодарить за проделанную работу, кое-кто встает грудью на защиту, не побоюсь этого слова, говнокодеров, с аргументами «а там просто ошибка (типа опечатки)».
Не знаю как кому, а мне глубоко по фигу на их сроки и почему ошибка возникла — мне достаточно того факта, что она есть и она принципиальная — не снижает скорость, а делает невозможным применение библиотеки.
А что касается кода Куюа — или Вы недостаточно внимательно его читали, либо у нас совершенно разные представления о качественном коде. В свое время Тойота за код именно в таком стиле заплатила весьма неслабые бабки. Просто включите правила MISRA и посмотрите на результат компиляции Куба, в котором Вы, кстати, ничего плохого не нашли.
+1
MISRA — это говно. Это мое ИМХО. Ну или чисто для автомобильных кодеров, т.к. это ихний стандарт и это ИХ проблема и ИХ попоболь. Что, почему-то, совершенно не помешало Тойоте говнозакодировать монолитный спагетти говнокод c гоуту и с магическими цифрами.

Писать в 21 веке на ANSI Си 89-го года, да еще кастрированном и выхолощенном MISRA по самое не могу на 70% его возможностей (это нельзя, это тоже нельзя, это опасно). Пусть эти мудаки идут нахуй, или создают себе для автопромышленности язык типа Паскаля или еще чего изначально ограниченного и защищенного. А лучше всего — пусть юзают готовые системы на ПЛК — там это уже все продумано — все что можно уже защищено и анально огорожено.

Нехуй им лезть в Си, да и ваще в MCU. Хорошо, что я не работаю на автопром (как и Линус и многие и многие другие) и могу спокойно обходиться без ихних иезуитских инквизиторских нравоучений. Лучше уже тогда ваще не изучать Си и не писать на нем, а сразу же уходить в программирование ПЛК или в говнокодирование на Java, ПХП или 1С.
-1
Бля, у меня аж подгорает! Так-то я не особо писатель комментариев клавиатурой не по делу, но.

Зачем вы себя ведете как школьник? Ну что это, блять, за херня? Или что это? Тут говно, там говно — везде говно! Или у вас весна, что ли? Вышли на улицу прогуляться, насобирали подснежников, и теперь «везде говно»? Не удивительно.

MISRA — нормальный стандарт. Все эти «тут нельзя, там нельзя», динамически нельзя, инициализировать только тут, и прочее. Все это имеет под собой здравое зерно и призвано обрисовать менее эфемерные рамки для того, чтобы создавать более безопасные системы. Прикладывать нужно просто правильной точкой, а не жопою, и все будет нормально.
Какая разница, на чем, блять, писать в каком веке? Есть бизнес (у вас от этого, что ли, бомбит?), есть бизнес-задачи, есть стандарты и инструменты, есть исполнители и есть результат. Если исполнители отлично справляются с задачей бизнеса, не гонят говнокод, то какая нахуй разница, какие они при этом используют стандарты и инструменты? Да хоть из палочек, камешков и желудей. Работает, стабильно, выполняет? Ок. Тем более, речь идет о проверенных временем палочках и камешках, а не о том, как сейчас принято у «модных и молодых»: возьмем NodeJS, и напишем на нем сервер нагруженной и важной информационной системы! Вот где мудаки живут. Да там хоть идеальный код вгони, сраный NodeJS сыпется сам по себе от каждого чиха. Поэтому и палочки, поэтому желуди, поэтому камешки. И клетка 2х2. Не нравится — не еште. А говнокод можно и из палочек сложить, будто бы тяжело очень.

Отладчик — хорошая штука и полезное подспорье. Но иногда валиться может в таком непредсказуемом месте, что отладчик не особо выручит (хоть и немного поможет). А еще бывают эрраты. Надо курить маны, читать существующие эрраты, вкуривать в код. Все равно. Мы находили пару эррат в 407, промудохались знатно. И таки-да, что-то пробовали писать в ST — толку ноль. Забили хуй.

Касательно куба. Это инструмент, хороший коммерческий инструмент с хорошей задумкой, на самом деле. Более того, пользуемся им в разной степени постоянно. Особенно по лапкам пощелкать, чтоб мозги не напрягать понапрасну. Что касается его библиотек. Ну, как сказать. Дареному коню в зубы не смотрят. Код там странный, местами неоптимальный, много косяков (косяков, а не опечаток!). Периодически то железо косо инициализируется, то маллочница пробирает, то еще что-то. За индусов (индийцев все же?) говорить не буду — китайцы, русские, СШПцы, европейцы (блять! какой у них криворукий код в большинстве) — все косячат одинаково. Просто применять все это надо, опять же, с умом. Где-то, где надо релёй щелкнуть, лампочкой мигнуть и уснуть — пойдет (хотя, с кубом можно внезапно не проснуться после этого). Где-то, где нужно быстродействие и уверенность, а не слабоумие и отвага — курить маны, писать код. Можно и кубовский за основу взять, хотя, как выяснилось в работе, проще сразу начать свой писать. Вот и все. А чужие косяки искать — очень муторная тема.
Опять же, все выщелачивается до тупо точки приложения, которая должна быть не жопою, а головою.

P.S. А что, если Java, то сразу говнокодирование? За такой гниловатый базар можно и ответить ведь.
+3
Воу-воу-воу, сколько экспрессии! :) Я даже с трудом вспомнил пароль и авторизовался тут, чтобы расставить плюсы-минусы и написать этот комментарий. :D

Так-то я тоже адепт MISRA и периодически воинствующий противник кубических ардуин. :) Давайте глубоко вдохнем, выдохнем и пойдем дальше рисовать схемы и писать код, оставив некоторых наших коллег за изготовлением мультивибратора из STM32F4. Все равно заказчик, намучившись с такими решениями, в итоге придет к нам. ;)
+1
Уважаемые адепты MISRA, существует ли бесплатное средство проверки правил MISRA, могущее работать совместно с GCC ARM?
0
Я не знаю такого, лично я пользуюсь IAR (обязательно нужно лицензионный, ну или… Вы поняли) но у него свой компилятор и ни фига не GNU.
0
В платных понятно, что есть. В демке Keil пробовал, понравилось.
Но лицензия дорогая, а за… ну вы поняли… у нас расстреливают.
0
Мне особенно понравилось сравнение с Линусом. Сразу вспомнилось «Галантерейщик и кардинал — страшная сила». Очень классно звучит от человека, который, судя по его комментам, не способен понять, что такое надежный код.
+3
Причем здесь Линус.

Ядро Linux значит написано с учетом всех обязательных (99 для MISRA C 1998, 121 для MISRA C 2004) её правил? Как насчет другого ПО, в частности для MCU?

Треть этих правил — боян, они были известны и применялись без всякого упоминания MISRA.

Еще треть — просто спорны.

Ну и последняя треть по тем или иным причинам просто не будут выполняться многими кодерами, т.к. являются чистым и тупым бюрократизмом и ущемлением свободы воли и выбора ПРОГРАММИСТА и заказчика.

Намного проще тогда уже — просто исключить язык Си, как потенциально очень опасный, из многих сфер человеческой деятельности. MISRA — это чистая бюрократия, ее надо почитывать, но тупо следовать всем ее указаниям — не нужно, конечно, если это не прямо указано в ТЗ (любой каприз за ваши деньги).
0
Флаг Вам в руки и паровоз навстречу.
Жалко Ваших заказчиков (если они есть)которым придется отдуваться за супер программистов, которые не желают ущемлять свою свободу воли (то есть свободу писать гавнокод) и следовать правилам, часть из которых для нормальным людей (не супер программистов с раздутым ЧСВ) очевидна и должна соблюдаться, часто менее очевидна и совершенно не спорна, поскольку спорить там не о чем, НИКАКОГО вреда следование правилам причинить НЕ МОЖЕТ, а польза несомненна, а часть в стандарте честно названа рекомендованной, а не обязательной.
«В Уставе караульной службы каждая строчка написана кровью людей, которые пытались делать по-своему» — вперед на грабли, они Вас заждались.
«Обычный человек учится на своих ошибках, умный — на чужих, дурак не учится вообще» — мне кажется, мы имеем в Вашем лице последнюю категорию.
+1
Ну наконец-то, срач дискуссия все же разрастается.

Дело в том, что тупое следование ВСЕМ рекомендациям MISRA, во-первых, просто не возможно. о чем и сообщается в доках на MISRA-C Compliant ПО, например, вот MISRA-C violations in CMSIS library.

Во-вторых, это совершенно не спасает от ошибок или говнокода, о чем и рассказывается в этой статье, т.к. либа STM32Cube HAL тоже MISRA-C Compliant.
-1
MISRA защищает от подводных камней С, а не ошибок логики. Если лабать код, даже не проверяя что на выходе получилось, то естественно будет как в топике.
+1
У Вас явные проблемы с логикой.
Если кто то не следует рекомендациям, то жто совсем не означает, будто бы им нельзя следовать.
Почитайте MISRA и приведите хотя бы 1 пример взаимоисключающих требований, из за чего действительно невозможно им следовать.
Да, рекомендации не спасают от ошибок (офигеть, какое тонкое наблюдение), но позволяют устранить наиболее часто встречающиеся.
Согласно Вашей логике, раз мы все умрем, то почему бы не сделать это пораньше? Жду, подтвердите верность своих слов поступком.
+2
Я же уже писал, что третья часть из этих рекомендаций и так выполняются кодерами, т.к. давно известны и описаны в разной лит-ре.

Но почему, вдруг, я должен отказаться от C99 и писать на С90/ANSI C89, отказаться от прерываний в коде (каково? занятно прочитать такое на MCU ресурсе), даже комментарий в виде // мне запрещён.

Или вот, например, битовые поля запрещены, а челу надо писать код под TI DSP MCU, а там спецом, в хедерах, описывающих регистровый name_space, они изначально использованы самим TI. А рекурсия? И если надо обрабатывать древовидные данные, или нужен некий компилятор (лингв.разбор).

И т.д. и т.п. Здеся разговор очень долгий может быть, если конкретно разбираться — на целую книжку потянет.
-1
If it is being relied upon, the implementation defined behaviour
and packing of bitfields shall be documented.
Да, это разговор долгий, надо уметь читать а это сложно, проще написать чушь.
Покажите, если нетрудно, где в этой фразе запрещают битовые поля?
Остальные Ваши высказывания о MISRA не лучше и показывают полное незнакомство с предметом.
+1
даже комментарий в виде // мне запрещён.
Проблемы кросскомпиляторной совместимости (сюда треть мисры смело попадает).
Или вот, например, битовые поля запрещены, а челу надо писать код под TI DSP MCU, а там спецом, в хедерах, описывающих регистровый name_space, они изначально использованы самим TI.
TI можно, так как хедеры они делают под конкретный процессор и конкретный компилятор, где требуемое поведение специфицировано.
Стоит заметить, применение битфилдов везде, где их реальная аллокация в памяти имеет значение — противоречит стандарту С (6.7.2.1 пункт 11). Независимо от того, следуем мы мисре или нет. Стандарт не определяет хранение битфилдов и если оно таки работает как надо — это досадная случайность.
А рекурсия? И если надо обрабатывать древовидные данные, или нужен некий компилятор (лингв.разбор).
Любой рекурсивный алгоритм можно реализовать итеративно, зачастую еще и выиграв в производительности (характерный пример — числа Фибоначчи, итеративно считающиеся как бы не на порядки быстрее) и не рискуя вломиться в дно стека.
0
Ну не читал человек MISRA. Ему кто то что то рассказал вот он и делится сокровенным знанием ни очем.
+1
А что Вы орете, дорогой камрад GarryC? Вы думали, что я сдулся? Ан нет, я просто находился под гипнозом другого ресурса.

Вы же сами и раздули этот MISRA-срач, упомянув, что де либу STM32Cube_HAL (которую Вы, в отличии от меня, считаете абсолютным говнокодом) надо проверить на правила MISRA. Тем не менее, она уже MISRA-C 2004 compliant :) Специально нашел в HAL driver User Manual, оказывается и HAL, а я думал, что только CMSIS.

И потом, Вы кто такой? Вы Лайфловер, Л_И или сам ChaN, чтобы я к Вам прислушивался? Где Вы применяете MISRA-C, покажите нам этот код, где Ваши статьи на тему применения правил MISRA-C в кодировании для MCU, если Вы такой фанат этого стандарта.
-2
Так все таки, где в приведенном мною правиле
«If it is being relied upon, the implementation defined behaviour
and packing of bitfields shall be documented.»
Вы нашли сведения, позволяющие утверждать, что
«Или вот, например, битовые поля запрещены».
А для того, чтобы проверить на совместимость со стандартом код, надо не искать соответствующее утверждение в мануале, а просто включить в IAR соответствующий флажок, задать правила, провести компиляцию и посмотреть на полученный листинг.
Сделайте это и вот тогда поймете, что ни одна их перечисленных Вами библиотек правилам НЕ УДОВЛЕТВОРЯЕТ.
Может быть, есть другая MISRA, так поделитесь сокровенным знанием, иначе складывается мнение, что Вы просто пишете чушь, не зная стандарта.
+1
Да отцепитесь вы от меня, пристал к человеку!
Вот видите значок у меня на лацкане пинжака?

А вот мой членская книжка.

-1
Проблемы кросскомпиляторной совместимости (сюда треть мисры смело попадает)
Вот об этом я и говорил, что не хочу по ихней прихоти уходить с C99. Мне это не надо — мое «уютненькое» — это ARM Cortex-M + C99, который в GCC/IAR/KEIL уже давно стандарт по дефолту, и больше мне ничего не надо. Хотя, вроде бы в MISRA 2012 они может и включили поддержку C99, но это надо внимательно изучать MISRA 2012. Вот ты и попробуй найти в сети этот стандарт (он ваще-то платный) и внимательно прочитай, а потом расскажи нам. А мне лень — мне и MISRA 98/2004 хватило.

А про битовые поля, ты просто еще раз доказываешь, что надо головой думать в Си и просто хорошо знать свои ecosystem & environment, чем тупо следовать каким-то правилам, навязанным сверху.

С рекурсией соглашусь, тем более рекурсивный алгоритм хоть и намного короче, но бывает труднее в понимании со стороны и в отладке. Хотя и рекурсивный алгоритм достаточно просто можно защитить от переполнения стека досрочным завершением. Про Фибоначчи — это плохой пример, здесь рекурсия чисто в учебных целях и не нужна, но вот если надо построить двоичное дерево разбора чего-либо — рекурсия хороша, а сами элементы дерева и строится в стеке по ходу алгоритма (рекурсивный спуск). Просто надо резервировать необходимый стек и считать итерации, чтобы они не превысили допустимый максимум.
-1
Вот ты и попробуй найти в сети этот стандарт (он ваще-то платный) и внимательно прочитай, а потом расскажи нам.
А схуяли, собственно, я? Я вообще предпочитаю с си не связываться. Кстати, к иару прилагается копия стандарта, хотя и вроде несколько кастрированная.
надо головой думать в Си
Головой всегда надо думать. А правила не с потолка взяты. Это шишки, набитые программерами за десятилетия (здесь я уже не только о мисре). И даже если тебе кажется, что ты делаешь под конкретное окружение, которое знаешь — это нифига не значит, что через полгода не придется куда-то портировать, сполна хлебнув последствия закладывания на implementation-specific.
но вот если надо построить двоичное дерево разбора чего-либо
Дерево тоже можно итеративно обойти. Особенно если нужен нетипичный алгоритм обхода, например послойный. Да и не требуется обход деревьев в эмбеде, обычно. А не в эмбеде куда раньше ты забьешь на правило «не использовать динамически выделяемую память».
0
через полгода не придется куда-то портировать, сполна хлебнув последствия закладывания на implementation-specific
А я хитрожопый и ловко устроился в этой жизни, и мне портировать/совместимость_соблюдать надо только в одной экосистеме от M0 до M4F. До пенсии мне хватит ARM Cortex-M.

Кроме того, я и так стараюсь соблюдать треть правил MISRA, которые полезный боян. Ты меня уговорил — надо выписать их все в список и проверять, а на остальные просто забить.
0
Вообще чужие ошибки искать ебанесся-) Особенно в объемном коде. Особенно если нужно срочно-)))
+2
В припадке альтруизма я решил поделиться найденными ошибками с разработчиками из ST: написал сообщение на форуме, приложил файлы. Прошло уже несколько дней — никакой реакции.
Тисните тему в форум ST (https://community.st.com/community/stm32-community/stm32-forum/content). Там живет clive и некоторые разработчики, которые быстро отвечают и принимают к сведению.
+1
Так я туда и написал. На текущий момент 50 просмотров и ни одного ответа.

Я смотрю, тут такая битва развернулась. Не думал, что тема настолько холиварная.
0
О, тема сторонний код vs свой велосипед очень холиварная. И далеко не только в embedded.
0
какая плата использовалась? Я запустил на макетке USB3300+stm32f4discovery, софт USB HS аудиокласс (UAC1), по EP0 всё проходит нормально, а вот звука нет. Когда принудительно с тем же софтом ставлю скорость в коде full speed, всё работает как надо.
0
stm32f4 Discovery с выпаяной кое-какой периферией, которая пересекалась по пинам с PHY.
По идее, если по EP0 прошло всё нормально, физика работает. Далее дьявол в деталях — dedicated IRQ, размеры пакетов, буферов и т.д.
0
осталось проверить это на stm32f723 со встроенным USB HS
0
Уважаемый автор, как с вами связаться? Личная почта здесь почему-то не работает.
0
Личная почта здесь почему-то не работает.
Работает, почему нет?
0
Да вот что пишет, когда нажмёшь «Отправить»:
Notice: Memcache::get(): Server localhost (tcp 11211) failed with: Connection refused (111) in /home/a146/www/we.easyelectronics.ru/engine/lib/external/DklabCache/Zend/Cache/Backend/Memcached.php on line 134
0
Письмо, однако, отправляется, только что заметил!
0
Вот именно. Вообще, сам по себе этот баг не фатален. Но в некоторых случаях гадит:
1) Страничка не может распарсить AJAX-ответы, замусоренные этим хламом — из-за этого «обновить комментарии» и подобные функции работают через раз.
2) Перенаправления ломаются. Поэтому вместо попадания на страничку отправленного письма ты видишь сообщение об ошибке.
3) При загрузке файлов этот мусор попадает в начало файла — от чего он естественно портится.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.