Расширение .s - это соглашение, используемое GNU и многими другими цепями инструментов для файлов ассемблера.
В последний раз я посмотрел, что стандартная периферийная библиотека STM32 не содержит файлов ассемблера, однако библиотека CMSIS содержит код запуска для различных компонентов STM32, например, startup_stm32f2xx.s - это код запуска для всех устройств серии STM32F2xx. Существуют разные реализации для разных цепочек инструментов; вам нужно создать и связать файл, связанный с вашей конкретной деталью и цепочкой инструментов. Если вы используете пример проекта, который создает и запускает, или IDE, которая создает проекты для конкретных деталей, это, вероятно, уже будет выполнено - если у вас есть код, который запускает, он, безусловно, имеет.
Способ построения и связывания кода будет зависеть от того, какую цепочку инструментов вы используете. Большинство инструментов на основе IDE автоматически распознают расширение и вызывают ассемблер для создания объектного файла, который будет связан как любой другой. Точное содержимое немного отличается в разных версиях цепочки инструментов, но в первую очередь создает среду выполнения C (стек и куча), инициализирует процессор, определяет исходную таблицу векторов прерываний / исключений, инициализирует статические данные и переходит к main ().
Ядро файла для версии Keil / ARM RealView, например, выглядит следующим образом:
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
Reset_Handler
- адрес регистра счетчика программ (ПК), который будет установлен после сброса процессора.
SystemInit
- это внешняя функция кода C, которая выполняет основную часть инициализации - для этого может потребоваться настройка вашего оборудования. Cortex-M необычен тем, что может запускать код C сразу после сброса, поскольку таблица векторов включает в себя как адрес сброса, так и начальный адрес указателя стека, который автоматически загружается в регистр SP при сбросе. В результате вам не нужно много знаний ассемблера, чтобы запустить его.
__main()
- это точка входа, поставляемая компилятором для вашего кода C. Это не функция main (), которую вы пишете, но она выполняет инициализацию для стандартной библиотеки, статических данных, кучи перед вызовом вашей функции main ().
Версия GCC несколько сложнее, поскольку выполняет большую часть работы, выполняемой __main()
в версии Keil / ARM RealView, но по сути выполняет ту же функцию.
Обратите внимание, что в CMSIS SystemInit()
определяется в system_stm32f2xx.c и может нуждаться в настройке для вашей платы (правильная частота кристалла, настройка PLL, внешняя конфигурация SRAM и т. Д.). Поскольку это код на Си и он хорошо прокомментирован, вам, вероятно, будет удобнее с ним работать.