enter image description here


Не могу назвать себя очень аккуратным и внимательным человеком, но тем не менее, за более чем 10 лет разработки ПО для встраиваемых устройств мне толком не удалось ничего сжечь или испортить. С одной стороны, стоит за это сказать "спасибо" моим коллегам — схемотехникам. С другой стороны, современная "умная" микроэлектроника имеет достаточно серьезную "защиту от дурака". Но пару дней назад произошел один интересный случай. Мне удалось превратить в "кирпич" микроконтроллер Atmel SAMD21G18AU, выполняя обычные манипуляции, описанные в user manual.


Как-то так получилось, что еще со студенческих времен меня учили, что "с Atmel работают одни дилетанты", поэтому использовать его не стоит. Аргумент весьма сомнительный, но по принципу "не читал, но осуждаю", нелюбовь к Atmel передалась и ко мне.


Однако в один прекрасный момент к нам пришел очередной заказчик и принес проект устройства, которое нужно доработать и для которого нужно написать "прошивку". Ядром этого устройства является микроконтроллер Atmel SAMD21G18AU. Так мне пришлось откинуть свои предрассудки и начать изучать данный кристалл.


enter image description here


Микроконтроллер оказался достаточно известным и распространенным благодаря ArduinoZero.


enter image description here


После изучения общих параметров я был очень впечатлен. Контроллер имеет мало общего со старыми атмеловскими семействами, работает на ядре Cortex M0 и использует мудреную систему конфигурации периферии, которой у него очень много.


enter image description here


Эта система позволяет гибко настраивать кристалл под широкий круг задач, но она же и повышает его "сложность" и отрицательно влияет на кривую обучения работы с ним (Arduino IDE я в расчет не беру :).


При этом Atmel имеет собственную программную библиотеку для работы со своими микроконтроллерами Atmel Software Framework. Дело хорошее, до тех пор, пока не начинаешь ей пользоваться :) Библиотека рассчитана для работы в IAR и Atmel Studio и содержит огромное количество драйверов, модулей и примеров почти для всех контроллеров Atmel… Но спроектирована и задокументирована она, на мой взгляд, достаточно плохо (попробуйте разобраться с ней сами)


Архитектура библиотеки спроектирована так, что все "завязано" на отладочные платы:


enter image description here


То есть чтобы использовать библиотеку для своей собственной платы, вам нужно сделать ее "описание" в определенном формате (весьма невнятно документированном) и поправить пару файлов (в частности, board.h). При этом, если вы хотите просто взять конкретный драйвер и использовать его в своем проекте, то вы столкнетесь с серьезными трудностями. Особенно если ваш проект сделан не в IAR или Atmel Studio. Придется долго разгребать зависимости модулей и вычленять необходимые файлы.


Этот-то процесс и погубил мой экземпляр контроллера. Мне нужен был драйвер Watchdog. Он в свою очередь тянет несколько других драйверов, среди которых драйвер Clock, занимающийся настройкой тактовых генераторов как для ядра, так и для периферии. Ну а Clock использует специальный .h файл, содержащий конфигурацию генераторов для конкретного устройства. И мне так "повезло", что мне попался не тот файл, который в итоге отключил мне тактовый генератор ядра, а заодно и модуля для работы с SWD.


SAMD21G18AU имеет два встроенных тактовых генератора и позволяет использовать два внешних. Модуль GENERIC CLOCK CONTROLLER имеет в своем составе несколько внутренних генераторов. Первый из них тактирует ядро, остальные используются для тактирования периферии. Для каждого внутреннего генератора можно задать источник (внутренний или внешний), множитель и другие параметры, среди которых есть "OnDemand". Он позволяет запускать генератор "по требованию", тем самым уменьшая потребление системы.


enter image description here


После перезагрузки SAMD21G18AU по умолчанию настраивает работу ядра от внутреннего генератора на 8 МГц, а остальные генераторы отключает.


Файл, который попался мне, заставляет драйвер Clock настроить тактирование ядра на внутренний 8 МГц'овый генератор, но при этом переводит его в режим "OnDemand". Но этот режим почему-то не срабатывает и генератор не заводится. Получается, что как только контроллер начинает выполнять код, он отключает себе тактирование.


При этом модуль работы с SWD тоже перестает тактироваться, а значит и перестает отвечать при попытке соединения. И никакие ухищрения не помогают поймать момент, когда процессор уже включился, но еще не успел отработать кривую настройку модуля GENERIC CLOCK CONTROLLER.


