`

СПЕЦИАЛЬНЫЕ
ПАРТНЕРЫ
ПРОЕКТА

Архив номеров

Как изменилось финансирование ИТ-направления в вашей организации?

Best CIO

Определение наиболее профессиональных ИТ-управленцев, лидеров и экспертов в своих отраслях

Человек года

Кто внес наибольший вклад в развитие украинского ИТ-рынка.

Продукт года

Награды «Продукт года» еженедельника «Компьютерное обозрение» за наиболее выдающиеся ИТ-товары

 

Андрей Зубинский

Микроконтроллеры и embedded вообще, часть 03

+1010
голосов

Предыдущие части были как бы совсем вводными, и обстоятельно подумав, я решил немного ускорить процесс и многого, что можно без труда узнать самостоятельно, не разжёвывать. Но впредь всё равно буду концентрироваться на том важном, что отдаляет (и даже отделяет) embedded-разработку от традиционного «большого» программирования.

Теперь – к делу. Извините, но никаких Arduino не будет. Вообще. 8-битовые микроконтроллеры Atmel безусловно хороши (но далеко не всегда и не везде, как и всё прочее), Arduino – полезная и забавная разработка, но обо всём этом без меня написали мегатонны текстов (хороших ли, плохих ли, не мне судить, у меня нет сил всё это читать). Но причина «не-arduin-истости» вовсе не в этом. Слепое использование для обучения Arduino прячет так много важных и интересных деталей, что это уже не столько обучение, сколько баловство без смысла и каких-либо перспектив (это моё скромное мнение, и оно совершенно нескромно обсуждению не подлежит :) ).

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

Второе неприятное в Arduino – это, всё-таки, завершённая система. А целый фрагмент спектра современных микроконтроллеров представляет собой «программируемые компоненты», к которым следует относиться точно так, как к любым дискретным компонентам (разве что они позволяют получить недостижимые для «функциональных вычислителей» свойства). И если «плясать от Arduino», неизбежно придётся об этом фундаментальном забыть. Что очень калечит культуру проектирования формированием стереотипов. Это не наш метод, короче.

Итак, начнём с задачи выбора. Она начинается с понимания и оценки собственно «Задачи Создания Чего-то». Типовой «реальный мир» в «поле зрения» встраиваемого вычислителя выглядит примерно так:

Микроконтроллеры и embedded вообще, часть 03
 
nT – всё, что можно наблюдать во внешнем мире, и что определяется «временем». Так как у нас нет никаких абсолютных способов измерения «времени», мы говорим о соотношении одного числа событий с другими. Например, «временной интервал» - это число событий с заведомо известными параметрами, которое мы подсчитываем в промежутке между двумя другими событиями. «Частота» - почти то же самое, только события с неизвестными параметрами меняются местами с двумя событиями с известными параметрами. И временные параметры задачи (сколько их и какие они) – пожалуй, самое главное, что в ней есть. Ещё главнее только анализ этих временных параметров и выявление из них самого непродолжительного («короткого»). От него зависит всё остальное, в том числе и выбор того, что нужно для решения задачи. Диапазон временных параметров в реальных задачах огромен. В качестве примера возьмём совершенно заурядную задачку – «умный» сенсорный выключатель света. Если это просто «включить-выключить» устройство, то проектировщик его располагает чуть ли не полной свободой – у человека, касающегося сенсора, время реакции очень большое, порядка 0,1 секунды, за это время встраиваемый RISC-вычислитель с тактовой частотой 10 MHz может сделать чуть ли не что угодно, потому что исполнит примерно миллион команд (0,1*10.000.000). Но стоит добавить функцию диммирования (управления яркостью), задача (если мы стараемся её решить максимально задействуя возможности вычислителя, и если речь идёт о лампах накаливания) изменится, для управления яркостью ламп накаливания нужна синхронизация с частотой переменного тока сети, и минимальный временной интервал станет не 0,1 сек, а 1/50 или 1/60 секунды (даже меньше, но это пока неважные детали). С другой стороны, задачи управления малым летательным аппаратом (дроном, например) могут потребовать минимального временного интервала порядка единиц миллисекунд, а что-то ещё (из области управления техническими системами) – и вовсе микросекунд. В общем, если ввести показатель K, индицирующий насколько хорошо разработчик понял задачу и как удачно выделил в ней минимальный временной интервал – стоимость разработки будет N*K, а время - NK (или наоборот, или одновременно с наихудшим значением, как повезёт), где N – произвольное значение, выбираемое по принципу «чтобы больше испугаться».

UI – это напряжения и/или токи. Здесь тоже есть свои нюансы. Для каждого наблюдаемого UI важны диапазоны изменений – это раз,  скорости изменений – два, «чистота» (или наоборот, зашумлённость) – три. Ну и, конечно, количество наблюдаемых UI – это номер «ноль». Естественно, в реальном мире все эти параметры (величины) могут быть исключительно «аналоговыми», и это уже дело разработчика как и когда трактовать аналоговое для решения задачи – когда ограничиваться просто обнаружением факта наличия сигнала (это уже дискретный мир), когда дискретности не достаточно.
∑ - всевозможные косвенные параметры, оценки которых можно или свести ухищрениями к nT и/или UI, или можно и нужно использовать преобразователи этих параметров в перечисленные фундаментальные (сенсоры).

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

Итак, самый первоначальный выбор начинается с анализа задачи – надо составить табличку (или любое неформальное описание) событий (сигналов) внешнего мира, которые необходимы для решения задачи и тщательно изучить особенности этих событий. Имея под рукой такую табличку решать задачу выбора встраиваемого вычислителя намного проще. Например, в табличке есть 14 аналоговых сигналов и 17 дискретных. Это без всяких дополнительных рассуждений означает, что микроконтроллер со всего 18-ю выводами без дополнительных ухищрений для решения задачи не подойдёт. Если есть уточняющая информация о минимальном временном интервале задачи – довольно легко понять какие вычислительные характеристики окажутся пригодными, тем самым можно сразу отсечь море заранее неподходящих микроконтроллеров.

Кроме этих очевидных фундаментальных факторов выбора «от задачи», есть ещё и технологические. Даже если вы любитель и для вас это дело не больше удовлетворения любопытства. Технологичность – штука сложная, потому что учитывает реальные возможности производств (и чужих, и своих). Даже «производство на коленях» имеет свои особенности. Например, позволяющие существенно экономить площадь печатных плат QFN-корпуса – крайне неприятны для любителей, в то же время «сугубо любительские» DIP-корпуса уже смело можно считать устаревшими, потому как всякое «подручное» для любительского использования даже самых маленьких выводных корпусов поверхностного монтажа (SOIC и SSOP) стало совершенно доступным и никаких особенных сложностей с ними нет. К технологичности можно отнести и «доставабельность». В любом нашем магазине электронных компонентов вы можете увидеть унылых людей со списками, наивно пытающихся купить какую-то совершенно замечательную микросхему, которых в нашей реальности просто не существует (и не только потому, что мы такие, какие есть – удачные и очень нужные микросхемы чаще всего выкупаются у производителей огромными тиражами на годы вперёд и их очень трудно отыскать у любых дистрибьюторов). К «доставабельности» относится и политика производителя – некоторые производители компонентов поддерживают небольшие фирмы, ориентированные на выпуск полууникальных изделий с малой серийностью, собственными каналами прямых продаж. И это существенно облегчает жизнь. В более глубокие детали я не хочу и не могу вдаваться, достаточно сказать, что без нормального этапа выбора обычно получается или избыточное, дорогое и сложное аппаратно, или очень простое, но с такой сложностью разработки ПО, что при сравнительно немалой серии лучше пусть оно будет в 10 раз дороже «по железу». К технологическим нюансам следует отнести и инструментальную поддержку производителем, но в 2014 году различия де-факто нивелированы, и большинство компаний предлагают «вообще всё» - от ассемблеров и компиляторов до IDE, очень развитых фреймворков (да, в embedded-программировании эпоха библиотек, похоже, закончилась) и аппаратных средств отладки.

В общем, на основании неоднократных (и не могу сказать, что неуспешных) процедур выбора я давно остановился на контроллерах производства Microchip. И присматриваюсь к многочисленным ARM-контроллерам (особенно с ядром Cortex-M0). К сожалению, производители ARM-контроллеров пока не предлагают самый интересный класс «умных компонентов» (даже несмотря на резкое снижение цен). Ну и у некоторых именитых производителей ARM-клонов (не хочу показывать пальцем) такая документация, что впору её распространять зашифрованной, не раскрывая ключа, разница будет невелика. Посему будем «дружить» с Microchip. Благо, «доставабельность» у них нормальная, но сразу советую не искать каких-то вычурных путей и покупать их «для вивисекции» у нормальных поставщиков (в Украине таковым в первую очередь является официальный дистрибьютор Microchip «Гамма», это не реклама, в вынужденная ссылка).

Microchip производит 3 класса микроконтроллеров с разной разрядностью обрабатываемых данных (обратите внимание на курсив) – 8, 16 и 32 бита. В каждом классе есть свои подклассы, а в них уже – десятки (а то и сотни) моделей. Мы начнём наши «игры» с самыми малышами, которые ещё не совсем «умные компоненты», но уже почти к ним близки. Это обновлённое семейство знаменитых в до-Arduino времена среди самодельщиков мира PIC16. Обновление (Enhanced Mid-Range Architecture, EMRA) оказалось настолько значимым и удачным, что Microchip, невзирая на потоки материалов «8-битовые микроконтроллеры мертвы» впечатляющими темпами «клепает» всё новые и новые микросхемы, и они, похоже, разлетаются, как горячие пирожки (если судить по принципиальной недоставабельности наиболее востребованных промышленностью именно что «умных компонентов» нижнего ценового диапазона).

Пришло время для самого интересного промежуточного – сколько стоит «вход в увлечение» (а для кого-то, возможно, и в будущую профессию). Или минимальный набор «юного embedded-садомазохиста». Цены указывать не буду (они сейчас быстро меняются), но, скажем, всё это будет в пределах похода в ресторан чуть выше средней руки. Главный инструмент – программатор-отладчик. Они у Microchip есть профессиональные (и если для уровня ваших доходов ресторан средней руки характеризуется чеком порядка $300, можете не стесняясь один раз не сходить ради такого удовольствия), есть и более скромные, но пригодные для почти чего угодно. Самое подходящее - PICkit 3 (лучше всего оригинальный, хотя на рынке есть и клоны, которые почему-то дороже). Ориентировочная цена – 500-600 грн. Это самая большая инвестиция. Собственно микросхемы, монтажные платы и прочая мелочь – здесь счёт на десятки гривен. Ну и маленький удобный паяльник (или паяльная станция). Для начала - всё. Необходимое ПО легально бесплатно доступно с сайта Microchip. О прочих нюансах и деталях будет по ходу дела. Как и не только о микроконтроллерах, embedded мир не ими одними жив.

Итак, начнём. PIC16 Enhanced Mid-Range Architecture (EMRA), усовершенствованная архитектура среднего уровня. Признаком принадлежности к ней является шаблон наименования микроконтроллера – все EMRA модели PIC16 именуются так: PIC16(F/L)XXXX, где X – цифра (PIC16 предыдущего поколения содержали три цифры в названиях моделей). Из доступного и очень интересного я выбрал микросхему PIC16F1783. Пока просто скажу – это очень хорошая машина (даже замечательная). Для подчёркивания общности иногда будет упоминаться PIC16F1829. И некоторое внимание будет уделено совсем малышу PIC16F1509, оснащённому очень интересными аппаратными подсистемами. Так, на примере трёх доступных контроллеров, мы попробуем осмотреть если не всё, что можно, то очень многое.

Первое, что нужно сделать, услышав наименование нового микроконтроллера – посетить сайт производителя и загрузить документацию для вдумчивого последующего её изучения. У Microchip она, к слову, одна из лучших в индустрии (до сих пор сказывается опыт, культура и рука Бонни Бейкер, замечательной женщины-инженера, автора неисчислимых документов и многих настольных для профессионалов книг, теперь работающей в Texas Instruments). Два главных класса документов для любого микроконтроллера - Data Sheet и Errata. Первое в деталях описывает как и что должно быть, а второе – как и что получилось в реальности не так, как должно быть (идеального ничего не бывает).

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

Во-первых, мы говорим о машине гарвардского типа, в главном являющейся классической RISC – длина машинного слова в битах у неё больше, чем длина обрабатываемого слова данных. В частности, для EMRA PIC16 разрядность машинного слова – 14 битов, разрядность слова данных – 8 битов. Все машинные команды состоят из одного 14-битового слова, команд из нескольких машинных слов не существует.

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

В-третьих, у этой машины очень много регистров, которые для запутывания непосвящённых называются RAM. Так что изучение «чистого CPU» в отрыве от подсистем памяти в случае с этой машиной почти невозможно.

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

Видимая программисту машина EMRA PIC16 состоит из 31-го почти одинакового «регистрового окна контекста» (пусть будет РОК) и 32-го «регистрового окна специального контекста» (РОСК), доступ к каждому из которых осуществляется изменением содержимого специального регистра. Одно РОК состоит из 127 регистров с адресами от 0 до 126 (0x00-0x7F в 16-ричной системе, то есть, внутри окна контекста для адресации индивидуальных регистров достаточно семи битов) и выглядит так:

Микроконтроллеры и embedded вообще, часть 03

 
Выделенные красным области (регистры процессорного ядра и независимые от контекста) при выборе любого из 32-х контекстов остаются в адресном пространстве CPU «на своих местах», то есть всегда доступны, они одни и те же, независимо от выбранного контекста. О «фокусе» с отображением регистров всех окон контекстов на линейную систему адресов и о регистровом окне специального контекста (РОСК) поговорим позже (оно принципиально новое в EMRA), после необходимой детализации.
12 регистров процессорного ядра – то, что в более традиционных микроконтроллерах и процессорах принято называть собственно «архитектурой CPU» (для начала приведу просто таблицу, затем проиллюстрирую её более наглядным рисунком):

Микроконтроллеры и embedded вообще, часть 03

«Подсвеченные» желтым цветом регистры EMRA CPU выделены не для красоты – их содержимое автоматически аппаратно сохраняется в «теневых» копиях в начале процедур обработки прерывания (и содержимое этих «теневых копий» программно доступно, но и  об этом позже). Давайте посмотрим на эту таблицу более традиционно, как принято для большинства CPU:

Микроконтроллеры и embedded вообще, часть 03

 
На деле это очень традиционный CPU, архитектурно весьма похожий на знаменитые и до сих пор выпускающиеся встраиваемые CISC-процессоры, например, на культовый Motorola 6809, наследники которого живее всех живых по сей день:

Микроконтроллеры и embedded вообще, часть 03
 
Теперь давайте «соберём» часть большой картины:

Микроконтроллеры и embedded вообще, часть 03

 
В зависимости от физического количества регистров общего назначения NR (размера RAM или SRAM согласно документации), каждый конкретный EMRA PIC16 содержит целое число NR/80 регистровых окон контекста (РОК) c 80-ю регистрами общего назначения, возможно одно дополнительное РОК с числом регистров общего назначения, равным остатку от деления на 80, и непременно последнее, 32-е регистровое окно специального контекста РОСК. Так, например, PIC16F1783 содержит целых семь заполненных регистрами общего назначения РОК (шесть – по 80 регистров общего назначения, и одно – 32 регистра) и одно обязательное РОСК. В РОК, где нет регистров общего назначения, всё равно есть регистры интрефейсов периферии (зелёная лента на рисунке) и две обязательные разделяемые регистровые области. В общей для всех РОК и РОСК 12-регистровой области (верхняя красная полоса на рисунке) 5 младших битов содержимого регистра BSR (голубой прямоугольник на красном, селектор регистрового окна) определяют текущий РОК, который в данный момент «попадает» в 7-битовое адресное пространство системы команд CPU. За пределы этого адресного пространства можно «заглядывать» с помощью косвенной адресации, причём косвенная адресация отображает на единое линейной адресное пространство RAM (регистры) и память программ (что для машины гарвардской архитектуры – весьма забавная особенность). Больше того, EMRA PIC16 позволяют с помощью механизма косвенной адресации программно «переписывать» флеш-память программ (что раньше было отличительной способностью высокоуровневых микроконтроллеров).

Пока ни разу не был упомянут важнейший элемент любого процессора – стек возвратов, – давайте посмотрим на эту архитектуру глазами программиста из 2014 года. Это нужно для пояснения весьма вольных терминов «регистровое окно контекста». По сути, архитектура реализует существенный фрагмент аппаратной поддержки «актёров» (шаблонов ли програмимрования, архитектуры ли, не важно). Она даёт в распоряжение программиста быстро изменяемый одной машинной командой контекст (80 байтов для многих управляющих задач далеко не так мало, как кажется, а с учётом «напичканности» почти автономной периферией EMRA PIC16 – и  вовсе большая цифра), за пределы которого можно «выглянуть» только специальным методом адресации и несколькими специальными командами, его использующими. Она даёт разделяемую между «актёрами» память (16 независимых от контекста регистров), или mailbox, в терминах архитектуры «актёров». И, наконец, она даёт очень быстрый вход в процедуру обработки прерывания (с копированием всех нужных системных регистров в теневой области – от трёх до пяти машинных циклов), без единого лишнего действия со стороны программиста.

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

Система команд EMRA PIC16 компактна – всего 49 команд, причём, как положено чистой RISC-машине, любая команда реализуется всего одним 14-битовым словом. Для большинства RMW-операций (это же RISC-машина, и в ней почти все операции – Read-Modify-Write, я об этой идиоме писал ранее) все 127 регистров текущего РОК практически равнозначны, аккумулятор WREG хоть и сохраняет своё специфическое назначение, но в RMW-командах можно выбирать куда будет помещён результат – в аккумулятор или указанный в коде команды регистр.

В следующем фрагменте продвинемся дальше. И так – вплоть до конкретики (что это будет – пока тайна, но, надеюсь, будет интересно).  

Откланиваюсь

+1010
голосов

Напечатать Отправить другу

Читайте также

Андрей, я так понимаю, что Ваш «упор» на PIC – это дань традиции. А планируете ли что-то по решениям AVR (Atmega)?

нет, это дань качеству и возможностям
об Atmel AVR слишком много написано, чтобы добавлять что-то
да и ничего особо нового в семействе AVR не видно совсем

ATXmega не в счёт?

Честно говоря, когда Вы в части 2 этого цикла упоминали про быстрый выход из спячего положения в активное состояние, я подумал про msp430.

 
 
IDC
Реклама

  •  Home  •  Рынок  •  ИТ-директор  •  CloudComputing  •  Hard  •  Soft  •  Сети  •  Безопасность  •  Наука  •  IoT