Только дурак учится на своих ошибках, умный предпочитает учиться на чужих


Мой активный корреспондент Чарльз Мэннинг отправил мне ссылку на вопрос с сайта Nordic Semiconductor. Вот этот вопрос, дословно: «Какой BLE профиль будет удовлетворять ЭКГ сигналам наилучшим образом и есть ли пример кода для АЦП из этого профиля? Искал какое-то время и не могу найти его ».

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

Это, наверное, несправедливо сделать такие выводы всего лишь из одного вопроса, несмотря на, возможно, леденящие душу последствия для пользователей. И я не собираюсь запретить форумы — они представляют собой отличный способ совместного использования знаний. В до-интернетовскую эпоху мы все в значительной степени должны были выяснить интересующие нас вопросы из собственного опыта, что было ужасно неэффективно. Я помню поездки в объятия вендоров для разговора с разработчиками чипа, чтобы получить внутреннюю информация о какой-то плохо документированной или неработающей функциональности.

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

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

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

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

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

Тем не менее надо проявить снисходительность к поставщикам — ведь их миссия заключается в продаже чипов. Референсный код является свободным и поэтому воспринимается как бесплатный. То есть он должен существовать, чтобы протолкнуть чип в дверь продаж, но никогда не получит требуемого внимания к потребностям пользователя. Современные микроконтроллеры действительно сложны. Даже шина может развалиться, периферия работает в бесчисленных режимах. Сотни или даже тысячи регистров должны быть установлены правильно. Список инициализации сегодня может составлять 500, 1000 или более страниц. Референсный код действительно не может обработать каждый режим и возможную конфигурацию. Стоимость развития такого кода огромна, а цена равна нулю.

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

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

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

Когда дело доходит до повторного использования мы должны думать о пирамидах. Они были построены на невероятно прочном фундаменте. В мире прошивки, слишком часто, эта пирамида перевернута.

Каков ваш опыт работы с референсным кодом?

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

Решение очевидно — надо использовать в подобных случаях аппаратный ШИМ, но, как вы думаете, где-нибудь в документации об этом было сказано? Причем все скачано с официального сайта Ардуино. Есть альтернативное решение, но там свои тараканы и чуть ли не крупнее. Как говорил товарищ Сталин — «Оба хуже».
Ну да фиг то с ними с Ардуино (хотя с какого перепугу, ребята то считают себя вполне взрослыми и спрашивать с них надо соответственно), но вот буквально вчера обнаружена бага в референсной библиотеке (порте lwIP) на STM, которая проявляется в определенных условиях при не-одновременности подачи питания на разные аппаратные части устройства.

Где-то с полгода назад у знакомых молодых инженеров на определенных режимах не работала референсная библиотека USB от STM, а через месяц появилась новая версия библиотеки, которая заработала, за что STM искреннее спасибо (что этих инженеров, конечно, не оправдывает в столь некритичном использовании стороннего кода).

Как, во многом справедливо, указал мой коллега по поводу все тех же Ардуино библиотек, их использование сильно напоминает карго-культ, то есть делай так и будет тебе счастье. И все замечательно, пока все действительно работает, но ежели нет… вот тут и требуются знания, которых следование наперед заданным правилам дать не может в принципе. Хотелось, что бы меня правильно поняли — я не против Ардуино, более того, это замечательная экосистема, которая потрясающе понизила порог вхождения и привлекла к прошивке колоссальное количество людей, но надо четко понимать что она никак не серебряная пуля и даже при реализации не экстремально сложных функций может создать определенные проблемы, решать которые она не учит. То есть, начинайте с Ардуино, но потом идите дальше — там самое интересное и начинается.