Можно было бы воспользоваться перепрошивкой через bootloader. Обычно в микроконтроллерах есть "зашитый" загрузчик, позволяющий программировать его как минимум через COM-порт. Но не тут-то было! Atmel перехитрил сам себя. Хотя использование bootloadr'а и предусмотрено, но из-за "гибкости" в настройках место, зарезервированное под него, может быть использовано для хранения исполняемого кода. И, похоже, это является настройкой по умолчанию.


То есть, чтобы работать с bootloader'ом, его нужно сначала "зашить" в контроллер. И конечно, в моем случае это сделано не было.


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


В заключении истории хочу сказать, что я все-таки не обладаю глубокими навыками работы с данным микроконтроллером, поэтому, возможно, есть способ его "оживить". Может быть, кто-то мне подскажет решение проблемы, пока мы не отпаяли "кирпич" и не припаяли новый SAMD21G18AU?


p.s. Ну а моя нелюбовь к Atmel получила первый аргумент в свою пользу. Контроллер, позволяющий загнать себя в тупик комбинацией настроек, при этом не имеющий штатных средств восстановления — это как-то не солидно...

Поделиться с друзьями
-->

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


  1. za121
    29.08.2016 10:07
    -28

    Двойные стандарты.


    1. za121
      29.08.2016 12:24
      +3

      Прошу прощения, за мой коммент выше, ошибся вкладкой.


      1. uSide
        29.08.2016 16:07
        +3

        Это вторая статья, где я это увидел и в обоих случаях ваш комментарий заминусовали. Задумайтесь


  1. Sergei2405
    29.08.2016 10:12
    +2

    Как вариант попробовать разогнать SWD до максимальных частот и попробовать перехватить управление (остановить программу) до момента когда она стопит тактовые частоты. Или «поиграть» с настройками сброса «connect under reset». Перебрать отладочные шнурки типа Ulink/ULINK-pro/J-link…


    1. AlexandrSurkov
      29.08.2016 11:45
      +1

      Я пробовал только uLink. С ним ничего не получилось. Когда добуду JLink — попробую с ним.


  1. golf2109
    29.08.2016 11:07
    +2

    а что пишет Datasheet о режиме OnDemand — каковы условия для входа в него и выхода из него?
    каким программатором-отладчиком пользуетесь?
    в J-link есть режим Connect under Reset — может это поможет?


    1. AlexandrSurkov
      29.08.2016 11:47

      У меня сейчас есть только uLink и соответственно uVision. Там перепробовал все режимы — не помогает. Тут же еще SWD. Он не все режимы полноценного JTAG поддерживает.


      1. golf2109
        29.08.2016 12:02
        +3

        Для STM32 мне помогло Debug->Connect & Reset Option -> Connect:under Reset Reset:HW RESET


  1. vilgeforce
    29.08.2016 11:16

    Внешние кварцы не помогают? JTAG или подобное есть?


    1. AlexandrSurkov
      29.08.2016 11:48

      Кварцы стоят, но они программно отключаются сразу после выполнения пользовательского кода.


  1. Polarisru
    29.08.2016 11:33
    +1

    еще со студенческих времен меня учили, что «с Atmel работают одни дилетанты»
    Дальше можно не читать. Специалисты — такие специалисты!


  1. Tsvetik
    29.08.2016 11:54
    +1

    Неужели у этого МК нет ноги или комбинации для полоног стирания кристалла?


    1. AlexandrSurkov
      29.08.2016 11:54

      Похоже что нет.


      1. Tsvetik
        29.08.2016 12:01
        +1

        А это что?
        http://www.atmel.com/Images/Atmel-42181-SAM-D21_Datasheet.pdf

        пункт 13.7


        1. AlexandrSurkov
          29.08.2016 12:20

          The Chip-Erase operation is triggered by writing a '1' to the Chip-Erase bit in the Control register (CTRL.CE)

          Это программный сброс.


          1. Tsvetik
            29.08.2016 12:34
            +9

            Там далее, по ссылке «cold start» можно узнать, что есть, так называемый «CPU reset extension».
            После внешнего ресета CPU, если видит отладчик, то сидит и ждет записи бита в спец регистр CSRTEXT.
            Пока отладчик этого не сделал, CPU не выйдет из ресета и программа в МК не запустится.

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


            1. rsx11
              29.08.2016 13:36
              +5

              Более того, этот CPU reset extension прекрасно описан там же в 13.6.2. Судя по всему, всё, что требуется, — это притянуть SWCLK к земле, пока отпускается ресет. Может, даже никаких скриптов или специальных отладчиков не нужно.


  1. xby
    29.08.2016 11:54
    +5

    «с Atmel работают одни дилетанты» — плод несозревшего юношеского сознания…


  1. FloppyFormator
    29.08.2016 12:00
    +2

    Можно аккуратно вскрыть кристалл и ультрафиолетом засветить ПЗУ, где хранятся настройки.


    1. AlexandrSurkov
      29.08.2016 12:02

      Экстримальный способ :) Проще перепаять ИМХО.


    1. vehar
      29.08.2016 13:36
      +1

      Ещё из вариантов:
      — ултрафиолет+вскрытие = рентген без вскрытия. Или другое ионизирующее излучение достаточной мощности чтобы пройти через корпус
      — пощупать его мощным высокочастотным эми
      — аккуратно(!) пройтись высоким напряжениям по пинам контроллера (типа електрозажигалки, но на расстоянии, дабы не было пробоя). Это если совсем безнадёга :D — имеется риск сжечь что-то работающее(!)

      А по хорошему — успеть программатором, как советовали. У STM32F4 (горький опыт) тоже есть такая фишка, если случается переход в какой-то глубоко спящий режим(точно не вспомню) а доступ только через SWD. Про Hwreset не скажу, т.к. обошлось без него.
      Возможно для ATMEL есть ещё какие-то свои отладочные ср-ва


  1. Immortal_Buka
    29.08.2016 13:36
    +2

    через SWD under reset например


  1. a_volkov1987
    29.08.2016 13:36

    Не знаю в точности, как обстоит с кортексом, но серия mega у Atmel в случае ошибочно прошитого конфига источника тактирования (например вместо кварца выбрали RC-цепочку) тоже не поддается сбросу, если у вас нет программатора с выходом тактирования. При входе в режим программирования mega выбирает в качестве источника тактирования или источник, указанный в настройках кристалла или же тактируется внешним генератором, который входит в состав программатора (особо подчеркну, что не любой программатор имеет выход тактирования. Phyton'оновские имеют точно). Прочитайте внимательно даташит на контроллер, скорее всего его тоже можно сбросить подобным способом.


    1. masai
      29.08.2016 16:27
      +1

      AVR — это принципиально другая архитектура. Там тестирование задается жёстко фьюзами. У ARM нет фьюзов.


      1. masai
        29.08.2016 16:36

        Прошу прощения, мой телефон внёс правки. :)


        Не тестирование, а тактирование, конечно. И я не дописал: у ARM нет фьюзов для жёсткого задания тактирования, это делает программный код. Собственно, об этом и речь в статье.


  1. pftbest
    29.08.2016 13:59
    +2

    Радиационно стойкие микроконтроллеры от Atmel сейчас очень популярны для малых космических аппаратов, и я бы не сказал что их дилетанты проектируют.


  1. MyXoMoPz
    29.08.2016 14:14
    +1

    Была аналогичная проблема на Stm32f100 при попытке переносе проекта из Cube'a в кокос, мк тоже не подавал признаков жизни. Из-за того что программатор был от VLdiscovery, не было возможности сделать Connect under Reset, просто потому что у программатора не было этого провода. Решилось так: прижимаем ресет, в утилитке нажимаем full chip erase, отпускаем ресет и мк очищается.


  1. andi123
    29.08.2016 14:15
    +1

    На старых добрых «мегах», всегда можно было воспользоваться HV-программированием и подключить выключенный SPIEN.
    > Я пробовал только uLink. С ним ничего не получилось. Когда добуду JLink — попробую с ним.
    Мдя. Видимо про OpenOCD, вы ничего не слышали?


  1. Arcanum7
    29.08.2016 14:46
    -2

    Стандартный высоковольтный программатор не? ВСЕ (поправьте если не прав) чипы от атмеля могут прошиваться через 12в программаторы.
    Read datashee, Luke!


    1. masai
      29.08.2016 16:50
      +2

      Стандартный высоковольтный программатор — это для AVR, у ARM по-другому всё, они программируются через SWD. Atmel ? AVR.


  1. olekl
    29.08.2016 15:24

    У ATMEGA похожая фича есть. В фьюзах есть биты, определяющие, откуда тактировать. И среди всех комбинаций есть неиспользуемые. И если таковую туда записать, то получается необратимый кирпич… А еще чтоб положительных эмоций себе добавить, попробуйте обратиться в их техподдержку :)


    1. ulole
      29.08.2016 18:41
      +1

      Не подскажете пример такой комбинации? Сколько я ни издевался над Мегой, пытаясь превратить ее в кирпич, всегда удавалось воскресить МК параллельным программатором (у меня Фитон)


      1. olekl
        30.08.2016 11:18

        ATMEGA165p, в байте Fuse Low четыре младших бита — CKSEL. По умолчанию там 0010 (внутренний клок), а зарезервированные значения — 0011, 0001, 0101, 0100. Значение 0000 — внешний клок (если записать туда 0000 при отсутствии внешнего клока — тоже весело, но все же решаемо).


      1. unsvp
        30.08.2016 11:22

        Классический вариант — в прошивке переключаемся на внешний кварц, который нераспаян. В поздних ревизиях чипов это исправили — RC генератор продолжает работать на низкой частоте и чип живет, хоть и очень медленно.
        У некоторых чипов (например ATmega8) пин RESET совмещен с GPIO и фьюзом можно заблокировать RESET, что делает последовательное программирование и отладку невозможными.
        Параллельное программирование спасает только если у вас все нужные пины или свободные, или толерантны к внешним сигналам. Такое в реальных схемах редко встречается — держать 16 пинов в качестве запасных довольно расточительно.


        1. ulole
          30.08.2016 11:39

          Да, это понятно. Но подразумевалось, очевидно, что кирпичом становится сам МК, то есть никакими манипуляциями его уже не воскресить. А на самом деле имелось в виду, что запаянный МК в smd-корпусе с разъемом для последовательного програмирования становится кирпичом. А так, если корпус DIP(что нередко в любительских конструкциях) — достаем проц из панельки и восстанавливаем заводские настройки фьюзов параллельным программатором. Можно заморочиться и отпаять МК от платы и также воскресить параллельным программатором через специальный переходник(ZIF socket for SMD). Только не уверен, что МК выдержит еще один цикл запайки.


          1. unsvp
            30.08.2016 12:32

            Любительские конструкции и DIP-корпус — это отдельная тема…
            В коммерческих же устройствах нет разницы — окирпичился МК или всё устройство, в любом случае — это возврат по гарантии со всеми вытекающими издержками. А если устройство нельзя перепрошить на месте или хотя бы в сервисе — значит, это кирпич. Фьюзы у ATmega пишутся как-то ненадёжно, бывает, что сдвигаются на 1 байт — сталкиваемся с этим даже в производстве. Что уж говорить об удаленном обновлении прошивки — каждый раз стресс. Порядка 80% возвратов по гарантии — сбой фьюзов при обновлении firmware. Дизайн старый, параллельное программирование невозможно, так что чипы выбрасываются и впаиваются новые. Если прибавить сюда так и не исправленный за 15 лет flash (непредсказуемая выносливость по числу перезаписей), то становится понятно, почему у Атмел репутация — «контроллеры для любителей».


  1. Dark_Purple
    29.08.2016 23:05

    Ну так это дело не в контроллере, «проблема с руками». Эдак любой контроллер убить можно. Как в анекдоте: «Один сломал, второй потерял.»
    Имеет смысл на этапе отладки поставить после старта задержку на пару сек. чтобы отладчик успел зацепится.


    1. masai
      29.08.2016 23:45

      Да контроллер не убит вовсе, а очень даже наоборот. Просто его теперь не запрограммировать, пока он работает. Но для этого и придумали Cold-Plugging (он же "Connection under reset" много раз тут упоминавшийся). Надеюсь, автору это поможет и он добавит в статью историю о решении возникшей проблемы. :)


  1. armature_current
    30.08.2016 09:08
    +1

    Имея опыт разработки аппаратных проишивальщиков/загрузчиков могу с большой долей уверенности сказать, что в любом контроллере в режиме Under-reset должен осуществляться опрос портов встроенного дебагера. Дебагер ждет появления определенной входной последовательности на выделенной для этого ноге, при этом тактируется по заводским настройкам. В зависимости от задачи, иногда ведь приходится задействовать и пины отладочного модуля в пользовательском режиме. Причем с конфигурацией через так называемые option-bits, которые загружаются еще до попадания на вектор Reset. Чтоб была возможность перепрошить контроллер каждый производитель просто обязан предусмотреть вход в отладочный режим в состоянии reset'a. Конечно же, если речь не идет об однократно-программируемых. Другое дело, что указанный внутрисхемный отладчик не полностью реализует необходимую последовательность подключения.