Как стать автором
Обновить

Разглядывая JTAG: самый быстрый программный JTAG на Arduino

Уровень сложностиСредний
Время на прочтение26 мин
Количество просмотров10K
Всего голосов 40: ↑40 и ↓0+55
Комментарии30

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

(картинка с троллейбусом)

Прекрасная реализация..! :) Правда, как мне кажется, правильный вопрос на предложенный вопрос должен быть "А вам зачем?!" потому что должно быть незачем... :)

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

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

P.S. Субъективно, я не слишком положительно отношусть к людям, с разбегу спрашивающих "А вам зачем?". На эту тему у меня есть отделтная статья.

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

А если не секрет, какой непротиворечивый юзкейс может быть? (впрочем, один я знаю -- обязательное соответствие определённому, неизменяемому, чек-листу; вообще он уже достаточно весом чтоб делать "надо так надо").

От слова "статья" ссылка отвалилась -- можно повторить?

p.s.: я всегда спрашиваю "а вам зачем?" даже когда есть идеи зачем -- потому, что я ни раз делал что-то, что оказывалось совсем не тем, что требуется; как в том анекдоте про кастрацию...

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

В этой статье - всё прекрасно. Пожалуйста, продолжайте.

Если допустить перерасход памяти программ, то можно "усушить" лишнюю таблицу переходов

switch_label:

rjmp case_0

rjmp case_1

rjmp case_2

rjmp case_3

при использовании ijmp, использовав грануляцию памяти согласно максимальному размеру ветви и используя

add ZL, r18*case_chunk_size

adc ZH, zero_register

В этой статье - всё прекрасно. Пожалуйста, продолжайте.

Спасибо :) Я и не собирался останавливаться ;)

"В скобках после switch пишется выражение, которое даёт целочисленный
результат. Этот результат поочерёдно сравнивается со значениями,
прописанными после каждого блока case." Возможно для микроконтроллера это так (я не знаю, нужно проверять). А в общем случае это не так. Конструкция switch предназначена для перехода, за одно сравнение, на соответствующий вариант case. Если вариантов мало (например меньше 4-х), то очевидно последовательное сравнение с каждой меткой case не будет сильно дольше и компилятор не генерирует код перехода за одно сравнение. Вообще статья хорошая, интересная.

Конструкция switch предназначена для перехода, за одно сравнение, на соответствующий вариант case

С точки зрения ассемблерных инструкций, если используются инструкции сравнения, то они производят сравнение только пары операндов. И тут два варианта:
1) последовательный перебор вариантов
2) бинарное древо/бинарный поиск

Бинарное древо имеет определённые накладные расходы и в сравнении с последовательным перебором оно начинает выигрывать начиная лишь с определённого количества case.

Но. При этом количестве case-ов бинарное древо, выиграв у последовательного перебора, проиграет (по скорости) конструкции на основе косвенного перехода.

Если же в конструкции switch-case используется инструкция косвенного перехода, то здесь не будет никаких сравнений.

Именно в приведённом в статье примере switch-case на косвенном переходе работает великолепно. Однако в общем случае у него есть ахиллесова пята - что если у нас совокупность возможных значений тестируемой переменной является сильно разреженной? Что если предполагается, например, три case: 1, 2 и 100500? В таком случае switch-case, конечно, сработает столь же быстро, но таблица переходов получится огромного размера. Причём на 99,999% она будет заполнена пустотой.

Поэтому я не вполне понимаю написанное вами. Что значит "за одно сравнение" перейти на "соответствующий вариант case"? Что вы имеете ввиду?

Когда-то давным давно, когда земля была раскаленным шаром, а C -- макроассемблером на стероидах, switch это был способ задать таблицу переходов в исходнике (а не просто синтаксическим сахаром). Но да, даже тогда, это не было "за одно сравнение", те же проверки на на отрицательные, на больше максимума и так далее необходимы для хотя бы default.

Сейчас разницы между switch с breakами и if/else if/else if не должно быть, так как оптимизаторы стараются выжать максимум вне зависимости от исходника.

Товарищ datacompboy прояснил для вас ситуацию, в общих чертах. Дискутировать с ним не буду, достаточно посмотреть исполняемый файл, что бы убедится в том, что switch и if принципиально разные конструкции. Простейший пример это массив меток, результат ключевого выражения это индекс в массиве. Далее выбор метки по индексу и переход. Именно для этого и существует конструкция switch, что бы не перебирать (например) сто ключей. В тривиальных случаях (мало веток case) компилятор считает, что последовательного сравнения хватит и накладные расходы, в виде объёма кода, не нужны. Никакие оптимизации не помогут сделать быстрее чем переход сразу на нужную ветку (если веток много). Ума не приложу, кто вбивает в голову людям, что switch и if это одно и тоже. Вы сами об этом пишете в своём комментарии. А тонкости, что мол сравнения нет... Ну к чему это? Поспорить? Повторюсь , статья хорошая. А тема switch для меня как красная тряпка. Интересуют тонкости компиляции (ну про разряженные таблицы и их огромный размер т.д.), есть интернет, читайте.

