image

Как отлаживают программы микроконтроллеров? Берется JTAG, осциллограф – пара дней/недель и программа отлажена. Таким будет типичный ответ, и в большинстве случаев он будет правильным… Но не всегда. Микроконтроллеры решают очень разные задачи, и в этой статье мы рассмотрим, что делать, если нужно разработать громоздкое ПО низкоуровневого управления каким-либо силовым электрооборудованием, например, преобразователями частоты для электродвигателей, DC/DC преобразователями заряда АКБ для поезда, корректорами мощности, сервоприводами и т.п. Оборудованием, где протекают килоамперы и ШИМят киловольты, где на счету каждая коммутация IGBT ключей инвертора, где время реакции микроконтроллера на нештатную ситуацию измеряется в микросекундах, а само оборудование в герметичных корпусах устанавливается и эксплуатируется где-нибудь на заводах Якутии. Если вы хотите узнать, какие особенности это накладывает на способы отладки – добро пожаловать под кат.


Особенности отладки систем управления


В чем же особенности отладки микроконтроллеров (МК), выполняющих такие задачи? Во-первых, когда МК работает с силовым оборудованием, его нельзя останавливать. МК при помощи ШИМ управляет силовыми ключами, регулирует множество величин в своих коридорах – токи фаз двигателя, напряжение звена постоянного тока, частоту вращения, положение рабочего органа и т.п. Если остановить МК во время работы на точке останова, то в лучшем случае оборудование отключится по аппаратной защите, а в худшем всё просто взорвется (если силовые ключи останутся включенными в «одном» положении или с одним заданием скважности). Поэтому классический способ отладки – «пройти по шагам отладчиком» в таких задачах не работает. Так можно только обкатать «на столе» совсем сырые программные модули перед их первым включением на реальном оборудовании.

Во-вторых, это сложность низкоуровневого ПО. Размер секции программного кода .text 50-200 Кбайт для программного кода, управляющего исключительно аппаратной частью (без высокоуровневых коммуникационных драйверов и т.п.) – это типичная ситуация для микроконтроллера какого-нибудь промышленного сервопривода. Поэтому для таких задач используют микроконтроллеры серии motorcontrol, которые сочетают в себе одновременно и очень развитую периферию, и высокую производительность, и относительно большой (для МК) объем памяти. В качестве примера из импортных МК можно привести 32х разрядные МК Texas Instruments серии C2000, из отечественных чип К1921ВК01Т ОАО «НИИЭТ». ПО для таких МК обычно содержит десятки или сотни тысяч строк отборного оптимизированного Си/Си++ кода, которые просто невозможно отладить «миганием светодиодиком», «printf’ом в UART» или наблюдением работы ножек МК внешним осциллографом.

В-третьих, контроллер системы управления электроприводом чаще всего стоит внутри силового преобразователя, корпус которого закрыт, а иногда даже загерметизирован. Поэтому доступ по JTAG – уже большая проблема хотя бы только для прошивки (с выключенным силовым питанием). И еще более серьезная проблема – отладка по JTAG с включенным силовым питанием. Здесь должен использоваться обязательно гальванически-развязанный и помехозащищенный JTAG (мы используем для МК TI JTAG SAURIS со встроенной гальванической развязкой – дорого, но работает).

В-четвертых, никаких операционных систем! Можно предвидеть, как у некоторых в голове крутится мысль «ну раз у вас такая сложная задача, поставьте нормальный микроконтроллер с Linux и пишите под него обычные приложения, обновляя ПО с флешки». Системы управления силовым оборудованием – системы очень жесткого реального времени. Не то что Linux, даже не все специализированные ОС реального времени подходят для таких задач. Например, прерывание АЦП по считыванию и усреднению аналоговых данных может вызываться с частотой до 100кГц. При этом оно будет содержать всего десяток-другой строк кода – сбор данных аналоговых каналов, пара проверок быстродействующих защит и выход – всё, больше ничего не успеть. Если поручить такое прерывание какому-нибудь планировщику задач ОС, то просто его собственное выполнение будет занимать больше ресурсов. Не говоря уже о том, что, в частности, для Linux вместо одной микросхемы МК на плату надо поставить еще две – внешнюю оперативную и флеш-память, отведя на них кучу драгоценных ножек кристалла, использовать шестислойную плату для правильной разводки, получить огромное время загрузки МК (иногда при сбое питания или срабатывании сторожевого таймера надо начать работу раньше, чем двигатель успел остановиться!), иметь проблемы с целостностью файловой системы и прочее.

Ну и пятая особенность – системы низкоуровневого управления электроприводом и другим силовым оборудованием (в отличие от задач коммуникации по разным интерфейсам, ПЛК, контроллеров всяких сигнализаций, пультов и прочего) реализуют в основном алгоритмы систем автоматического регулирования. А именно: софт наполовину состоит из различного рода замкнутых структур с ПИД-регуляторами, блоками насыщения, мертвой зоны, таблиц зависимости одного от другого, фильтрами, наблюдателями, задатчиками интенсивности, планировщиками движения и прочим. Вычисления в таком ПО выполняются с определенной частотой – скажем, на частоте 10кГц вызывается прерывание и обсчитывает все перечисленные блоки, которые вместе образуют нужную структуру управления оборудованием. В таких алгоритмах пошаговая отладка не помогает – чаще всего на каждом шаге каждый модуль выдает то, что от него ждут – собственно, все эти фильтры, регуляторы и прочее уже отлажено годами и сюрпризов там мало. Проблемы возникают при работе всей структуры в целом – каждый блок по отдельности работает, а желаемый процесс регулирования происходит не так, как ожидается. И проблемы оказываются как в настройке сотен параметров и коэффициентов этих блоков, так и в самой собранной из них структуре – может статься, что нужно добавить новый контур стабилизации чего-то где-то, добавить блок предсказания, ограничения и т.п. Поэтому это очередной «камень в огород» пошаговой отладки и отладочных сообщений printf: отлаживать нужно чаще всего не сам программный код, а собранную структуру автоматического управления. Если кто-то слабо представляет себе, что это такое (структура), то вот простейшая структура бездатчикового векторного управления синхронным двигателем:



