Pull to refresh
166
-1
Павел Локтев @EasyLy

Системное ПО, инструменты для разработчиков

Send message

Оххх. У меня как навалятся студенты, так не до Хабра становится. По отсутствию статей видно, в какие семестры они наваливаются... Прошу прощения, что не заметил этого вопроса.

Правда, хорошего всё равно ничего не скажу. Началось с того, что наш Заказчик принципиально отказался от устройств на базе Litex. Потом он вообще сместил фокус на контроллеры... А для души - то студенты, то... Выяснилось, что эффективную процессорную систему на этой базе всё равно не сделаешь. Эффективность ядра SDRAM просто смешная. Только если шинами пользоваться для связи своих модулей, а не как ЭВМ. А с ними своя беда. Латтисы закрылись для нас после начала СВО. И биться головой о стену для не самых лучших в мире ПЛИС я не вижу смысла. Если бы они были доступными - ну куда ни шло. А так - ну не рады, и не рады. Без них обойдёмся. Если биться головой, то кому из-за Ксайлинкска, а мне - из-за Альтеры ... У Альтеры же есть QSys.

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

Всё в порядке, разбирались по заказу от товарища не из нашего ВУЗа, от товарища из Америки (слегка переделанная цитата из фильма "Дежа вю").

Но там была целая цепочка разных контроллеров. Вот тут, например, я описывал, как мы нашли в одном из них аппаратный баг. В другом (GD32F107) нашёлся баг поинтереснее. Его сетевая аппаратура зависает, если длина Ethernet пакета кратна четырём, а используется кольцевой буфер DMA. В фирменных примерах буфер используется связный, с ним такой проблемы не возникает. Но там материалов не на целую статью, поэтому я пока не стал писать, надо с чем-то объединить. В общем, если смотреть на весь объём работ, то там много интересного было. CH579 был быстро обследован, выводы сделаны, быстро Заказчиком отброшен.

Пробежал глазами по Zhele. На вид довольно интересно. Спрошу наверное самый стандартный вопрос, какая разница в ресурсах/производительности относительно реализации на Си?

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

Там главная прелесть в шаблонах. Этот шаблон один раз объявил, у тебя появляется имя, к которому можно ссылаться. На чистых сях это можно сделать только через макросы. Но макросы второго или большего уровня - совершенно нечитаемы. И абсолютно не типизированы. Запутаться легко. Шаблоны - и легко понять, и предупредят, если неверно используешь.

Можно строить целые цепочки драйверов. Скажем, ножки GPIO, над ними SPI, над ними - экран, над ним - графическая библиотека. Любой кирпичик можно заменить. Ноги другие выбрать у того же SPI, выбрать другой SPI, заменить SPI на I2C с его ногами и т.п. Цепочки получаются - прелесть. Оптимизация - высшая! Прозрачность кода - все связи в одном месте через typedef прописаны, дальше - по именам внутренним обращения. Все замены - внутри этого заголовочного файла.

Если же хранить какой-то дескриптор в ОЗУ, а не через макросы/шаблоны делать - там процессор каждый раз цепочку от этого дескриптора должен раскручивать, тратя такты. В случае макросов или шаблонов, всё оптимизируется на этапе сборки. Ассемблерные команды сразу к портам лезут, так как их адреса заранее известны, даже через цепочку.

В наше время оптимизаторы в режиме LTO творят чудеса. Можно будет перепроверить, не будет ли всё так же красиво разрулено при вызове цепочки функций, где первая вызвана с константным аргументом. Но как Вы верно заметили, инертность... Когда-то потратил почти месяц, чтобы найти хорошее решение, теперь тратить ещё на перепроверку - лень. Всё ведь и так работает! Но факт того, что оптимизаторы ушли вперёд - я заметил.

Что касается Zhele - я помогал автору оптимизировать работу с USB. Он там в итоге добился двухбуферной схемы, что позволило выжать из USB все соки, но вылезли проблемы, которые мы ловили совместно. Фирменная библиотека от ST этого не позволяет. Причины туттут - продолжение неожиданное). И вообще, работа с USB там классная. А дескрипторы строятся - вообще автоматически. Не то, что в Сишных реализациях. Поправить на Сях - целый процесс. Поменяй данные, поменяй длину. Тьфу!

не пойму почему под него разработчики микросхем не делают шаблоны.

К слову... Вот я - фанат библиотеки Константина Чижова mcucpp. Ну, и её наследницы Zhele. А вокруг почти никто не может прочувствовать их круть. Я, конечно, удивлён, что никто не хочет их использовать... Но это не мешает мне совать их во все более-менее серьёзные собственные проекты. Мне нравится - я пользуюсь. Другим продвигаю, но к тому, что мало кто фанатеет, отношусь философски. Их проблемы. Я-то пользуюсь...

Ну, начнём с того, что чисто официально этот Qt в России сегодня не скачать

Продолжим вопросом лицензии на использование Qt Creator (хоть и не фреймворка) для коммерческих проектов.