PS. Вот не могу понять, почему тот же Джек читает свой курс по прошивке «More Firmware, Faster» каждый год в 5-6 странах, а у нас ничего подобного нет и не предвидится. У нас нет потребности в сильных инженерах? Не верится. Или дело в нежелании учиться? Или в нежелании платить за учебу (за свою или своих сотрудников)? У меня нет ответа на эти вопросы, есть только констатация факта.

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


  1. tsmar
    07.05.2015 14:28
    +1

    Предложу, в этом случае, заменить «референсный» на «тестовый», потому как именно в этом контексте подается материал статьи «не доверяйте примерам кода от производителя!».


    1. progchip666
      07.05.2015 15:33

      Это не верно. Библиотеки производителя не являются тестовыми.


      1. Houston
        07.05.2015 16:41
        +1

        Возможно, лучше развернуть до максимально понятного «Код из примеров, поставляемых с оборудованием»?


    1. iliasam
      07.05.2015 16:46
      +2

      Может быть: «демонстрационные» библиотеки?


      1. GarryC Автор
        07.05.2015 17:44

        О точно, пожалуй наиболее подходяще, сейчас в статье помечу.


  1. progchip666
    07.05.2015 15:37
    +2

    Хорошая статья, поднимающая очень важные проблемы. Сам постоянно удивляюсь несовершенстовом библиотек. Их бездумное использование ведёт к катастрофическому разрастанию объёа кода и замедлению работы. Плюс ошибки, которые кстати часто возникают от совместного использования библиотек почерпнутых из разных источников.
    Однако удивительно дурацкое название у вашей статьи, которое совсем не отражает сути затронутой проблемы.
    Я имею ввиду

    Только дурак учится на своих ошибках, умный предпочитает учиться на чужих


    1. Int_13h
      08.05.2015 05:32

      Главное, чтобы сюда не пришли программисты под РС и иже с ними с соседней ветки обсуждений с соседнего ресурса, у которых самое ценное — количество времени, затраченного на разработку, а ресурсов не хватает — возьмите железо помощнее (с)


  1. mark_ablov
    07.05.2015 17:37
    -1

    Только велосипеды, только хардкор!


    1. GarryC Автор
      07.05.2015 17:49

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


      1. mark_ablov
        07.05.2015 17:56

        Ну я и сам матерился местами, когда референсный код даже не совпадает местами с даташитом.
        Но всё равно думаю, что, скажем, увлекаться переписыванием какого-нибудь софтового USB-стека или tcp/ip-стека не следует.


      1. JC_Piligrim
        08.05.2015 01:24

        Как будто в своих велосипедах ошибок не бывает. Бывает ещё жёстче, чем в чужих.

        Критичные системы надо нещадно тестировать. Вот и всё. А писание своего говнокода вместо говнокода производителя чипа никак не поможет избежать драматических ошибок в продакшене.

        P.S. Примеры с STM и Arduino только подтверждают, что свои велосипеды — зло. В библиотеках, которые используются на миллионах разных устройств в разных режимах ошибки будут найдены и исправлены раньше, чем в самописных, которые всю жизнь использовали в одном режиме, а в очередной партии — в другом, в результате чего всё взорвалось. Повторюсь, примеры с Arduino и STM это подтверждают, хотя, конечно, ситуация действительно, когда «обе хуже». И не дай Бог у кого-нибудь заклинит кардиостимулятор из-за того, что кто-то написал свой велосипед или взял чужой и не протестировал его люто.


        1. progchip666
          08.05.2015 09:24

          Трудно не согласиться.
          В сегодняшнем усложняющемся мире без библиотек не обойтись.
          Но по крайней мере прежде чем использовать их в ответственном приложении, а не конструкции выходного дня крайне желательно заглянуть в код, ознакомиться со списком функций и примерами. Иначе можно пострадать не только из за косяков библиотеки, но и от её некорректного использования. Ведь у любой библиотеки есть свои ограничения. Любая библиотека потребляет определённые ресурсы. Если бездумно использовать разные библиотеки то их ресурсы могут начать пересекаться и тут начнутся такие глюки!!!
          Лично я стараюсь в ответственных участках программы использовать свой код. То же самое в участках требующих высокой производительности. Иногда приходится вплоть до оператора всё оптимизировать или вообще делать ассемблерные вставки.
          С другой стороны писать собственную библиотеку для преобразований Фурье или USB стек с нуля конечно не имеет смысла. Необходимо искать разумные компромиссы.


          1. GarryC Автор
            08.05.2015 10:24

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


            1. progchip666
              08.05.2015 10:36

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


  1. Ezhyg
    07.05.2015 20:18
    +3

    > Только дурак учится на своих ошибках, умный предпочитает учиться на чужих
    Это не верно!
    «Дураки не учатся, умные учатся на своих ошибках и только мудрые — на чужих»


    1. bormotov
      09.05.2015 14:28

      мало кто знает, что есть продолжение:

      … а потом переучиваются на своих


  1. neverman
    08.05.2015 01:56

    вот, кстати, да…

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

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

    «мудрых» — предыдущем посте, тоже косит слово только


    1. Ezhyg
      08.05.2015 11:01

      в «оригинале», кажется было «мудрые предпочитают...», но я постоянно забывают использовать этот вариант :(


  1. aml
    08.05.2015 08:52
    +2

    Проблема серьёзная, и она не только прошивок касается. В электронике разработчики передирают typical applications, даже не удосужившись подобрать номиналы под параметры конкретного устройства. В веб- и десктоп-программировании — одна копипаста со stackoverflow. С распространением IoT чудеса нас ждут — полностью согласен. Статьи в «Хакере» про взлом унитазов будут — это точно.


    1. GarryC Автор
      08.05.2015 10:12
      +3

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


      1. grossws
        09.05.2015 02:31
        +1

        У любителей есть развлечение повеселее: брать схемы из интернетов и не заглядывать в appnotes/datasheet. А потом удивляться нестабильной работе, повышенным шумам или сгоревшим компонентам.

        Я, как любитель, считаю, что любому человеку, который хочет собрать что-то сложнее avr с диодом стоит прочитать что-нибудь из классики. Двухтомник Х-Х, например.


  1. Ivan_83
    08.05.2015 09:17
    +1

    Я не согласен насчёт того что «референс» всегда ужасен.
    Кроме железячников референсы есть ещё много где.
    В тех же RFC, и не всегда они плохи. Например референс MD5 очень качественный (а SHA1 нет, хотя отличаются они мало, в целом).


    1. GarryC Автор
      08.05.2015 10:15

      Конечно, особенно то, что касается дизайна схем, там ошибки крайне редки (но не полностью исключены и я на них натыкался).
      И ни Джек, ни я не призываем к разработке с нуля, он в блоге так ясно и написал, мы лишь предостерегаем от бездумного использования, от предвзятого отношения как к коду, так и к дизайну — раз ЭТО размещено на сайте производителя, то уже заранее правильно.


  1. Vasyutka
    08.05.2015 11:02

    ну регистратор ЭКГ — это не кардиостимулятор, совершенно зря автора передернуло от ужаса. Использовать радио в критичных системах вообще рука ничья не повернется. Особенно в 2.4ГГц

    Так, а вот действительно, вопрос автору и просто присутствующим: а какой BLE подходит для ЭКГ? И какой модуль из доступных это позволил бы сделать. У меня задача попадалась с похожей частотой оцифровки (300-500Гц и 1-3 канала). Это все совершенно прекрасно летит на WT12 на втором BT, но захотелось же BLE! Взял BLE112, там BLE, скрипты, все дела. И с ужасом выяснил, что за те 25мА, которые трачу, не могу выгнать больше 200Гц один канал 16ти битный. И это с отключенным подтверждением о доставки. Просто беру пример от акселерометра (ага, вообще для того и покупал, что бы шлеп-шлеп и в продакшн), отменяю гарантийную доставку и учащаю таймер, играл размером буфером, помогает, но не сильно. И работает все это на 1.5м от компа.

    Встречались BLE модули «чик-чик и в продакшн», желательно с МК и АЦП под щитом?

    а по статье, со всем уважением к размышления автора, это вопрос цены. Критическая система? Какая цена ошибки и сбоя то? (не используйте Bluetooth тогда вообще никогда!!) Есть пол года поизучать/сделать самому? Да слава богу. Нет — даже разбираться не хочу, и так есть в чем.


    1. Vasyutka
      08.05.2015 11:04

      еще раз, подчерку большими буквами про BLE: 25мА, 200 СЭМЛПЕВ В СЕКУНДУ, 1.5м. НЕТ ПОДТВЕРЖДЕНИЯ ДОСТАВКИ
      LOW ENERGY!

      Техподдержка Bluegiga говорит проблемы с Windows 8.1 есть.


    1. GarryC Автор
      08.05.2015 11:57

      Intel Edison — BLE, АЦП и МК в одном флаконе (шутка).


      1. GarryC Автор
        08.05.2015 12:16

        А если серьезно — если буферизовать и сбрасывать длинным пакетом — лучше не станет? Вроде для ЭКГ реал-тайм не особо нужен?
        А так у TI много новинок с обещаниями снижения потребления до 75%, хотя сам пока не пробовал.


        1. Vasyutka
          08.05.2015 15:21

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


  1. Delsian
    08.05.2015 12:11

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


    1. GarryC Автор
      08.05.2015 12:17

      Посмотрите на код наших производителей и вы прибежите к TI со слезами радости, приговаривая «И как я мог ругать такой чудесный код», поскольку наши берут их код и добавляют своих тараканов.