Каждый квадратик – это иногда несколько формул, а иногда модуль на десяток-другой страниц кода. У модуля есть входы/выходы, а также некоторые переменные состояния (например, интегральная часть ПИ-регулятора и прочее). Также желающие могут посмотреть аналогичную структуру на странице википедии. Так как система управления замкнутая, то неправильная работа одного блока (или неправильная его настройка) приводит к неработоспособности всей структуры. И найти, где именно проблема – та еще задача.

Как же это отлаживать?


Итак, что же делать, как это отлаживать? Внешний осциллограф? Не поможет. Осциллограф, конечно, необходим для отладки некоторых чисто аппаратных проблем, но им можно лишь увидеть входные и выходные величины микроконтроллера, а сотни переменных внутри структуры останутся за кадром. Ну увидите вы, что ток фазы двигателя странно дергается, и странно дергается выходное напряжение инвертора. А почему – какой блок внутри ПО МК к этому приводит (или к этому приводит кривой двигатель или датчик положения или ещё что) – останется непонятным.

Модель? Да, это хорошее подспорье. Чаще всего разработка сложных структур управления начинается с моделирования. В терминах ТАУ и в виде дифференциальных уравнений описывается объект управления, строится предполагаемая система регулирования (как на рисунке выше, например), а далее всё это реализуется… ну, кто в чем любит, но стандарт-де-факто – это Simulink Matlab. В нем можно «нарисовать» структуру вместе с моделью объекта управления, используя «рассыпуху» в виде интеграторов, сумматоров, переходных функций и т.п. Можно воспользоваться его пакетом по моделированию электрических цепей, где есть готовые IGBT ключи, электродвигатели, резисторы, конденсаторы и прочее, отдав на откуп программистам матлаба реализацию нарисованного в виде дифференциальных уравнений, а саму структуру управления нарисовать уже в виде «рассыпухи» самому. А еще можно написать все нужные блоки в матлабе на Си. Этот способ удобен тем, что отлаженный программный код в матлабе можно просто скопировать в микроконтроллер. Обычно этот этап всегда следует за «рисованием», когда структура системы управления после прикидочных исследовательских работ по моделированию более-менее сформировалась. Но зачастую параметры объекта априори неизвестны, или известны очень неточно – никогда еще софт, работающий в модели, не начинал также хорошо работать на объекте. Также нельзя заложить в модель «всё» – переходные процессы переключения транзисторов, насыщение магнитопровода, вихревые токи, ёмкостные связи, уплывание параметров от температуры и от экземпляра к экземпляру, помехи то здесь, то там… А иногда объект регулирования настолько сложен, что проще делать разработку структуры управления для него уже непосредственно на объекте.
Например, когда мы делали систему управления для поддержания тока в дуге плавильной печи при помощи транзисторного источника напряжения, объект управления (дуга) был чем-то из разряда черного ящика. Мы нашли несколько моделей дуги в разных статьях, но они описывали внутренние процессы в плазме дуги, без ответа на наш «простой» вопрос – как надо задавать на дугу напряжение, чтобы ток оставался постоянным, и справится ли с этим обычный ПИ-регулятор тока? (если кому интересно – не справился, пришлось городить «огород высоких материй», но всё получилось).


Также есть ряд продуктов, позволяющих «рисовать» программы непосредственно для микроконтроллеров. В том числе тот же Matlab умеет генерировать Си-код для МК именитых брендов на основе модели в Simulink. Якобы можно нарисовать и отладить нарисованную структуру системы управления на компьютере в модели, а потом загрузить в МК – и готово, поехали! И даже такие среды позволяют отлаживать нарисованные структуры управления прямо внутри МК, смотреть переменные и т.п., а на сайтах таких продуктов есть куча демо-проектов для самых сложных систем, «запрограммированных» таким образом. Но так как все реальные проекты до сих пор почему-то программируют «руками», то можно догадаться, что с «рисованием» что-то не так. Но тут даже сложно описать, что именно, когда не так – всё. Главный аргумент против – это отсутствие полного контроля над происходящим внутри МК. Вы нажимаете кнопку в такой среде «сделать хорошо» и надеетесь, что генератор кода сделает за вас всё остальное. Для каких-то простых систем, где производительности МК «за глаза», сроки разработки очень поджимают, а программировать на фирме, которая взялась за проект, никто не умеет… то да, наверное, можно попробовать «нарисовать» программу. Но если она не заработает как надо, или будет иметь какой-то очень специфический глюк, то отладить её уже не будет никакой возможности. А для сложной задачи, где даже при программировании руками с производительностью МК всегда проблемы, рисование не подходит просто по причине нехватки ресурсов – любой язык программирования, чем он более высокоуровневый (куда уж выше рисования), генерирует менее оптимальный машинный код. А низкоуровневые оптимизации, которые сделал бы программист на Си, такая система сделать не сможет (расчет блоков одной структуры с разным тактированием, использование закешированных значений синуса и косинуса, замена функций деления на умножение на заранее подготовленную величину, или совсем уж хитрые вещи типа таких и т.п.).

Таким образом, приходится писать свой софт, и писать на Си. И отлаживать свой софт так или иначе надо, и надо на объекте. Наверное, к этому месту статьи все уже поняли, что отладить структуру управления можно только просмотром осциллограмм внутренних переменных, т.е. просмотром графиков во времени, как меняется та или иная переменная на Си – скажем, «выход вот того блока, пятого слева, одновременно с входами третьего справа». Получая картинки типа такой:

И сделать это можно только средствами самого микроконтроллера. Нельзя просто взять и поставить внешний быстрый интерфейс связи и посылать «наверх» значение какой-то переменной, так быстро, как только можно, а уже в системе верхнего уровня строить график. Потому что ни один интерфейс связи МК не успеет сделать это с той частотой, с которой протекают регулируемые переходные процессы. А если успеет, то все ресурсы МК уйдут на обслуживание этого интерфейса связи. Поэтому делают так – записывают осциллограмму в оперативную память МК, просто в массив. Обычно много точек не надо – достаточно поймать нужный момент, когда именно записывать данные: возвести нужный триггер на старт записи. И тогда можно увидеть, что выдавали те или иные блоки системы управления в момент сбоя, как он развивался, что пытался сделать МК. Конечно, все переменные сразу не заосциллографировать – но на практике по нашему опыту хватает, скажем, четырех массивов по 256 точек каждый – эдакий четырехканальный осциллограф средствами МК. Если сбой работы оборудования происходит не раз в неделю, то отладить это не проблема – в одном опыте смотрим эти 4 переменных, в следующем заменяем половину на другие, смотрим снова… пока не найдется неправильно работающий блок, или пока не снимем всё, что происходит на всех блоках и не уйдем просматривать «отснятый материал», почесывая то место, кто чем думает…