Но повторю... Вот у меня в Qt Creator при отладке под Windows иногда совершенно рабочие функции просто вылетают, если в них поставить точку останова. Пробегаем мимо этой функции - всё работает. Каждый раз приходится с бубном плясать, чтобы найти проблемное место. Причём суть проблемы обычно не ясна. Просто ушаманивать приходится. Чуть иначе проблемную строку перепишешь - начинает работать. Не любит меня Qt Creator, хотя под Windows я в последнее время им часто пользуюсь.

Но на самом деле... Каждый любитель той или иной среды разработки почти всегда может сконвертить в неё проект из другой среды. Производители CH579 любят Кейл, но мы под Эклипсу его быстро преекинули.

Да там проект разросся на кучу разных китайских процессоров, даже с разными ядрами (M3 и M4). Плюс кучка прочих опций. Заказчик сказал, что надо делать на CMake. Но я там только сбоку смотрел и при затыках идеи кидал. Делал напарник. Решили, что Qt Creator с этим лучше всего справляется. Он действительно справился на ура.

К сожалению, добра Заказчик на публикацию материалов не дал. К счастью, не так этих материалов и много. Самое главное я на словах изложил.

QT Creator для работы с Cortex M мы рассматривали, когда от нас потребовали проверить, что можно работать через CMake. Попробовали, всё получилось. Тот путь, что мы использовали, требовал слишком много подготовительных действий. Целую инструкцию на экран или два текста выполнить. Может быть, какие-то действия можно было и автоматизировать, не могу точно сказать.

Но каждый использует то, что ему нравится. Всё равно все среды разработки так или иначе завязываются на GDB или LLDB. Они, в свою очередь, могут опираться среди прочего на OpenOCD или J-Link. Поэтому на что опереться - тут показано (скачать китайский OpenOCD и работать через wch-link, либо взять JLINK и поправить ему конфиг). А дальше - всё, что сверху - заработает, кому бы что бы ни нравилось.

Лично мне очень нравится Эклипса. Ко мне она почему-то весьма дружелюбно относится. И в ней максимум всего автоматизировано. Напарник мой всё больше к VS Code тяготеет. Вам, вон Qt Creator нравится, но вот у меня к нему при отладке Виндушных приложений вопросики есть, поэтому я его не жалую и в других местах. Это же замечательно, когда каждый может выбирать что-то своё!

Похоже, без приоритетов

extern bStatus_t tmos_start_task( tmosTaskID taskID, tmosEvents event, tmosTimer time );

Там есть события (event), сообщения (msg), таймеры. Из того, что вижу - в целом, всё.

Нам доступен только заголовочный файл, так что менять нельзя. Весь стек на это дело сильно завязан. Пользовательский код тоже на taskах построен. Как именно - я глубоко не погружался. Мне показалось, что это - не самый полезный контроллер для BLE, я решил другие поизучать, когда будет время свободное.

А возможно ли подключить через JTAG (SWD) на основе FT4232?

Всё та же проблема. Вот прямо взять готовое - скорее всего, нельзя. Сделать поддержку в OpenOCD - можно, только надо время потратить (унифицировать китайский вариант или скопировать загрузчик оттуда в основной, творчески переработав обращения к нему). В коммерческих проектах после фразы про время обычно сразу всё заканчивается. Не любят Заказчики за такое платить. Особенно если находится готовое решение.

Хотя UART бы тоже устроил, если бы хоть протокол обмена известен был.

А любым монитором порта если поглядеть? Вдруг там будет видно, что к чему?

Спасибо за информацию.

В целом, у нас программа простенькая

text data bss dec hex
20252 1112 48400 69764 11084

Но информация пригодится! Спасибо!

Я переводил их карту в режим LoopBack, вставлял на передачу пакеты из статьи, но КС добавлял чип сам. Да. На приём приходило вместо нуля FFFF. Скорее всего, на эти.

Какая соль? Это контрольная сумма заголовка. Заголовок формирует операционная система. Мы туда только IPшники и порты передаём. Остальное (включая MAC адреса и даже наш IPшник) заполняет ОС. Мало того. Если я ничего не путаю, при прохождении через маршрутизаторы, порт и даже наш адрес могут поменяться. Правда, это я просто нутром чую. В рамках нашего проекта такое не проверялось.

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

А в целом - довольно удивительно подстраивать протокол под ошибки конкретного контроллера. Сколько этих контроллеров в мире? Вот мы сейчас по указанию. Заказчика переходим от опытов с GD32 к CH32. Если там найдётся какая-то ошибка, учитывать и её?

Мы просто нашли, как устранить проблему на уровне прошивки и успокоились. А как ответственный человек, я поделился знаниями со всеми.

Конкретно у GD32 с делителем всё хорошо. В отличие от STM32, она поддерживает частоты до 200 МГц. Само собой, в проекте установлена именно эта частота. Так что для получения 50 МГц, деление целое.


/* choose DIV2 to get 50MHz from 200MHz on CKOUT0 pin (PA8) to clock the PHY */ rcu_ckout0_config(RCU_CKOUT0SRC_PLLP, RCU_CKOUT0_DIV4); syscfg_enet_phy_interface_config(SYSCFG_ENET_PHY_RMII);

