Селекция полезных сигналов. Проектирование и программирование интеллектуальных сенсоров
27.3. Программирование интеллектуальных сенсоров
Для того, чтобы сенсор был и в самом деле интеллектуальным, "разумным", его надо правильно запрограммировать. Это означает – разработать и записать в память сенсора всесторонне продуманные и проверенные программы работы микрокомпьютера.
Значительная часть "интеллектуальности" сенсора определяется именно его программным обеспечением. Тот, кто всерьез занимался программированием компьютеров или микрокомпьютеров, не раз сталкивался с удивительным ощущением. Имеешь дело с тем же самым "железом", с той же конструкцией машины, устройства, сенсора. В их составе ничего не меняется. Ты лишь заносишь в память лучшую программу. И на глазах происходит чудо: плохо "соображавший" ранее "тупой автомат" вдруг превращается в "разумное существо", которое удивительно осмысленно, рационально действует на всем множестве прогнозируемых ситуаций! И чем лучше продумана программа, тем "умнее", точнее становятся действия сенсора, его реакции на изменения ситуации. А при хорошо продуманных программах сенсор разумно "ведет себя" даже и в заранее не прогнозированных ситуациях. В такие минуты ощущаешь себя "чуточку богом", поскольку именно ты "вселил в мертвое железо ум".
Но, ради истины, надо подчеркнуть, что значительную часть "интеллектуальности" сенсора определяют также его конструкция, выбранный микропроцессор, микроконтроллер, микроконвертор. Когда переходишь от одного микропроцессора к другому, более совершенному, который почти на таком же кремниевом чипе имеет значительно больше возможностей, на котором "идут" значительно более сложные и эффективные программы, то понимаешь, что микропроцессор – это далеко не "мертвое железо". И всегда восхищаешься мудростью и мастерством тех, кто разрабатывал, проектировал и изготавливал этот чип. Ведь они создали не больше и не меньше, как "искусственный мозг", который во многом уступает, но кое в чем и превосходит биологический мозг, созданный природой!
27.3.1. Рекомендуемый порядок разработки программ
Исходя из собственного опыта программирования интеллектуальных сенсоров, мы можем посоветовать следующий порядок разработки текстов программ. Разработку стоит начинать с подготовки документа "Постановка задачи" и написания полного "сценария" работы сенсора ( рис. 27.3).
Рис. 27.3. Рекомендуемая последовательность разработки текста программы работы интеллектуального сенсора
увеличить изображение
Рис. 27.3. Рекомендуемая последовательность разработки текста программы работы интеллектуального сенсора
"Сценарий работы" интеллектуального сенсора представляет собой детальное описание работы сенсора во всех предполагаемых режимах и ситуациях. Он нужен для того, чтобы четко понимать, что в каждом из режимов, в каждой ситуации должен делать микрокомпьютер.
Оба эти документа следует обсудить, обдумать, согласовать с конструкторами всех основных узлов сенсора и с теми специалистами, которые будут им пользоваться. Сам факт официального подписания этих документов с последующей возможной ответственностью за ошибки стимулирует всех участников добросовестно отнестись к работе по их созданию, избежать многих досадных "промахов", которые обычно случаются при легкомысленном отношении к этой работе и очень досаждают, а то и могут дорого обойтись на следующих этапах разработки интеллектуального сенсора. "Постановка задачи" и "Сценарий работы", насколько это возможно, должны предусматривать и перспективное развитие, предполагаемые усовершенствования сенсора, должны быть ориентированы в будущее. На конкретном этапе разработки временный сценарий работы может быть упрощенным, неполным, "урезанным". Но ориентировка "на максимум", на будущее заложит основу для существенного сокращения работы по программированию будущих усовершенствованных версий сенсора.
27.3.2. Метод постепенной декомпозиции
На основе хорошо продуманного, согласованного со специалистами сценария составляются блок-схемы программы методом постепенной декомпозиции. Сначала составляется наиболее общая ("системная") блок-схема, определяющая крупнейшие программные блоки, которые будут обслуживать основные режимы и этапы работы сенсора, порядок передачи управления от одних блоков к другим. Названия программных блоков и их программные "метки" следует подбирать так, чтобы по названию легко было догадаться об их назначении. Далее крупные программные блоки детализируют, создавая блок-схемы уже для каждого из них. Детализацию продолжают до тех пор, пока не станет возможным для каждого из программных модулей начертить уже детальную схему алгоритма его работы или свести его к какой-то стандартной подпрограмме, которая уже отработана у разработчика и имеется в библиотеке стандартных программных модулей. На этом этапе алгоритмизации надо рассмотреть все возможные методы реализации сложных преобразований и выбрать из них наилучший для данных конкретных условий. Затраты времени на это, как правило, окупаются потом сокращением сроков разработки и качеством программ.
Сопоставляя алгоритмические схемы всех программных модулей, находят похожие их части или почти одинаковые блоки и, если это сулит определенный выигрыш, формируют специфические для данного сенсора стандартные процедуры. Разработанные алгоритмические схемы корректируют с учетом этих процедур и внимательно выискивают пути дальнейшей рационализации.
Уже на этом этапе следует подбирать контрольные примеры для последующей отладки всех возможных разветвлений ("веток", "траекторий") каждой процедуры. Во-первых, так или иначе, это придется сделать на этапах отладки и контроля программы, во-вторых, это поможет как можно раньше выявить ошибки и своевременно избавиться от неопределенностей и нестыковок в составленной алгоритмической схеме, что сократит время разработки. Чтобы подобрать эффективные контрольные примеры, анализируют поведение программного модуля при изменении значений входных данных, определяют область допустимых значений, критические значения входных данных, если таковые есть. Размышляют над тем, как будет работать программный модуль, если в него по ошибке попадут критические входные данные или данные, выходящие из области допустимых значений. И, в случае необходимости, вводят страхующие процедуры. На этом этапе стоит обратить внимание на потребности в использовании таймеров-счетчиков и предотвратить возможность "конфликтов" в их использовании разными подпрограммами.
Во многих учебниках и указаниях по программированию утверждается, что каждый программный модуль должен иметь лишь одну точку входа и одну точку выхода. В большинстве случаев таки следует придерживаться этой рекомендации. Но не стоит воспринимать ее как категорически необходимое требование. В частности, это касается "диагностических" программных модулей, контролирующих значения входных или внутренних текущих данных и, если они выходят за допустимый диапазон, должны сообщить об этом пользователю и дальше действовать по его указаниям. Такие модули могут иметь несколько выходов. Но надо внимательно проанализировать каждый из возможных выходов, чтобы ни один из них не создавал предпосылок для ошибочного функционирования следующих программных модулей. На каждом из выходов всё должно быть "тщательно убрано за собой".
Для "подпрограмм", которые претендуют на пополнение библиотеки стандартных подпрограмм, это требование "один вход и один выход" является обязательным. Это зафиксировано даже в международном стандарте на программные продукты Hierarchy-Input-Process-Output (HIPO). Для подпрограмм исключается также "эффект последействия", когда текущая работа программы может повлиять на ее работу при следующих вызовах. Как правило, подпрограммы параметризируются, т.е. предполагается, что вызов такой подпрограммы должен сопровождаться указанием значений ее параметров и/или операндов (входных данных, которые в ней будут обрабатываться). Преимуществами широкого использования подпрограмм являются сокращение длины программы работы сенсора в целом, возможность их автономной отладки, параллельной их разработки несколькими программистами, экономия времени при комплексной отладке сенсора и перспектива использования при программировании следующих усовершенствованных образцов сенсора и при будущих разработках других сенсоров.
На этапе коррекции алгоритмических схем программных модулей следует провести многократное "мысленное имитирование" их работы в специально осложненных случаях, при наличии всех возможных прерываний (даже не предвиденных), в том числе, когда из-за отвлечения на обработку прерываний можно не заметить какое-то важное кратковременное событие.
27.3.3. Подготовка текстов программ
Лишь после итерационной коррекции алгоритмических схем, когда они уже стали для Вас совсем четкими и прозрачными, следует приступать к написанию текстов процедур, подпрограмм и программных модулей. К этому времени должны быть окончательно известны программные адреса всех интерфейсов контроллера, т.е. выводов и портов, через которые вводится или выводится каждый элемент данных, и формат, в котором это происходит. Сначала делают предварительное распределение памяти программ и памяти данных и выбирают язык программирования.
Практика показала, что оптимальными для программирования интеллектуальных сенсоров являются 2 алгоритмических языка: "ассемблер" и "СИ". Программировать на них несколько сложнее и дольше, чем на языках высокого уровня, но после трансляции на машинный язык программы выходят короче, эффективней и работают быстрее. Существует много учебников и справочников по программированию на этих языках. Мы советуем начинать написание текстов с подпрограмм обработки прерываний. Они должны быть как можно короче, быстро выполняться и, главное, не вредить работе тех программных модулей, выполнение которых они могут прерывать, и всех других. С этой целью для подпрограмм обработки прерываний выделяют отдельные ячейки памяти или регистры либо в начале их работы "прячут" коды, находящиеся в нужных им регистрах, а после окончания работы восстанавливают исходное содержимое этих регистров.
Дальше мы советуем не пожалеть время на так называемую спецификацию памяти, т.е. на поиск наиболее рациональной схемы использования областей (блоков) памяти данных, ее наиболее быстро доступных регистров и ячеек с разными правилами доступа с учетом нужд подпрограмм обработки прерываний. Ведь от этого будет зависеть время выполнения, надежность, длина создаваемой программы.
При написании текстов программных модулей обязательно надо сопровождать их достаточным количеством комментариев-объяснений, чтобы через полгода – год, когда Вы уже забудете детали этой программы, Вы сами или тот, кто продолжит работу, смогли по имеющимся комментариям быстро понять всю логику программы. Не следует экономить время, отказываясь от комментариев, поскольку может произойти так, что через полгода и Вам самим, и другому программисту легче будет написать новый текст программы, чем разобраться в Вашем, к которому нет никаких объяснений. Призрачная "экономия" превратится в свою противоположность – в дополнительные затраты времени.
После написания текстов всех программных модулей стоит для каждого из них составить полные списки адресов памяти, которые в них используются, с указанием назначения. Дальше эти списки надо внимательно сопоставить и проанализировать с целью недопущения конфликтов между программными модулями, которые используют тот самый регистр или одну и ту же ячейку и поэтому потенциально могут помешать друг другу, изменяя код в этой ячейке. В случае необходимости оптимизируют распределение памяти данных и корректируют тексты соответствующих программных модулей.
27.3.4. Отладка программ
Дальше следует использовать одну из так называемых "кросс-систем" автоматизированной подготовки программ, которые ныне легко доступны. В состав такой системы обычно входят:
- редактор текстов программ, который автоматически обнаруживает синтаксические и другие ошибки в тексте и позволяет их исправить;
- программы-трансляторы, которые автоматизируют процесс создания объектных модулей, т.е. процесс перевода (трансляции) программных текстов на алгоритмическом языке в объектные коды, – понятные микрокомпьютеру двоичные слова-команды;
- программы-эмуляторы, которые полностью имитируют работу микрокомпьютера и, таким образом, позволяют имитировать функционирование программных модулей в нем; лучшие эмуляторы могут имитировать также работу соединенных с микрокомпьютером источников информации и исполнительных узлов в приближенном к реальности масштабе времени;
- программы отладки программных модулей, которые позволяют проверять выполнение отдельных команд или указанных последовательностей команд, подсчитывать число использованных на это машинных тактов, имитировать прерывания или поступление некорректных данных, разветвления по условию и т.п.
Отладку программы работы сенсора осуществляют в несколько этапов:
- автономная отладка каждого отдельного программного модуля в статическом режиме, т.е. без учета временного хода последовательности команд;
- определение времени работы критических программных модулей (в первую очередь, модулей обработки прерываний) при самых сложных условиях и, если необходимо, коррекция программ, чтобы обеспечить требования относительно времени их работы;
- комплексная отладка всей программы в статическом режиме;
- комплексная отладка всей программы в динамическом режиме, т.е. с учетом фактора времени.
На этапе отладки очень пригодятся контрольные примеры, подобранные при алгоритмизации программных модулей. И с учетом результатов отладки их надо скорректировать и подобрать новые, чтобы получить "заготовку" для будущих контрольных испытаний программы.
Окончательную отладку и доработку программы делают уже по результатам предварительных испытаний действующего образца интеллектуального сенсора.