Чем же снимать такие осциллограммы? Какой софт это умеет? Через какой интерфейс связи это пересылать? Собственно, Texas Instruments потому и является лидером по производству motorcontrol микроконтроллеров, так как он сделал для этого всё, что надо: Code Composer Studio (их среда разработки) плюс режим реального времени МК. Режим реального времени – это когда через JTAG среда разработки может запрашивать и записывать данные в оперативной памяти МК без его остановки. Даже не просто без остановки, а без малейшего нарушения его работы. Этот режим есть во всех МК серии C2000, но для использования требуется дорогой и быстрый JTAG, который это поддерживает. Но кроме самого режима в МК должно быть что-то соответствующее и на обратной стороне кабеля: среда разработки Code Composer Studio «из коробки» умеет строить осциллограммы. Причем как в простейшем режиме, когда пользователь задает имя переменной Си и видит её изменение во времени на графике, а среда запрашивает данные с той частотой, с которой сможет (обычно хорошо, если герц 10), так и в режиме отображения массива в памяти в виде осциллограммы – т.е. как раз то, что описывалось выше. Таким образом, пользователь в МК делает ПО, которое запишет в массивы нужные осциллограммы, а Code Composer Studio через JTAG в реальном времени их скачает и покажет. При этом устройство может продолжать работать как ни в чем не бывало. Этот инструмент успешно используется уже больше десяти лет, и, собственно, такая идеология отладки (кажется, но могу ошибаться) и была предложена Texas. Во всех их демо-проектах есть модуль даталоггера (который записывает массивы осциллограмм) и в мануалах рассказывается, как им пользоваться. Кстати, здесь надо бросить камень в огород ARM. У них тоже есть режим реального времени, и на этой архитектуре есть МК, которые могут управлять электродвигателями. Однако ни в одной среде разработки мне не повстречалось функции построения графиков, даже если режим реального времени поддерживается. Например, в любимом всеми Keil даже нельзя на запущенном МК нормально поменять значение переменной – она постоянно обновляется, а вписываемое пользователем в окошко новое значение затирается… Не говоря уже о каких-то там графиках. Может быть кто-то в комментариях предложит работающий вариант? Или это «никому не надо», поэтому и не работает?

Но с этим способом отладки, даже через Code Composer Studio, есть проблема. И эта проблема JTAG. Как было сказано, его разъем не всегда доступен, а чаще всего на запущенном оборудовании и не доступен вовсе. Да и, честно признаться, не очень комфортно сидеть в паре метров от мегаватного преобразователя, смотреть его осциллограммы работы, и очень сконцентрировано и сосредоточенно объезжать мышкой кнопку «стоп» микроконтроллера, вдруг по пути дрогнет палец? А вы знаете, как глючит тачпад при работе мощного ШИМ? А если сглючит среда? А если JTAG? Всё, бабах?
Бабах обыкновенный


Кроме того, осциллограммы в среде разработки отображаются в тех значениях, «как есть» на Си, без всякого масштабирования, на разных окнах графиков, без пользовательских единиц измерения (надо помнить, что на этом графике 0.342 это вольты, их надо умножить в уме на 540 чтобы получить физические единицы, а тут 1.2 это амперы с масштабом 800А). И неудобно, и страшно. А еще ведь не на всех МК и средах разработки можно смотреть осциллограммы! Вдруг у вас – не Texas? Поэтому мы решили изобрести другой путь.

Наше решение


Собственно, если нам не нужна пошаговая отладка, то в чем проблема? Заменяем всё, что мы делаем через JTAG, на любой другой интерфейс связи и делаем свою оболочку верхнего уровня, которая строит графики так, как нам захочется. Profit!

Так мы и сделали. Интерфейс связи мы выбрали CAN, протокол – CANopen. Почему? CAN – очень хороший промышленный интерфейс связи, помехоустойчивый, имеет аппаратный арбитраж, неразрушающий доступ к шине, аппаратное подтверждение посылок, и при этом – всего два провода и земля. Это лучше, чем все RSы, и менее монстровидное, чем Ethernet (который на motorcontrol МК скорее экзотика). Почему CANopen? Собственно, для CAN есть два распространенных протокола, это J1939 («автомобильный») и CANopen (станки, автоматика, датчики и прочее). Разницы между ними не так много, но CANopen нам показался более гибким, поэтому мы реализовали его в своем собственном стеке (драйвере). Кто не знает ничего о CANopen – основная его функция, как и многих протоколов для МК, это предоставление доступа к словарю объектов (списку переменных на Си МК) по определенному адресу. Делаться это в нем может двумя основными способами: сообщениями SDO вида запрос-ответ, а также сообщениями PDO в виде постоянной отправки значений по таймеру или по событию (настраивает верхний уровень, что посылать и когда). Также есть различные служебные сервисы типа аварийного сообщения (emergency), сообщения наличия устройств в сети (heartbeat) и т.п. Мастер в сети не обязателен: кто хочет – посылает, кому надо – принимает.