А тонкости, что мол сравнения нет... Ну к чему это?

В смысле, тонкости? ))))))))) Вы пишете:

Конструкция switch предназначена для перехода, за одно сравнение, на соответствующий вариант case.

...я вас спрашиваю, как такое возможно? Вы выдаёте абзац экзальтированного текста с вкраплениями "Дискутировать не буду".
Ну такое себе )))) Я бы охарактеризовал это как неконструктивное общение :)

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

Где бы я был без таких советов )

Тссс ))) Не разрушайте картину ))))

Если серьёзно, то большое спасибо за столь оперативно составленные примеры. В такие моменты хочется сказать: Хабр - тот!

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

Сохранение регистра в стек - это 2 машинных цикла, а в ячейку ОЗУ - 1. Поэтому я на AVR сохранял в ОЗУ. Для контроллера без вытесняющих прерываний это допустимо. И обязательно надо сохранять регистр с флагами SREG, чтобы вызов прерывания в момент между арифметической/логической операцией и проверкой результата операции (по флагам SREG) не нарушал работу программы.

Весьма полезный комментарий! Спасибо. Ваше замечание про SREG я внёс в статью.

а в ячейку ОЗУ - 1

У межек/тинек 2 такта. Только у xmega ST/LD 1/2 такта.

При грамотном использовании регистров (то что С должен бы делать, но не сделает) вообще ничего можно не сохранять, кроме SREG (и то не всегда): прерывание использует только свои регистры, основной цикл - свои.

Красивое! Я что то даже не вижу как бы здесь использовать сдвиговый регистр от SPI

На более новых avr появилась куча интересной периферии - там может еще чего то можно придумать.

Я что то даже не вижу как бы здесь использовать сдвиговый регистр от SPI

Штатный SPI сдвигает только один байт. А в JTAG регистр IDCODE в обязательном порядке 32-битный. Так что да. Но с другой стороны - тем лучше этот пример в качестве бенчмарка :)

На более новых avr появилась...

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

Хм-м-м... Возможно, упустил нить. Но что с того, что только один байт? Ну, пусть будет 4 прерывания на 32 бита.

да там такие скорости что он только и делать что прерываться будет, оверхед на прерывания немалый, и самое главное - ничего особо полезного "в свободное время" делать то и ничего. У новых контроллеров avr есть dma - на полном автомате как минимум 4 байта можно послать, плюс usb аппаратный во "втором потоке" - получаем отладчик.

Ну и где в Ваших текстах про JTAG написано как делать тест на пропай электронной платы по Net List(у)?

Всё будет :) Качество статей для меня является приоритетом по отношению к количеству и, соответственно, скорости/частоте публикаций.

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

С JTAG-тестированием в этом смысле есть проблемы. Компании, предлагающие свои решения, все как одна, стараются сделать vendor lock (продавая свои собственные тестеры-программаторы), а также выдать триальную версию ПО только после клятвы на крови, что это ПО будет в дальнейшем куплено.

С другой стороны, то, что инженеры, к которым вы обратились по поводу генерации теста по нет-листу сделали круглые глаза вместо того, чтобы произнести фразы с участием слов Gopel, JTAG Technologies, XJTAG или Corelis - не делает им чести.

Вот то- то. Vendor locking, клятвы, пробные версии...

А мой cross detect на конечном автомате позволяет делать контроль пайки без лишних церемоний. Всем кто пожелает.

Vendor lock и всё остальное в данном случае мешают лишь выпуску статьи, которую могли бы использовать все, в том числе и любители с любым уровнем дохода и подготовки.

Но это не значит, что ваш подход становится автоматически правильным.

Keysight старается сделать vendor lock - давайте теперь вместо их осциллографов использовать самопал на встроенном в STM32 ЦАПе.

National Instruments старается сделать vendor lock - давайте теперь вместо LabVIEW использовать язык ДРАКОН.

У Cadence их EDA Allegro заточена на интеграцию в первую очередь с другими продуктами Cadence - давайте теперь делать трассировку в KiCAD.

Бесплатный LTspice делает vendor lock к продукции Analog Devices. Точно также, как TINA-TI к продукции Texas Instruments. От этого люди не перестают ими пользоваться.

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

Любителя находить опечатки и/или ошибки в тексте наказать святое дело!

Поэтому не удивительно (слитно!), что, например, Texas Instruments выпустили линейку процессоров Sitara AM437x, ориентированных на задачи реального времени.

Иди поплачь или приди понизь мою карму, гений грОмматики.

Поэтому не удивительно (слитно!), что,

Обосновать сможете? :)

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

Лавинный учебник

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

Статья доцента МГИМО

Поэтому не удивительно, что первый портрет писателя написал русский живописец И. Н. Крамской, идеолог и основатель передвижничества.

Описание выставки "Лев Толстой в изобразительном искусстве"

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории