bevice писал(а):Можно штаны через голову надевать
С точки зрения большинства любителей именно так вы и поступаете.
Не путайте любительские проекты (которые на гит мало кто выкладывает, т. к. обычно пишут только для себя) и промышленного масштаба.
Вот объясните зачем любителю билд-сервер и другое перечисленное вами?
А зачем новичкам разбираться с ARM? Зачем писать программы для микроконтроллеров? Никто же не заставляет, и точно не требует.
Вы почему-то искренне считаете, что все новички клинические идиоты, что не могут разобраться с десятком ключей компиляции и пятью командами git. Ну если приучать с детства кликать галочки в кейле и копипастить код из примеров аки народстрим, то ничего хорошего не выйдет.
У ТС был вполне конкретный вопрос -
как должна быть составлена команда на компиляцию
вы сходу предложили забить на это и использовать IDE. Так зачем с такими советами сюда писать? Ходите с ними в тему, где спрашивают какую IDE выбрать для GCC, а если ответить на вопрос не можете и вам оно не интересно - так пролистайте мимо, не нужно новичкам навязывать то, что навязали вам.
BOND12, да, чтобы не голословить, вам и тут отвечу, жаль что из-за праздников возможно опоздал поучаствовать в этом цирке.
Ну, основной вопрос составляет то, как заставить компилятор вырабатывать объектные файлы под вариант архитектуры arm cortex m3, на которой построены данные микроконтроллеры. Сама компиляция осуществляется, если я ничего не напутал, командой arm-none-eabi-gcc.
Да, в целом это так, но не совсем. Я опущу тут и префикс arm-none-eabi-, чтобы меньше писанины было. Компиляция на языке C/C++ всегда состоит из трёх этапов:
1. Препроцессинг
2. Компиляция
3. Линковка.
Препроцессинг - это раскрытие макросов, #define #include и тому подобных. Никакой код при этом не компилируется, ничего не анализируется, просто, например вместо #include "header.h" вставляется (прямо как есть) файл header.h, а работы с макросами #define очень похожа на операцию "Найти и заменить" в блокноте или любом другом простейшем текстовом редакторе.
Компиляция - это преобразование всего исходного кода в машинные инструкции, но на данном этапе никакой работы с адресами не происходит. Вместо адресов переменных используются их имена, равно как вместо переходов и вызовов функций. Каждый файл компилируется отдельно, поэтому очень важно чтобы в каждый файл был включен заголовок с описанием всех используемых внешних функций и переменных. Поскольку компиляция происходит пофайлово - могут применяться разные языки программирования. gcc - это компилятор C, g++ для языка C++, as - для ассемблера. На выходе из компилятора всегда будет объектный файл.
Линковка - это сборка из скомпилированных (объектных) файлов готовой программы. Именно на этом этапе происходит связывание, раскладывание по адресам, выкидывание не нужного. Для работы линковщику передаются объектные файлы и правила построения исполняемого файла. Эти правила обычно называются скриптом линковки. Там указывается сколько памяти у контроллера и её адреса, куда положить код, куда данные. Ничего сложного, но почему-то у большинства вызывает полнейший ступор. А уж с нуля написать могут полтора человека.
На выходе после линковки получится исполняемый файл в формате ELF, там кроме самой прошивки еще куча-куча всего лежит, даже исходные тексты могут быть, при желании. Этот исполняемый файл можно передать в отладчик (GDB) и он может запустить-остановить-прошагать программу на микроконтроллере. А вот для того чтобы получить hex или bin файл еще потребуется воспользоваться командой objcopy которая из ELF может вытащить только то, что требуется микроконтроллеру.
Поэтому для сборки прошивки потребуется как минимум исходник на каком-то языке программирования (C/C++/ASM) и скрипт линковки. Поскольку никакой операционной системы на микроконтроллерах нет, еще потребуется кое-какая инициализация, для кода C это немного поработать с предварительно инициализированными переменными. Обычно это делается в startup-файле. Который обычно же пишется на ассемблере, и в нем тоже никто ничего не понимает (даже ST, да в кубе долгое время был косяк с двойным вызовом SystemInit()) - короче этот файлик многими считается обязательным и кочует из проекта в проект из форума в форум. При загрузке микроконтроллер выполняет код, который прописан в этом startup-файле и в конце переходит в функцию main() которую уже и пишет программист. Переходит не сам по себе, а в соответствии с инструкцией в стартапе.
Далее, для упрощения жизни gcc после компиляции по-умолчанию вызывает линковщик, для того чтобы он этого не делал есть специальный ключ. Но вы его не указали, поэтому линковщик был вызван без скрипта линковки. Он ничего не знал про ваш контроллер, про память, про стек итп. Поэтому споткнулся о первую операцию выделения стека. Это первая ошибка.
Вторая -
Please select first the target STM32F10x device
- заголовки CMSIS требуют опередения семейства процессора, например STM32F103xB. Проще всего это сделать через ключ компиляции -D (gcc -DSTM32F103xB ...)
Ну и последняя ошибка. startup_stm32f10x_cl.s - это файл на ассемблере, а вы его скармливали компилятору языка C на что он ругался.
В общем и упрощенном виде компиляция будет выглядеть примерно так:
- Код:
arm-none-eabi-gcc -c -g -Wall -mcpu=cortex-m3 -mthumb -o main.o main.c
arm-none-eabi-ld -g -Tscript.ld -o main.elf main.o
arm-none-eabi-objcopy -Obinary main.elf main.bin
ключи компиляции gcc:
-с - не вызывать линковщик, только компилировать
-g - добавить отладочную информацию
-Wall - включить все предупреждения
-mcpu=cortex-m3 -mthumb - компилировать для процессора cortex-m3 и использовать набор инструкций thumb
-o main.o - выходной файл называть main.o
main.c - компилировать файл main.c
Линковка (ld):
-g - то же самое, добавить отладочную информацию
-Tscript.ld - использовать правила линковки в файле script.ld
-o main.elf - записать полученное в файл main.elf
main.o - (тут используется один, но должны быть все необходимые ранее откомпилированные файлы) - объектные файлы программы, которую нужно компоновать.
objcopy, тут все просто
-Obinary - формат бинарный
main.elf - на вход
main.bin - выход.
Для того, чтобы не писать каждый раз руками все эти команды - придумали сборщики, вроде make.
Про скрипты линковки уже подробно писал, ссылка выше. Если плохо разобрано - спрашивайте, попробую изложить понятнее.