Мы сделали стек CANopen не только для МК, но и для компьютера в виде библиотеки. И уже на её основе под Windows написали свою среду верхнего уровня. Сначала сделали просто доступ к переменным словаря объектов, чтобы можно было смотреть и менять настройки системы управления (а их, между прочим, сотни!), потом сделали отрисовку графиков путем периодического запроса параметра словаря объектов по сети, а потом добавили загрузку осциллограмм из массивов МК (причем выбор что осциллографировать производится также из переменных объектов словаря). Получили всё тоже самое, что дает отладка через JTAG. Или нет? Нет, потому что нужна была еще функция обновления ПО через CAN. Несмотря на наличие бутлоадера по CAN в МК Texas, мы решили сделать свой, так как стандартный был не CANopen и мог мешать работе других устройств в сети, пока мы шьем одно, также как и устройства могли мешать прошивке. Кроме того, там были проблемы с коррекцией ошибок и пропажей сообщений (хоть CAN и очень хорош, сбои иногда бывают, а прошивка – очень ответственная вещь, чтобы не сделать верификацию или повторную попытку отправки битого куска). Поэтому мы реализовали свой «программатор» по сети CAN, но в рамках протокола CANOpen. Вот теперь всё. Теперь мы смогли полностью отказаться от JTAG, используя его только один раз, для программирования нового МК.

При этом такой подход открыл нам еще новые горизонты отладки, которые мы не видели раньше. Так как среду верхнего уровня мы делали с прицелом не только на программистов, но и на «обычных людей», мы сделали всем параметрам русскоязычные названия и сделали документацию наладчика по каждому параметру (документация не среды, а устройства, конечно). И это принесло пользу – теперь при наличии какой-то проблемы с приводом не обязательно «дёргать» разработчика – обслуживающий персонал заказчика в ряде случаев может самостоятельно выполнить диагностику проблем. Теперь мы можем получить е-меил вида «У нас привод стал странные звуки издавать иногда, я посмотрел осциллограмму датчика положения, вот что увидел (картинка). Проверил заземление экрана, оно отвалилось, я подпаял и все заработало как надо!». И совершенно не нужно никуда ехать или лететь! Второе «открытие» – если есть проблема, просим заказчика подключить компьютер к оборудованию и дать управление удаленным рабочим столом через интернет – запускаем свою среду верхнего уровня, сами все осциллографируем, правим параметры/прошивку/говорим что сломалось – profit! Опять не надо никуда ехать (главное, чтобы интернет на объекте был, хотя бы через сотовую сеть).

С годами использования эта программа верхнего уровня обрастала мелкими функциями, как грибами (естественный процесс для софта, которым пользуются). Это и работа с журналом аварий устройства, и сохранение/загрузка слепка всех параметров в файл на компьютере, и конфигурирование панели управления устройством а-ля «пульт управления», и ведение логов сети в файл, и отдача трафика CAN сети по TCP/IP, и автоматическая множественная прошивка/параметрирование однотипных устройств в сети (если устройств десятки, то прошить все руками – лениво, нужен скрипт) и т.п.

Ну а теперь немного рекламы. Сейчас это уже очень мощный инструмент (назвали мы его ни много ни мало – UniCON), который в некоторых задачах выглядит функциональнее, чем аналогичное ПО от именитых брендов по настройке их приводов и устройств. При этом он не привязан к конкретному устройству – можно настраивать хоть электропривод, хоть печку, хоть зарядное устройство – меняется только словарь объектов. Сейчас в нашей компании мы не видим возможности выполнить успешно новый сложный проект без наших CANopen средств отладки. Для работы с UniCON нужно всего лишь встроить в МК наш стек CANopen, после чего МК превращается в цифровую лабораторию. Уверены, все фирмы, которые делают серьезные системы управления на МК, имеют подобные средства отладки. Но мы предлагаем наше CANopen решение в виде самостоятельного программного продукта, так как оно выполнено универсально в плане независимости от функций устройства. На текущий момент мы реализовали стек CANopen с описанными расширенными функциями для МК Texas Instruments C2000, их ARM микроконтроллеров (например, семейства Concerto) и для К1921ВК01Т ОАО «НИИЭТ». Поэтому если вам требуется разработать систему управления электроприводом или другим сложным объектом управления, то мы приглашаем вас к сотрудничеству.



P.S.
В комментариях с нетерпением ждем критики вида «Так есть же *** – оно делает все то же самое и бесплатно». Так как мы долго искали аналогичные по функционалу средства отладки для ARM, но споткнулись даже об именитые среды разработки.

