Keil C51. Использование внешних трансляторов исходных файлов при сборке проекта

Александр Бельченко
13 ноября 2004
В статье пойдет речь об одной редко используемой, но тем не менее очень мощной возможности. А именно — возможности использовать внешние трансляторы для некоторых исходных файлов вашего проекта. В статье рассказывается как подключить и настроить внешние трансляторы на примере утилиты pyLCDstring.

Постановка задачи

Наша задача — научиться использовать некоторые внешние трансляторы исходных текстов в общем процессе компиляции-сборки проекта при работе в интегрированной среде Keil µVision2. В качестве примера возьмем утилиту pyLCDstring, которая является транслятором текстовых файлов с набором строковых переменных. В нашем примере эта утилита будет использоваться для того, чтобы производить автоматическую замену двух русских букв «э» и «я» на их восьмеричные эквиваленты (см. FAQ — вопрос про глюки с русскими буквами).

Нашим исходным примером будет стандартный проект «Hello», который вы наверняка хоть раз видели после первой установки пакета Keil — при первом запуске интегрированной среды этот проект открывается автоматически. Этот учебный проект располагается в каталоге с примерами Keil в подкаталоге

{BaseKeil}\C51\Examples\Hello

Модифицированный проект hello1

Для удобства рассмотрения и последующей модификации я несколько изменил набор исходных файлов проекта и их содержимое. Вы можете скачать проект hello1.

Изменения в проекте относительно стандартного примера:

  • Добавлены еще две строковые переменные (в дополнение к «Hello World\n»):
    • строка «Здравствуйте, я Ваша тётя!\n»
    • строка «Введите коэффициенты:\n»
  • Все строковые переменные выделены в отдельный файл messages.c
  • В вечный цикл добавлен последовательный вывод на терминал всех трех строковых переменных

Добавленные строки на русском языке выбраны таким образом, чтобы они содержали буквы «э» и «я».

Для файла messages.c установлена опция трансляции в ассемблерный SRC-файл, а затем последующая компиляция. В общем случае в этом нет необходимости, но так будет удобнее отслеживать, что же происходит с русскими буквами и где они теряются.

Компиляция проекта

При компиляци проекта файл messages.c транслируется сначала в ассемблерный файл messages.src, а затем собственно компилируется. Если посмотреть на ассемблерный код messages.src, то можно заметить, что русская буква «э» (шестнадцатеричный код 0xFD) в слове «коэффициенты» бесследно пропала. Хотя буква «я» у меня осталась (шестнадцатеричный код 0xFF), но на вашем компьютере она тоже может пропасть.