В свою очередь, на той конкретной плате 200 делается из кварца на 25 МГц.

Но спасибо за технологию. В будущем может пригодиться где-нибудь.

Документация на GD32 весьма толковая и написана явно с нуля (ну, то есть, пересказана, а не просто переведена на китайский и потом обратно на английский). Хотя, разумеется, и близка к оригиналу. Но по крайней мере, ни разу не пришлось кричать: "Да что же там такое?" и открывать оригинал. Только GDшную штудируем в рамках этого проекта, а раньше с блоком Ethernet я не сталкивался для STM32.

И надо отметить, что библиотеки у них написаны даже красивее, чем у STшников. Кто-кто, а программисты у STшников странно пишут. У китайцев стиль, конечно, интересный, но оптимальность у библиотек для доступа к железу - на высоте. Я не со всеми решениями согласен, но то, что в рамках проекта более, чем в 50% случаев работаю через их библиотеки - это о многом говорит. Кто их писал, тот молодец.

Там путаницы в коде много. Как они тактовую частоту настраивают - это эталон путаницы. Там всё пришлось выкинуть и написать заново. Но доступ к железу, да на втором уровне оптимизации, да со включённой оптимизацией во время компоновки... Конфетка! По крайней мере, по сравнению с оригинальными STшными решениями.

Cпасибо, маркировку поправил.

Про то, что STM32 тоже может дурить - понятно. У нас две NUCLEO просто работали, на том и остановились. Но в целом, вывод в тексте всё равно универсальный, так что его править не нужно.

В общем, если у вас проблемы, проверьте, не PLL ли их создаёт. Возможно, стоит потратиться на внешний генератор именно для PHY.

А про то, что это не только у GD32 бывает - пусть в комментариях будет.

1) CRC (он же контрольный циклический код) - у всего пакета. А у заголовка - арифметическая контрольная сумма, она же CS

2) Заголовок формируется на уровне Операционной Системы. В обычной ситуации, мы на него не можем повлиять . Для исследований, можно слать пакеты через PCAP драйвер, как я описывал тут. В обычной же ситуации, мы открыли сокеты, и шлём данные. А оборачивает в пакеты их ОС. Как я показал, посылая абсолютно идентичные данные, мы получали потерю каждого 65536-го пакета, потому что одно из полей в каждом следующем пакете увеличивает именно ОС. Прочие поля (и их тоже заполняет ОС) не меняются. Поэтому плохая КС получается раз в 65536 посылок (поле, которое увеличивается - 16 битное, КС - тоже).

3) К счастью, контроль CRC всего пакета и CS заголовка - разные операции. Поэтому на уровне контроллера, мы отключили проверку CS заголовка, но оставили контроль CRC пакета. Поэтому если данные исказились при передаче, с очень большой вероятностью, такой пакет будет отброшен.

Ну STM32 примерно так и работает. А вот GD32, если видит в этом поле входящего пакета ноль, то игнорирует такой пакет. При этом не выявлено каких-либо флагов ошибки. По крайней мере, мы ставили точки останова на участки, где в дескрипторе вернулся признак ошибки. Ни разу не сработали. И те счётчики ошибок в портах, что мы мониторили - не увеличивались. А пакеты именно с таким признаком именно GD32 - теряли.

Что касается флагов ошибок - может не то смотрели, может где-то что-то и отмечалось. Но что настоящий STM32 в тех же ситуациях ничего не терял - факт. Отключение проверки контрольных сумм заголовков решает проблему - тоже факт.

Это что. Мне однажды свалился баннер - купите отечественный RISC-V контроллер. Ну я зашёл. Ага! Не купите, а запишитесь на покупку. И когда он будет доступен, то у него будет 8 килобайт флэша... При том, что по моим ощущениям, RISC-V с Compressed командами требует в среднем вдвое больше памяти для кода, чем Cortex M. А самая базовая голубая пилюля 64К флэша на борту имеет...

В общем, всё познаёмся в сравнении. Тут - пойманные проблемы неприятны, но пока не смертельны.

В полном соответствии с логикой STM32, с которым эти контроллеры функционально совместимы. Причём настолько совместимы, что вот у STM32F10X MAC намного проще, чем у STM32F4.... Поэтому у GD32F107 MAC похож на STM32F107, а у GD32F450 - на STM32F4. У первой парочки, скажем, нет расширенных дескрипторов.

А так - там на уровне MAC ещё и аппаратная поддержка PTP имеется. У всех выше перечисленных. И опять же, парочка STM/GD32F107 имеет логику PTP попроще, А которые F4 - покруче. Всё совместимо.

У меня такой печальный опыт общения с первыми линиями разных техподдержек, что я без нужды к ним не обращаюсь больше. Обычно никому это не надо у производителя. А если кому-то и надо, то пока до него прорвёшься... А смысл?

Конечным пользователям будет полезно - я задокументировал. Заказчик в Штатах тоже в курсе теперь. Возможно, он с производителем свяжется.

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Registered
Activity