IAR: как переопределить и перенаправить библиотечные модули без пересборки всей библиотеки Печать
Добавил(а) microsin   

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

Решение в лоб - пересобрать библиотеку с небольшими внесенными изменениями. Однако пересборка библиотеки - процесс сложный. Если рассматривать стандартную библиотеку C/C++, то этого гораздо сложнее из-за доступных вариантов предварительной сборки с различными форматерами, декскрипторами файлов, интерфейсами низкого уровня и поддержки многобайтных значений и плавающей точки float/double.

[Переопределение и перенаправление]

Линкер в IAR Embedded Workbench дает возможность переопределить модули или подпрограммы/функции без необходимости пересборки библиотеки целиком. Концепция реально проста, поскольку линкер дает более высокий приоритет для Ваших собственных модулей над библиотечными. Т. е. если Вы создали точно такую же функцию в своем модуле, как и в библиотеке, то линкер берет Вашу функцию вместо библиотечной.

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

Линкер автоматически загружает только те модули библиотеки, пользовательские библиотеки и стандартные варианты библиотек C или C, которые фактически необходимы приложению. Линкер в IAR Embedded Workbench может генерировать MAP-файл со всеми символами, используемыми в окончательном исполняемом файле. Эта опция доступна в разделе Linker свойств проекта. MAP-файл упрощает определение модулей, которые необходимо настроить. Это также помогает выяснить библиотеку, к которой относится модуль:

IAR overriding and redirecting fig1

Например, если мы хотим переопределить функцию __write, чтобы перенаправить вывод printf из Terminal I/O по умолчанию в UART или даже на LCD, то Вы сможете найти через MAP-файл, что функция __write является частью модуля write.o:

IAR overriding and redirecting fig2

Если известно имя модуля, то можно легко найти его исходный код для стандартной библиотеки C или C++ в каталоге arm\src\lib директории установки IDE IAR:

IAR overriding and redirecting fig3

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

Другое решение заключается в создании функции на основе её прототипа:

__ATTRIBUTES size_t __write(int, const unsigned char *, size_t);

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

[Замена вызова функции]

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

Напримем, если нужно перенаправить __write в Вашу функцию __write_own (которая делает что-то подобное, что и __write, но по-другому), то в командной строке нужно указать --redirect __write=__write_own. Опцию перенаправления нужно добавить ко дополнительным опциям линкера в свойствах проекта (раздел Linker -> закладка Extra Options). После сборки проекта мы увидим, что функция __write_own теперь вызывается вместо оригинальной функции __write.

IAR overriding and redirecting fig4

Здесь приведен пример изменения поведения стандартной библиотеки ввода/вывода, однако концепция переопределения и перенаправления модулей без пересборки библиотеки также может использоваться и со сторонними библиотеками. Это простой и прямой способ добавления/изменения функционала системы без пересборки библиотеки, которая была протестирована на протяжении многих лет, или когда библиотека была предоставлена в виде готового продукта другим разработчиком (возможно без исходного кода).

[Ссылки]

1. How to override and redirect library modules without rebuilding the entire library site:iar.com.