Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С — страница 5 из 70

В этой главе мы дали определение встраиваемым системам и привели примеры таких систем. Мы также обсудили проблемы, связанные с разработкой встраиваемых систем. В заключении мы провели обзор основных технических характеристик микроконтроллеров семейства 68HC12/HCS12, тех МК, с которыми Вы будете иметь дело на протяжении всей этой книги.

1.6. Вопросы и задания

Основные

1. Перечислите основные блоки вычислителя.

2. Какие функции выполняет центральный процессор в составе вычислителя?

3. Дайте определение термину компьютер.

4. Дайте определение термину микропроцессор.

5. Дайте определение термину микроконтроллер.

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

7. Какие функции может исполнять модуль ШИМ микроконтроллера 68HC12 в системе управления?

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

Более сложные

1. Поясните, чем отличаются микроконтроллер и персональный компьютер.

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

3. Приведите примеры работы встроенных систем в реальном масштабе времени?

4. В каких случаях Вы, как разработчик встроенной системы, можете выбрать однокристальный режим работы МК, а в каких расширенный режим работы?

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

Исследовательские

1. Программно–аппаратный дуализм встраиваемой микропроцессорной системы?

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

Глава 2ПРОГРАММИРОВАНИЕ ВСТРАИВАЕМЫХ СИСТЕМ И СТРУКТУРНОЕ ПРОЕКТИРОВАНИЕ

ПОСЛЕ ИЗУЧЕНИЯ ГЛАВЫ ВЫ СМОЖЕТЕ:

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

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

• Рассказать об основных положениях метода структурного проектирования и применить этот метод на практике в области встраиваемых систем.

• Понять важность документирования в процессе разработки.

• Перечислить правила ведения инженером рабочей тетради.

• Применить методы универсального языка моделирования к описанию функционирования встраиваемых систем.

Предлагаемая Вашему вниманию глава, быть может, самая главная в этой книге. Она предлагает Вам несколько шире взглянуть на процесс проектирования встраиваемых систем, нежели Вы делали это до настоящего времени. Мы покажем в этой главе, почему язык Си стал основным языком высокого уровня для проектирования управляющих программ встраиваемых систем. Далее мы сравним технологии программирования встраиваемых систем на Си и на ассемблере и покажем, что оптимальным является сочетание этих двух языков. Следующим предметом нашего изучения будет метод структурного проектирования в приложении к встраиваемым системам. Мы рассмотрим основные положения этого метода и приведем примеры его использования. Мы также рассмотрим способы описания программного продукта с использованием универсального языка моделирования.

2.1. Почему мы программируем микроконтроллеры на Си?

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

В предисловии мы адресовали данную книгу подготовленным читателям, которые знакомы с основами цифровой и микропроцессорной техники, имеют опыт программирования на языке ассемблера для какого либо типа МК. Не пугайтесь, если Вы чувствуете себя недостаточно образованным в перечисленных областях знаний. Мы постарались преподнести материал данной книги так, чтобы он легко усваивался учащимися. Для того чтобы восполнить недостающие знания в области цифровой техники, рекомендуем обратиться к книге [9] или к иным подобным изданиям. Для предварительного знакомства с архитектурой и системой команд микроконтроллеров 68HC12 Вы можете использовать книгу [6].

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

2.2. Преимущества программирования на языке ассемблер

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

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

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

2.3. Преимущества языков высокого уровня

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

Недавно один из авторов этой книги должен был выполнить разработку, в которой заказчик определил использование МК компании Atmel. Он никогда ранее не использовал 8-разрядные МК от компании Atmel, но был не прочь их освоить. Поэтому автор решил выполнять проект на Си. Это позволило ему быстрее завершить исполнение заказа. Если бы он решил выполнять проект на ассемблере, то ему потребовалось значительно больше времени не только для изучения архитектуры и алгоритмов работы периферийных модулей, но и системы команд, поскольку МК Atmel существенно отличаются от знакомых автору МК Motorola/Freescale Semiconductor. Кроме того, область применения устройства была такой, что он мог не беспокоиться о размере программы и времени ее выполнения. Поэтому в приведенных условиях выбор языка Си для проекта был логичным и естественным.

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

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