Собираем проект и запускаем отладку в симуляторе. Открыв окно последовательного терминала (Serial Window #1) и запустив программу на выполнение на полной скорости, можно увидеть, что буква «э» действительно исчезла из третьей строки.

Если остановить симуляцию программы, то буква «я» пропадает в окне терминала. Еще один глюк.

Подключаем pyLCDstring

Утилита pyLCDstring предназначена для перекодировки строк с русскими буквами из одной кодировки в другую. Задействуем ее для автоматической замены двух русских букв «э» и «я» на их восьмеричные эквиваленты (\375 и \377 соответственно).

Для этого нужно несколько скорректировать наш проект hello1 — вы можете скачать проект hello2. Утилита pyLCDstring автоматически строит исходный код на языке Си и соответствующий ему заголовочный файл на основе исходного файла с набором объявлений строк. Поэтому нам нужно подготовить и подключить в проект этот самый исходный файл. Назовем его messages.lcd.

Исходный файл messages.lcd

Содержимое этого файла достаточно простое — он содержит несколько деклараций, необходимых для работы самой утилиты, а также набор строк:

//// Coding = keil
//// Declaration = char code

msg_hello = "Hello World\n"

msg_aunt = "Здравствуйте, я Ваша тётя!\n"

msg_coef = "Введите коэффициенты:\n"

В первых двух строках содержатся декларации для pyLCDstring: первая из них указывает, что для перекодировки необходимо использовать словарь перекодировки keil, а вторая указывает, что тип строк в объявлениях си-переменных должен быть

char code variable[] = ...

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

Настройка опций для файла messages.lcd

После того как файл messages.lcd будет подключен в проект, его необходимо настроить на использование внешних утилит-трансляторов. Для этого откройте опции этого файла:

В выпадающем списке File Type обязательно должно быть выбрано «Custom file». Команда для запуска трансляции задается в окне редактирования Custom arguments. В приведенном примере предполагается, что у вас утилита pyLCDstring установлена в каталог:

C:\utils\pylcdstr

Как видно, в командной строке необходимо указывать имя файла, который будет обрабатываться внешним транслятором. Также можно заметить, что я указал ключ --smart, который заставляет утилиту pyLCDstring сравнивать дату модификации исходного файла и генерируемых файлов: messages.c и messages.h. Трансляция файла messages.lcd будет производиться только тогда, когда он новее, чем сгенерированные им c- и h- файлы.

Файл messages.c должен быть подключен в проект как обычный си-файл. Поскольку при сборке проекта файлы компилируются в том порядке, в котором они присутствуют в окне проекта keil, то разместите файл messages.lcd в дереве проекта выше файла messages.c, для обеспечения корректной работы.

Компиляция проекта

В ходе компиляции и сборки проекта будет запущена трансляция файла messages.lcd при помощи указанной нами команды (вызов утилиты pyLCDstring). В результате трансляции получаются два файла: messages.c и messages.h. Следующим этапом кейл откомпилирует файл messages.c и будет использовать полученный объектный модуль messages.obj при компоновке выходного файла.

Таким образом трансляция исходного файла messages.lcd в объектный модуль messages.obj происходит в два этапа:

  1. messages.lcd -> messages.c (при помощи pyLCDstring)
  2. messages.c -> messages.obj (при помощи компилятора C51)

Собрав проект и запустив его симуляцию, убеждаемся, что теперь-то все русские буквы остаются на своих местах:

Методика использования

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

При включении таких исходных файлов необходимо указать их тип файла (File Type) как «Custom file» (в опциях файла). Командная строка для запуска трансляции указывается в опциях файла в поле Custom arguments. Заметьте, что указывать надо полную строку запуска, кейл не производит автоматической подстановки имени файла в эту командную строку.

Там же в опциях файла можно указать условие прерывание хода сборки проекта — см. выпадающий список Stop on Exit Code. Указав код, возвращаемый внешним транслятором в случае неудачной обработки, можно прерывать ход сборки проекта. Так, например, утилита pyLCDstring возвращает код 1, если при обработке файла встретились некоторые предупреждения (чаще всего это не фатальные ошибки, си-файл будет сгененерирован, но вам лучше убедиться, что все нормально); в случае фатальных ошибок (как невозможность открыть исходный файл для обработки) утилита возвращает код 2; когда все нормально — возвращается код 0.

Варианты выбора в списке Stop on Exit Code:

  • Never — (никогда) возвращаемый код не анализируется;
  • Translator Warnings (Exit Code >= 1) — при кодах >= 1 (предупреждения и ошибки);
  • Translator Errors (Exit Code >= 2) — при кодах >= 2 (ошибки);
  • Translator Fatal Errors (Exit Code >= 3) — при кодах >= 3 (фатальные ошибки);
  • Custom Exit Code >= 4 ... >= 10 — при кодах больших или равных 4...10
  • Not specified — не указан.
При использовании утилиты pyLCDstring целесообразно устанавливать останов при возникновении предупреждений (Translator Warnings Exit Code >= 1). Сообщения-предупреждения будут выведены в окне Output Window. Двойным щелчком по тексту предупреждения можно перейти на ту строку исходного файла, в которой возникло это предупреждение.

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

Источники

  • Документ «Getting Started with µVision2» («Начинаем работу с µVision2») — gs51.pdf. Глава 4, раздел «Tips and Tricks», параграф «Using a Custom Translator».

Файлы с примерами

Ссылки