Обработка прерываний при использовании CMake для сборки прошивки STM32

Я отлаживаю проект STM32, созданный с помощью CMake. Он использует библиотеку HAL, и в начале я настраиваю HAL и SysTick.

root/
├─ core/
│  ├─ core.c
│  ├─ core.h
│  ├─ stm32g4xx_it.c
│  ├─ stm32g4xx_it.h
│  ├─ CMakeLists
├─ main.c
├─ startup.s
├─ CMakeLists.txt

startup.s содержит слабый SysTick_Handler, а именно:

.weak   SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler

stm32g4xx_it.c также содержит SysTick_Handler, который переопределяет слабое объявление. Проблема в том, что при компиляции, компоновке и загрузке приложения, как показано выше, прерывание SysTick заканчивается на Default_Handler. Если я удаляю слабое объявление из файла startup.s, то он работает правильно и выполняется правильная функция обработчика. Я думаю, что это результат того, как работает cmake. В корневом каталоге находится основной файл CMakeLists.txt, который компилирует файлы startup.s и main.c, а затем связывает основную библиотеку. Правильный SysTick handler помещается в основную библиотеку, поэтому компиляция файла startup.s не видит другую реализацию этой функции-обработчика. Каков правильный, но элегантный подход к ее решению?

Другой вопрос, который приходит мне на ум, заключается в том, как мне написать код для других обработчиков прерываний и как связать их в системе сборки CMake? Допустим, у меня есть модуль UART, и этот модуль имеет свои собственные обработчики прерываний. Должен ли я создать отдельную библиотеку на основе файла startup.s и связать с ней все остальные модули, имеющие обработчики прерываний? Я думал, что CMake должен сделать сборку более прозрачной, читабельной и простой, но в этом случае это больше похоже на спагетти. Наверное, я что-то упускаю...


РЕДАКТИРОВАТЬ 14.04.2021

Я узнал, что проблема связана только с файлом запуска asm. Например, я могу создать символ слабой функции в main.c, например:

__attribute__((weak)) void SystemInit(void)

В основной библиотеке в core.c я создаю функцию:

void SystemInit(void)

затем после компиляции и компоновки используется правильная функция из core.c. Итак, похоже, что здесь есть что-то, строго связанное с ассемблерным файлом.


person VIPPER    schedule 11.04.2021    source источник
comment
Я бы предположил, что, возможно, stm32g4xx_it зависит от приложения и не принадлежит библиотеке. Копия stm32g4xx_it.o из библиотеки вообще включена в сборку? С другой стороны, startup.o не меняется от приложения к приложению, и может иметь смысл находиться в библиотеке.   -  person Tom V    schedule 11.04.2021
comment
Похоже, я столкнулся с той же проблемой, что описана здесь: jonathanhamberg.com/post/gcc -archive-linker-странность. Я думаю, что другим возможным решением было бы использование библиотек OBJECT, как описано здесь: scivision.dev /cmake-object-libraries. Однако в моем случае есть одна небольшая проблема. Моя библиотека HAL создана с множеством небольших библиотек на основе одного файла, как это предлагается в github.com/ObKo. /stm32-cmake. Все эти библиотеки HAL имеют один и тот же общий файл HAL в зависимости, что означает, что будет создано несколько объектов одного и того же файла... и это вызывает другую проблему.   -  person VIPPER    schedule 12.04.2021
comment
Решение с дополнительной библиотекой запуска не работает   -  person VIPPER    schedule 12.04.2021


Ответы (1)


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

Нет необходимости использовать библиотеки во встраиваемых проектах для микроконтроллеров. Я обнаружил, что это причиняет больше боли. Некоторые разработчики не используют библиотеки add_library() в своих CMakeLists.txt. Я не нахожу это очень разумным при использовании CMake. Он используется для лучшей организации файлов проекта и управления зависимостями между модулями.

Проблема здесь может быть просто решена с использованием OBJECT библиотек. Этот тип ссылки был добавлен в target_link_libraries в версии 3.12. Я думаю, что он был добавлен специально для проектов микроконтроллеров, и он действительно отлично работает.

person VIPPER    schedule 18.04.2021