UPD: Благодаря комментариям Indemsys, olekl и LeonidLenin нашлись функции построения графиков в средах разработки под ARM Keil и STMStudio при работе через SWD. Однако отображать массив данных из памяти МК в виде графика они не умеют, что как раз нужно для наблюдения быстротекущих процессов систем управления. Также интересным выглядит инструмент FreeMaster от NXP — по описанию и назначению очень похож на нашу разработку UniCON, но со своими особенностями.

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


  1. amarao
    14.01.2016 18:21
    +1

    Мне интуиция говорит, что нужно писать эмуляторы оборудования. Те же моки, но в железе.

    «А вот эти три вольта на 1мА изображают 10кВ с током в 500А и мы его типа-коммутируем». А рядом железка, которая выдаёт результаты теста.

    Насчёт «без ОС» — в моём представлении (опять же, наивном) — программа должна писаться на каком-то высокоуровневом DSL'е, который транслируется потом в монолитный блобик машинного кода, намертво интегрированный с библиотекой (изображающей из себя ядро и libc в одной ипостаси). И именно на уровне обработки DSL'я должны проверяться все граничные условия и корректность обработки событий (на математическом уровне проверки — как выведение типов в хорошо типизированных языках).


    1. BelerafonL
      15.01.2016 16:36
      +1

      Эмуляторы оборудования, они же «макеты», конечно же делаются и применяются в ряде случаев. Когда нужно провести какое-то научное исследование в лабораторных условиях. Железкой, выдающей результаты «теста», может являться меньший по мощности электродвигатель. Но иногда можно и сделать программируемый имитатор, который в себе крутит модель объекта управления и взаимодействует с отлаживаемой системой управления. Более того, иногда сама модель объекта управления встраивается непосредственно в софт системы управления. Например, можно встроить модель электродвигателя с систему управления преобразователя частоты — у меня в одном из проектов так сделано. Однако всё это не сильно лучше модели в матлабе — объект можно промоделировать лишь настолько, насколько вы можете математически его описать. И как бы вы не отладили всё это на модели, на макете или на эмуляторе — на объекте окажется всё по-другому. И всё равно придется смотреть переходные процессы, перенастраивать десятки параметров, дописывать фильтры, добавлять новые неожиданные защиты и т.п. Поэтому на объекте желательно иметь доступными те же самые средства отладки, которые использовались «в лабораторных условиях» — иначе поиск проблем на объекте может затянуться на неопределенное время, а бесконечные командировки могут «съесть» весь бюджет проекта.


      1. amarao
        15.01.2016 22:15
        -1

        А юнит-тесты не используются?

        Мол, у нас есть релюха, которая 20кА коммутирует. У нас есть устройство, которое отлажено на коммутации микроамперными токами. Теперь мы берём и собираем стенд, где эта штука коммутирует 20кА. Не реальный мотор, а просто 20кА.

        Я понимаю, что железо делать — не мегабайты кода писать, но те же принципы тестирования, что отработаны в софте, возможно, могут быть применены и в железе, не?


        1. BelerafonL
          15.01.2016 23:43
          +4

          Очень дорого так делать. Если у софта цена тестирования — это лишь цена времени программиста, то чтобы в железе сделать юнит-тест «релюхи на 20кА» — нужно сделать целый дорогущий стенд, причем состоящий не просто из релюхи на 20кА, а еще источника на 20кА и того, куда эти 20кА утекут (целая комната силовых шкафов). Делать такой стенд только ради того, чтобы проверить, что у контроллера ножка ставится в единицу, которая эту релюху включает, конечно, никто не будет. Если вы, конечно, не производитель этой релюхи, а не её пользователь как готового продукта. Более того, сами такие объекты, где надо коммутировать 20кА, это единичные объекты, а скорее даже это может оказаться один специализированный софт для одного единственного объекта с этой релюхой. И делать по кусочкам еще один такой же объект только для юнит-тестов — учетверенная цена объекта. Но такие «юнит-тесты» на самом деле делают, но называется это пусконаладкой устройства/объекта. Никто не приходит на только собранную электрическую вундервафлю на 20кА и не нажимает кнопку «поехали», где она сразу включается в номинальный режим. Сначала собираются аппаратчики и программисты на заводе-производителе, где начинают постепенную наладку устройства, включая узлы по кусочкам и проверяя, что на выходе то что надо. Потом включают это нечто на холостом ходе, небольшом токе, всё измеряют, осциллографируют, правят косяки. Потом дают небольшую мощность, тестовый прогон, проверяют все защиты, имитируя те или иные отказы. Если есть сомнение в каком-то узле, могут уже на оборудовании поставить какой-то эксперимент, приняв нужные меры предосторожности. Потом номинал, прогон на тепло с записью всей телеметрии, потом разборка на куски и отправка заказчику, там монтаж, первое включение там, продолжение правки косяков (которые вдруг повылезали еще), прогон 72 часа, сдача объекта… потом начало тестовой эксплуатации, где всё еще продолжают вылезать иногда косяки, которые приезжают и правят… И так постепенно оборудование входит в строй.
          Поэтому — нет, для 20кА юнит-тестов не делают, или делают, только если сомневаются в каком-то физическом явлении, но это не тест уже, а скорее исследовательская работа, и делается она только если ни на модели, ни на объекте это проверить никак нельзя. Все юнит-тесты софта в основном делаются софтом же, либо совсем простым оборудованием типа еще одного контроллера-имитатора, тумблеров, лампочек и т.п.
          Но, как я уже сказал, реальное устройство имитатором полноценно не описать, а поэтому особо интеллектуальные куски кода, увы, приходится рожать во время пусконаладки. И даже если это делается всё на заводе-изготовителе, то всё равно для программиста — это уже не отладка «на столе», это настоящие шкафы в пыльном цеху, где и сесть особо негде, и удлиннителей для зарядки ноутбука вечно нет, и провода силовые везде висят, и шум, и брызги то масла, то тосола летят, и интернет еле ловит (хорошо если из репозитория запуллить что-то получится или спросить консультации в чате у коллег) — никакой комфортной отладки. А ещё обязательно рядом будет стоять заказчик, который будет смотреть через плечо в ноутбук и спрашивать: «Почему не работает? Мы должны были поставить оборудование еще на той неделе! Вы же говорили, что программа написана, почему не включаете? Как это ток пульсирует, зачем он так делает?»…
          Поэтому нужно заранее иметь все инструменты, которыми можно быстро и эффективно понять, в чем может быть проблема и оперативно исправить её. Как программист, я бы с удовольствием согласился бы на юнит-тесты железа, но реалии обычно таковы что «Мы заказали силовые ключи и трансформатор, поставка долгая, вы пока пишите спокойно программу, а они придут через шесть месяцев на завод, там их смонтируют в силовые шкафы за две недели, потом вы поедете настроите все (недели вам хватит?), а на к концу седьмого месяца оборудование должно быть у заказчика». Вот и все юнит-тесты на этом…


          1. amarao
            16.01.2016 00:20
            -1

            Спасибо.

            Ещё один грустный продакшен. Интересно, в мире бывает добрый, светлый пушистый продакшен, где каждый участник проекта ощущает, что он, и все окружающие, всё сделали правильно и на совесть, как положено?


  1. Sergei2405
    14.01.2016 18:43

    Так есть же ITM и ETM у армов – оно делает все тоже самое и бесплатно.

    Ну это так шутка…


  1. Mirn
    14.01.2016 19:08
    +3

    добавлю к автору что работа с подобными штуками очень сильно меняет стиль программирования и даёт возможность на си писать более компактные и быстрые в циклах программы чем это делают мастера ассемблера при подготовке своей статьи (но не комментариев), когда мигалка светодиодом с задержкой реализуется в один сдвиг и одну сумму (см цикл while (true)).
    например тут:
    http://habrahabr.ru/post/274901/#comment_8738493
    Да и вообще привыкаешь думать критериями фазы, вращения, частотами и условиями устойчивости

    у меня например есть своя библиотека с «чёрной магией», например:
    1. нонстоп обмен потоками данных при помощи дма без прерываний в реалтайме (помним, нам надо избегать прерываний вообще, т.к. реалтайм)
    2. всякие быстрые синусы и тригонометрия по таблицам (кстати именно таблицы и жрут часто очень много флеша)
    3. быстрые и ОЧЕНЬ быстрые (быстрее аналогов boost-а) lockfree очереди состоящие из просто вычисления адреса указателя и размера кол-ва данных в указателе
    4.и просто стопятьсот мелочей например как очень шустро вычислить квадратный корень там где его нет аппаратно, пусть даже немного неточно, или точно вычислить квадратурный детектор

    это я со звуком работаю если что а не с приводами
    да даже там есть очень сложные штуки типа эхо-подавления когда надо найти глобальный минимум в 256 мерном пространстве в реалтайме да ещё чтоб системма в целом самовозбуждалась


  1. Indemsys
    14.01.2016 19:19
    +6

    Все слишком категорично.

    Я разрабатываю частотники и прочую силовую электронику вполне нарушая все эти выше перечисленные принципы.
    Вот здесь один приведен для примера — habrahabr.ru/post/256611

    Cделан строго с применением RTOS. Без RTOS я вообще силовую электронику не делаю.
    Отлаживаю по JTAG. Гальвано-изолированный JTAG стоит копейки.
    Пользуюсь точками останова вовсю и во время работы силовых цепей. А ARM-ах на точках останова не обязательно останавливается вся периферия. ШИМ-ы могут оставаться работать, это как зададите.
    Гораздо удобнее чем JTAG это SWD интерфейс.
    Графики в реальном времени могут строить и Keil и IAR. Даже у Segger-а производителя отладчиков J-Link есть построитель графиков с передачей по отладочному каналу.
    Вместо CAN применяю RS232, по нему передаю информацию в PC со скоростью 1.25 Мбит, это гораздо быстрее CAN-а.
    А не менее мощный аналог UniCON это FreeMaster от NXP. Имеет открытый протокол и все сорсы.


    1. BelerafonL
      14.01.2016 20:11

      Было бы интересно, если бы Вы рассказали о вашем опыте разработки с практической стороны на ARM. Про точки останова во время работы силовых цепей, где их можно ставить, где нет, как сконфигурировать периферию, чтобы это было безопасно — ШИМы-то работать будут, а вот будет ли обновляться вектор напряжения? Как не промахнуться с точкой останова?
      Какой дешевый JTAG с изоляцией посоветуете, который не сбоит при ШИМящих киловольтах по соседству?
      Где в Keil и IAR можно посмотреть осциллограмму синуса тока фазы, как это организовать? Это очень интересно, так как я, как пользователь Code Composer Studio от тексас, банально не нашел этих опций в Keil и IAR.
      Грамотно использовать RTOS — согласен, можно. Небольшой платой за «оверхед» можно получить очень много полезных вещей. На мощных микроконтролерах это уместно, особенно если вы эту RTOS освоили и знаете все её подводные камни. Но, зависит, конечно, от МК — например, у меня проект в стиле «Bare metal» под DSP микроконтроллер TI TMS320F2810 занял буквально всю флеш-память — RTOS туда просто некуда вставить. Это нужно МК с в два раза большей памятью брать. В общем, соглашусь, что RTOS — дело привычки.
      За FreeMaster — спасибо, обязательно посмотрим на его возможности. По описанию действительно похож на нашу разработку.


      1. olekl
        15.01.2016 11:18

        1. BelerafonL
          15.01.2016 18:33

          Да, спасибо, действительно, получилось запустить — изначально не нашел этой опции потому что функцию рисования «аналоговых» графиков в Keil спрятали в логический анализатор. Для работы пришлось задействовать по мануалу Trace режим, указать все галочки, после чего график нарисовался. Однако он не очень обрадовал — работает режим отрисовки текущего значения переменной (причем не очень быстро), а вот режима отображения данных из массива в виде графика опять же нету (а это самое главное!). Так что Code Composer Studio в этом плане впереди. Кроме того, почему-то в Keil отрисовка графиков работала довольно капризно, через раз — надо было то перезапускать сеанс отладки, то передергивать питание платы — иначе ничего не рисовалось. Проверял на stm32f4discovery по SWD интерфейсу.


          1. olekl
            15.01.2016 18:44

            Чтобы отобразить массив, я объявлял еще одну переменную и в цикле присваивал ей элементы массива. И уже саму переменную выводил в анализатор. Про не очень быстро — непонятно, т.к. у меня все работает в реалтайме. STMF4.


          1. Mirn
            15.01.2016 18:46
            +1

            даже среда для плис — квартус умеет и снимать и рисовать аналоговые графики, например есть где либо внутри или на ножках плис, например знаковое 16 битное с ацп или внутренне расчитанная синусойда — в SignalTap можно подключиться и снимать график в реалтайме не разрушая этот реалтайм. Максимум что будет если кристалл заполнен на более чем 70% то сильно съедут тайминги на сотни пикосекунд.

            Более того в сигнал тапе можно делать на порядки больше всего. тактироваться с разных источников, сложное тактирование а апериодическое, условия и целые скрипты написать по поиску нужного тебе события.

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

            Я на плис делаю многие вещи связанные с переферией в десятки раз быстрее чем на старших микроконтроллерах. Т.к. ты делаешь только то что тебе нужно а не изучаешь мегамонстра под все случаи жизни, и пытаешся его запустить и абуздать шатл.


            1. JerleShannara
              16.01.2016 17:13

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


  1. olekl
    14.01.2016 19:25

    Да, осциллограммы в реальном времени — круто! Только правда через CAN уже не совсем в реальном, но плюсы перевешивают, согласен :) MDK/ARM так тоже умеет, только через дебаггер. При этом разрешение именно что реал-тайм. Т.е. я на МК с 168 МГц в цикле присваиваю одной глобальной переменной значения масива и на экране логического анализатора вижу график этого массива. И такой красоты сохраняется последних несколько секунд. Работе контроллера не мешает.

    Еще одна полезная штука, тоже однажды делал себе с нуля — сохранять таймстемпы для заданных пользователем событий. Позволяет красиво визуализировать последовательность событий. Например, в начало-конец каждого превырвания добавить по пользовательскому событий — и вуаля, можно увидеть, как часто прерывания происходят, в каком порядке и сколько каждое из них длится. Доп. нагрузка на контроллер, правда, в этом случае есть, но небольшая — таймстемпы берутся из аппаратного таймера, пишется все в циклический буфер…


    1. BelerafonL
      14.01.2016 20:29

      Захватывать вообще все данные работы системы управления с огромной частотой обновления обычно не требуется. Для «реального времени» хватает вяло обновляющихся данных о текущем состоянии «телеметрии» — частоте вращения, мощности, температуре и т.п. А когда происходит сбой, вот тогда и нужна осциллограмма его процесса с хорошим разрешением по времени. Кроме микроконтроллера её записать всё равно никто не успеет. А раз она записана внутри, передавать «наверх» данные можно уже тоже не торопясь. Поэтому в таком стиле работы вообще быстрого интерфейса связи не требуется как такового. Хоть это CAN, хоть RS 9600 кБит/с — не важно.

      Касательно последовательности событий — можно записывать время, как вы говорите, а можно, имея «осциллограф» в самом быстром прерывании, просто осциллографировать счетчики других прерываний или флаги нахождения внутри прерывания. Тогда можно точно также увидеть, где что вызывалось. Но это уже нюансы реализации — просто для вашего способа нужно писать отдельную утилиту для выкачивания и визуализации этих данных, а если есть осциллограф внутри, то нужно лишь добавить на каждое событие счетчик и смотреть его.


  1. olekl
    14.01.2016 19:29
    +2

    Наезд на RTOS не совсем понятен. RTOS совсем не мешает прерываниям, и не надо их заменять на переключение задач, это разные штуки. А многие рутинные вещи RTOS очень даже упрощает, позволяя написать простой код вместо сложной машины состояний…


    1. Amomum
      15.01.2016 11:03

      Ну, мешает или нет — это зависит от конкретной RTOS. Если мне не изменяет память, то порт uC/OS для stm32, например, все обработчики прерывания пропускал через свой программный «контроллер прерываний».
      То есть, вместо специализированного обработчика сначала вызывался один общий обработчик от ОС, который программно проверял источник прерывания и вызывал нужный обработчик из массива указателей.

      Зачем это делалось я сходу не скажу.

      Но в той же freeRTOS такой проблемы нет.


  1. Mirn
    14.01.2016 20:48

    а как в моторном деле обстоят дела с ПЛИС?
    Применяется или нет?
    На плис же гораздо быстрее и гибче можно сделать свою переферию с нужыми таймерами, мёртвыми интервалами и запусками ацп когда надо да и всю рутинную работу по усереднению и управлению тоже можно свалить на ПЛИС. В добавок плис может работать с очень малым шагом управления и переваривать в реалтайме очень жирный поток от АЦП — сотни миллионов выборок в секунду запросто даже начального уровня типа МАКС 2… МАКС5. Я на плис например спокойно и без оптимизаций делал обработку потока видеоданных для FullHD видеопотока.
    У той же Альтеры есть немало демо и отладочных плат на FPGA.


    1. BelerafonL
      14.01.2016 22:18
      +1

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


      1. JerleShannara
        15.01.2016 14:42

        А вариант использования дешевой ПЛИС + синтезируемого ядра микроконтроллера (не обязательно платных *blaze/nios/ppc/arm (раз уж стоит вопрос цены), можно что-нить подобрать на opencores)? Знакомый разработчик лет десять назад для работы написал аналог меги и был им доволен (причём аналог не только в плане ядра, а ещё и обвязки в виде всяких таймеров, uart-ов и прочего её фарша) настолько, что перевёл разработки целиком на ПЛИС.


        1. BelerafonL
          15.01.2016 15:36
          +1

          Я не специалист в ядрах ПЛИС, но, думаю, что если сравнивать готовый 32х разрядный микроконтроллер и аналогичное по функциональности и скорости работы ядро, собранное на ПЛИС, то ПЛИС выйдет точно дороже микроконтроллера. Кроме того, какое бесплатное 32х разрядное DSP ядро можно предложить для синтеза, чтобы на нем можно было решать сложные вычислительные задачи электропривода? Какие компиляторы Си-кода на него использовать? Достаточно ли они функциональны, хорошо ли работает оптимизатор? Если для «меги» это еще можно представить, то электропривод — это совсем другой класс задач… Нужно максимально использовать готовые решения, собирать микроконтроллер из кусочков — это задача для производителей микроконтроллеров, или разработчиков с очень специфическими задачами, где стандартные микроконтроллеры не подходят. Для электропривода всё уже есть.


  1. vladimir_open-dev
    14.01.2016 21:30

    Объясните почему CAN лучше RS-485? Я вот никак не пойму. RS-485 имеет 2х тактный выход, а CAN однотактный(тянет только вниз)…


    1. BelerafonL
      14.01.2016 22:54
      +1

      Как раз за счет этого и лучше. За счет так называемых рецессивных и доминантных состояний на линии. Если в RS-485 два устройства начнут передавать одновременно, возникнет коллизия — битые данные. В кэне передающие узлы контролируют линию. Если узел выставил рецессивный 1, а прочитал доминантный 0, то значит кто-то другой на линии передает свои более приоритетные данные. Этот узел «затыкается», данные продолжает посылать более успешный узел, посылка доходит до всех в сети в сохранности. А заткнувшийся узел пробует передать свое сообщение уже вслед еще раз. Поэтому при одновременной передаче доступ к линии (выигрывает арбитраж) получает узел с самым приоритетным началом посылки (идентификтором) — т.е. чем меньше идентификатор в цифровом представлении, тем выше приоритет (одинаковые идентификаторы — запрещены). Так автоматически разрешаются коллизии — не нужен мастер в сети, все шлют «когда хотят». А еще на этом же механизме (рецессивных и доминантных состояний) основано подтверждение посылки — в самом конце передачи есть битик, который должен быть всегда равен единице и который называется битом подтверждения (ack). Если какой-то из узлов плохо расслышал посылку, то он утягивает линию в ноль — передающий узел видит, что посылку кто-то не воспринял и автоматически (аппаратно) перепосылает еще раз. В RS всё это невозможно. Это же всё и минус CAN — такая система накладывает ограничения на максимальную длину линии/частоту передачи, чтобы узел на конце линии, выставив доминантный ноль, мог за время передачи одного бита быть услышан узлом в начале сети (скорость света, переходные процессы и всё такое). CAN — это не просто линия передачи, а целый протокол — там и бит стаффинг, и контрольная сумма и арбитраж (неразрушающий доступ к линии), и перепосылка данных — и все это на аппаратном уровне выполняется контроллером CAN линии в микроконтроллере.


      1. vladimir_open-dev
        14.01.2016 23:20
        +1

        Может я не понял, но помехоустойчивость это способность работать в сложной ЭМ обстановке(2х тактный выход как раз там покажет себя с положительной стороны) и разруливание коллизий на нее не влияет. То, что плюшек больше на CAN я не спорю.


        1. BelerafonL
          14.01.2016 23:34

          Если CAN рассматривать не просто как физическую линию, а вместе с неотъемлемыми функциями аппаратной проверки контрольной суммы и перепосылки сообщения, то он покажет себя лучше по сравнению с RS, несмотря на более «слабый» физический сигнал передачи. И по количеству неполученных посылок CAN выиграет в большинстве случаев у RS — он просто перепошет битое сообщение, никто даже и не заметит. А в RS вы явно получите битые данные и будете программно уже их верифицировать протоколом более высокого уровня. Так что всё зависит от методов сравнения.


          1. vladimir_open-dev
            14.01.2016 23:49

            а у CAN все проверки разве на аппаратном уровне?


            1. DiAli
              15.01.2016 00:20
              +4

              Арбитраж доступа, механизмы контроля и предотвращения ошибок (а их в CAN несколько — bit stuffing, проверка контрольной суммы), автоматическая перепосылка недоставленного сообщения — все это реализуется на аппаратном уровне. Вероятность невыявления ошибки передачи 4,7?10?11 (Из вики). Таким образом, надежность передачи сообщений в CAN очень высока. При этом программисту не надо об этом особо задумываться — отправляешь данные и знаешь, что они дойдут. В RS все тяготы разрешения конфликтов, расчета контрольных сумм, проверок доставлено ли сообщение и т.д. ложатся на плечи программиста.


              1. vladimir_open-dev
                15.01.2016 00:38

                Спасибо, теперь понятно.


              1. vladimir_open-dev
                16.01.2016 01:14

                А сколько стоят драйвера CAN? RS-485 начинается от 0,5 доллара…


                1. BelerafonL
                  16.01.2016 13:03
                  +1

                  Ну там всё равно развязка самое дорогое. Можно, например, взять ISO1050DUB — это совмещенный драйвер+развязка, 4 доллара. Сам драйвер где-то 2 стоит хороший. Может есть и дешевле, не знаю.


  1. vladimir_open-dev
    14.01.2016 23:49
    +1

    не туда


  1. LeonidLenin
    16.01.2016 10:41
    +1

    Читаю, прямо по-живому всё! Спасибо, приятно осознавать что ты не одинок)

    Но у меня есть чем поделиться: motorcontrol построен на stm32f3, а данные я снимаю через STMStudio по SWD.
    Быстродействие можно довести до 50-80Гц, в зависимости от числа снимаемых переменных.
    Есть возможность записи в регистры. Контроллер не останавливается и не резетится.
    Минус — сидишь рядом с 20-30КВт оборудованием, да и SWD довольно чувствителен к помехам, даже с экранированными кабелями.
    А вот снятие осциллограмм из ОЗУ приходилось делать через дебуггер CoIDE, копируя-вставляя столбец данных массива в Calc.
    Если-бы STMStudio умела считывать и строить график по массиву — цены бы ей небыло.
    Писать свою оболочку пока нет времени, стараемся получить нужный результат на том что есть.
    Вот картинка для примера, рад буду ответить на вопросы или попробовать что-то новое.
    image


    1. BelerafonL
      16.01.2016 12:45
      +1

      У нас есть порт нашего CANopen драйвера под STM32F4, я думаю, его можно и для f3 собрать, только он… инкапсулирован в RS :) То есть пакеты, которые аппаратно должны были бы идти по CAN, засунуты в RS и добавлена сверху контрольная сумма. Я это делал, когда мне нужно было поиграть с STM32F4 discovery, но играть хотелось со своей оболочкой, а с даташитом CAN разбираться не хотелось. Там всё работает, только медленно. Раз вы так мучаетесь… мы можем вам собрать упрощенную версию оболочки и драйвера, где вы сможете смотреть несколько переменных через массив. А в будущем мы, может быть, портируем наш CANopen для STM полноценно.


      1. LeonidLenin
        24.01.2016 10:14

        Спасибо за предложение, очень ценим такую открытость!
        Благодаря вашей статье совершили очередной подход к документации к STMStudio и нашли как сделать скоростное получение переменных.
        И сразу удалось довести до ума контроллер. С передачей по CAN пока повременим.

        Получается, что ST ничуть не хуже TI в плане motorcontrol — просто не так распиарен. Ну и я даже не знаю как с 4х параллельно работающих ADC переходить на один)


        1. BelerafonL
          24.01.2016 10:18

          Отличная новость, хоть какие-то разработчики среды услышали, что нужно электроприводчикам :) Значит STMStudio записываем в годные!


  1. LeonidLenin
    17.01.2016 01:38

    UPD: сегодня, по горячим следам, был найден способ записи и передачи stmstudio пакета данных, записанного в оперативку с любой скоростью. Пока только на их же примере, но на днях попробую на реальном силовом блоке. Snapshot trigger capture.


  1. Khort
    17.01.2016 17:27

    Как Вы оцениваете юзабельность нового кортесаМ4 от НИИЕТ? Хорошая микросхема получилась?


    1. BelerafonL
      17.01.2016 17:39

      Юзабельна. Подождите, пожалуйста, 1 день — уже дописываю статью.


      1. Khort
        17.01.2016 17:58

        Любопытный материал будет, у Вас ведь эксклюзив, я так понимаю — была возможность с прототипом работать.
        А эта микросхема уже пошла в серию, или до сих пор опытные образцы только? На сайте НИИЕТ ее пока нет в списке продукции


        1. BelerafonL
          17.01.2016 19:15
          +2

          Даже чуть больше, чем с прототипом. К1921ВК01Т уже доступен к заказу. Пожалуйте к прочтению: geektimes.ru/company/npf_vektor/blog/269246