Языки высокого уровня обладают важным свойством переносимости программного кода. Это означает, что программа, написанная на языке высокого уровня для одного МК, затем может быть скомпилирована другим компилятором для МК с другим процессорным ядром. И эта программа тоже окажется работоспособной. Для того, чтобы программа обладала свойством переносимости, синтаксис языка высокого уровня для разных компиляторов должен быть абсолютно одинаков. В частности, таким свойством обладает язык Си стандарта ANSI (American National Standards Institute). Разработчики называют его просто «ANSI C». Основная цель стандартизации состоит в том, чтобы обеспечить разработчику возможность написания типовых функций управления один раз с последующим их многократным использованием в разных проектах и для разных микроконтроллеров.

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

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

TIMP= (216×n) + (Stop_count − Start_count)

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

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

2.3.1. Выбираем язык высокого уровня для программирования встраиваемых систем

Проведя обзор в Internet, Вы обнаружите достаточно большое число разнообразных компиляторов различных языков высокого уровня для встраиваемых систем. Вы без труда найдете компиляторы Си, С++, Java. Ada, Fortran и некоторые другие. Каждый из этих языков имеет свои преимущества и недостатки. Часто выбор языка программирования может определяться специфическими особенностями задачи или просто пожеланиями заказчика. Детальное сравнение всех перечисленных языков выходит за рамки этой книги и вряд ли возможно.

Для этой книги мы выбрали язык Си, потому что именно он сейчас используется в организациях разработчиков, и он обеспечивает хороший доступ к аппаратным ресурсам микроконтроллеров. Язык Си известен как некоторый промежуточный язык, который объединяет в себе свойства языка высокого уровня и одновременно обеспечивает легкий доступ к регистрам и ячейкам памяти МК. Именно это свойство отмечал один из разработчиков Си господин Ричи (Ritchie).

Язык Си был изобретен в середине 60-ых годов прошлого столетия. Несмотря на почтенный возраст, он так и остался одним из простых и компактных языков высокого уровня. Изначально язык Си был разработан для создания операционной системы Unix, поэтому его характеризуют как «инструмент для создания более сложных инструментов». Язык Си покрывает основные потребности программистов встраиваемых систем без отягощения редко используемыми конструкциями. Более того, программист может достаточно быстро освоить навыки программирования на Си и создавать приложения, которые по быстродействию и затратам памяти близки к ассемблерным. В завершение отметим, что основные конструкции языка Си делают их крайне удобными для реализации принципов структурного программирования.

2.3.2. Краткая история языка Си

Наш разговор о Си был бы неполным, если бы мы кратко не остановились на происхождении этого языка. Для более полного погружения в эту тему советуем обратиться к книге [8]. Ниже по тексту параграфа мы даем краткое изложение одного из разделов этой книги.

Первая версия языка Си была разработана в середине 60 ых годов для разработки операционной системы Unix в лаборатории Bell. Один из самых первых разработчиков этого языка, Кен Томсон (Ken Thompson), решил, что требуется язык для создания более сложных языков программирования. Он создал такой язык и назвал его «B». В процессе развития своего творения Томсон постоянно боролся с ограничением ресурсов памяти, что теперь очень похоже на встраиваемые системы. Деннис Ричи (Dennis Ritchie) решил расширить язык «B» свойством генерировать малый по объему код, который сможет соперничать с кодом, написанным на ассемблере. В 1973 году важнейшие свойства этого нового языка «C» были получены.

Возрастающая популярность Си заложена в его переносимости. Компиляторы Си были созданы для многих платформ (так в сообществе разработчиков называют процессорное ядро МК), отчего его популярность еще больше выросла. Наиболее бурно Си стал использоваться в 80 годах, когда стал основным языком для создания программ персональных компьютеров.

Американский национальный институт стандартизации (American National Standards Institute — ANSI) в 1982 году учредил комитет X3J11 для разработки стандарта языка Си. В 1989 доклад комитета был передан в Международную организации стандартизации (International Organization for Standardization — ISO) и международную электротехническую комиссию (International Electrotechnical Commission — IEC) и был утвержден в качестве стандарта ISO/IEC 9899-1990. За этим стандартом последовало неизбежное развитие языка, которое было узаконено в 1999 стандартом ISO/IEC 9899. И Си стал языком, который наиболее часто используется в компьютерной индустрии.

2.4. Оптимальная стратегия — программирование на Си и на ассемблере