Целью использования кросс-инструментов является создание на инструментальной машине файла с двоичным образом (firmware) начального содержимого памяти (как машинные команды, так и данные) для целевой аппаратной системы. Такой файл затем используется для загрузки в конкретные целевые устройства.
В качестве языков программирования встраиваемых систем выступают обычно C (а также его расширенные подмножества типа Embedded C [14]) и ассемблер. Ассемблер используется как в виде вставок в код на языке С, так и в виде отдельных ассемблерных модулей. В случае встраиваемых систем программирование на ассемблере остается важной составляющей создания программ ввиду, как правило, жестких требований к высокой производительности и малому объему программного кода.
На рис. 2 представлена типовая схема разработки программ с помощью кросс-инструментария.
Обычно процесс взаимодействия программиста с кросс-инструментами происходит через визуальную интегрированную среду разработки (IDE) со встроенным редактором, механизмами поддержки проектов, различными средствами управления и анализа результатов работы отдельных инструментов.
Рис. 2. Разработка программ с помощью кросс-инструментов.
Реальные программы обычно состоят из нескольких модулей, каждому из которых соответствует файл с исходными текстами программ (на языках высокого уровня или ассемблера). Компилятор транслирует модули на языке высокого уровня в промежуточные ассемблерные модули. Ассемблер
отвечает за преобразование ассемблерных модулей (как написанных вручную, так и сгенерированных компилятором) в объектные модули с машинными кодами и данными для целевой аппаратуры. В качестве формата объектных модулей обычно используется ELF [15-16], включающий в себя различные секции (например, секции исполняемого кода, секции данных, секции с информацией о символах и секции с отладочной информацией). Компоновщик выполняет сборку нескольких объектных модулей в один абсолютный модуль с объединением соответствующих секций входных объектных файлов.
При этом выполняются перемещения символов по абсолютным адресам памяти (автоматически или в соответствии с заданной программистом картой памяти) с соответствующими исправлениями зависящих от них кодов команд и значений данных. На этом заканчивается этап сборки программы. Полученный абсолютный модуль можно преобразовать в образ памяти для непосредственной загрузки в целевую аппаратуру с помощью программатора.
Для программиста взаимодействие с исполняемой моделью аппаратуры осуществляется через отладчик, который позволяет просматривать состояние модели (содержимое памяти, регистров, шин, сигналов) и осуществлять управляемое (в том числе, пошаговое) выполнение целевой программы на уровне отдельных команд или строчек исходного кода. Совместно с отладчиком используются различные виды профилировщиков
и средств анализа, визуализирующих необходимые характеристики модели (как статические, так и времени исполнения) и соответствующие статистики. В качестве примеров можно привести: