STM32F030. Прокачиваем make-файл

Вторая версия make-файла с точки зрения идеологии — правильная. Но тем не менее, все еще далека от совершенства. И сейчас мы еще немного продвинемся в этом направлении.

Начнем с наименования цели проекта.

Любой проект всегда имеет какое-то уникальное имя, которое отличает его от других проектов. Обычно имя проекта совпадает с именем конечного файла.

В английском языке есть слово target, которое обозначает цель, мишень, конечную точку, которую нужно достичь.

Давайте создадим в нашем make-файле переменную с этим именем и присвоим ей значение — имя нашего проекта. Это лучше сделать в первой строчке make-файла:

TARGET=blinky

Теперь мы можем использовать эту переменную на протяжении всего файла. И во всех его местах, где раньше мы писали слово blinky, теперь мы размещаем эту переменную.

Например, было:

# Извлекаем двоичный кода для прошивки
blinky.bin: blinky.elf
	arm-none-eabi-objcopy -Obinary blinky.elf blinky.bin

стало:

# Извлекаем двоичный кода для прошивки
$(TARGET).bin: $(TARGET).elf
	arm-none-eabi-objcopy -Obinary $(TARGET).elf $(TARGET).bin

Теперь, если по каким-либо причинам, мы будем вынуждены переименовать проект (ну, допустим, клонировали его как основу для другого проекта), то нам нужно изменить имя только в одном месте.

Только не переусердствуйте! Изменять нужно только только имя проекта, но не имя исходного и объектного файлов. В нашем проекте имя проекта и имя исходного (и объектного) файла совпадают.

Вообще в переменные такого рода удобно выносить часто-повторяющиеся элементы. Например, очень часто создается переменная PREFIX:

PREFIX=arm-none-eabi-

и на основе этой переменной потом создаются имена утилит из binutils:

CC=$(PREFIX)gcc
AS=$(PREFIX)as
LD=$(PREFIX)ld
OD=$(PREFIX)objdump
OC=$(PREFIX)objcopy
SZ=$(PREFIX)size

Тогда, в том месте, где мы раньше писали

blinky.elf: start-up.o blinky.o
	arm-none-eabi-ld --gc-sections -Map blinky.map -T linked.ld -o blinky.elf start-up.o blinky.o
	# Узнаем чего и сколько мы наплодили
	arm-none-eabi-size blinky.elf

start-up.o: start-up.S
	arm-none-eabi-as -mcpu=cortex-m0 -o start-up.o start-up.S

теперь мы можем писать более лаконично:

$(TARGET).elf: start-up.o blinky.o
	$(LD) --gc-sections -Map $(TARGET).map -T linked.ld -o $(TARGET).elf start-up.o blinky.o
	# Узнаем чего и сколько мы наплодили
	$(SZ) $(TARGET).elf

start-up.o: start-up.S
	$(AS) -mcpu=cortex-m0 -o start-up.o start-up.S

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

CFLAGS   = -c
CFLAGS  += -Wall -fno-common -Os
CFLAGS  += -mcpu=cortex-m0 -mthumb
ASFLAGS  = -mcpu=cortex-m0
LDFLAGS  = --gc-sections -T linked.ld
LDFLAGS += -Map $(TARGET).map

Как вы видите, переменные допускают даже конкатенацию (добавление). Если, напрмер, нам по какой-то причине не ненужно будет получать карту памяти, то последнюю строку мы можем спокойно закомментировать.

...
LDFLAGS = --gc-sections -T linked.ld
#LDFLAGS += "-Map $(TARGET).map"

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

Таким образом, некоторые цели нашего make-файла начинают приобретать вид:

$(TARGET).elf: start-up.o blinky.o
	$(LD) $(LDFLAGS) -o $(TARGET).elf start-up.o blinky.o
	# Узнаем чего и сколько мы наплодили
	$(SZ) $(TARGET).elf

start-up.o: start-up.S
	$(AS) $(ASFLAGS) -o start-up.o start-up.S

Я думаю, вы уже уловили суть переменных.

Если вы уже начали играться — создавать проект, а потом очищать его, то наверняка заметили «ругань» от команды clean:

dirty-make-clean

Собственно, нам ни к чему знать, что в нашем директории нет тех файлов, которые мы и так собирались удалить.

Давайте стандартный поток ошибок у команды rm сольем в «канализацию» (2>/dev/null)

clean:
	rm *.o *.elf *.map *.bin *.hex *~ 2>/dev/null

Теперь экран стал меньше замусориваться не нужными сообщениями. Однако, нам все еще есть куда улучшать наш make-файл.

Символ ‘@’ помещенный перед командой заставляет утилиту make не выводить эту команду на консоль.

clean:
	@rm *.o *.elf *.map *.bin *.hex *~ 2>/dev/null

Теперь шум от этой команды снизился до одной строки.

Однако, идем дальше! Теоретически make-файл может запускаться не в ручном режиме, путем набора команд в консоли, а участвовать в каком-нибудь скриптовом файле, который может проверять наличие ошибок при выполнении той или иной его (make-файла) команды.

Утилита make предоставляет нам еще один символ для управления. Символ ‘-‘ (дефис, черточка) перед командой говорит утилите make игнорировать любые ошибки, возникающие в процессе работы этой команды.

clean:
	-@rm *.o *.elf *.map *.bin *.hex *~ 2>/dev/null

Теперь выполнение make clean всегда будет возвращать положительный результат — «ошибок нет».

Только не думайте, что это работает только с командой rm. Управляющие символы (-, @) и перенаправление потоков работают с любой командой. Не бойтесь экспериментировать! Это вам не Виндовс, здесь возможности ограничены только вашей фантазией. Отпустите ее на волю, пусть порезвиться!

Что еще можно сотворить с make-файлом?

Можно добавить свой вывод комментариев при выполнении той или иной команды. Я даже иногда добавляю в свои make-файлы подсветку вывода своих комментариев:

# Чтобы убрать подсветку вывода, закомментируйте эти строки
COLORIZE  = "\033[01;38;05;192m"
BACKCOLOR = "\033[0;0;0m"

...

clean:
	@echo $(COLORIZE)"Сейчас наша старательная тетя-Маша поработает на благо директория..."$(BACKCOLOR)
	-@rm *.o *.elf *.map *.bin *.hex *~ 2>/dev/null
	@echo $(COLORIZE)"Мдя... поработала :("$(BACKCOLOR)

Что еще можно улучшить?

Мы видим, что ассемблирование файлов start-up.S и blinky.S очень сильно совпадает. Разнятся команды только по именам файлов.

start-up.o: start-up.S
	@$(AS) $(ASFLAGS) -o start-up.o start-up.S

blinky.o: blinky.S
	@$(AS) $(ASFLAGS) -o blinky.o blinky.S

Можно объединить эти две команды ассемблирования в одну шаблонную.

Символы %.o и %.S — шаблоны для целевого и зависимого файлов. Символы $* заменяют имя без суффикса исходного файла, а символы $< заменяют имя с суффиксом исходного файла в команде.

Для того чтобы получить имя с суффиксом для объектного файла мы используем шаблон имени без суффикса, и к нему дописываем уже другой суффикс — $*.o.

%.o: %.S
	@$(AS) $(ASFLAGS) -o $*.o $<

Но мне кажется, что в данном (в нашем) случае это уже перебор.

И хотя возможности make-файлов все еще не все рассмотеры, я все же предлагаю остановится на этом. Мы уже многое поняли, но нам нужно развивать не только в этом направление. Нам еще нужно разобраться с именами регистров и битов у STM32. Давайте-ка будем двигаться в ту сторону.

В заключение я приведу конечный вид нашего make-файла:

# Третья версия make-файла.
# Идеологически она верная.

TARGET=blinky

PREFIX=arm-none-eabi-

# Инструментарий
AS=$(PREFIX)as
LD=$(PREFIX)ld
OD=$(PREFIX)objdump
OC=$(PREFIX)objcopy
SZ=$(PREFIX)size

LOADER=stm32flash

# Флагистика
ASFLAGS  = -mcpu=cortex-m0
LDFLAGS  = --gc-sections -T linked.ld
LDFLAGS += -Map $(TARGET).map

# Фантомные (мнимые) цели
.PHONY: all load clean

# Укажем, что будем делать по умолчанию
all: $(TARGET).elf

# Чтобы убрать подсветку вывода, закомментируйте эти строки
COLORIZE  = "\033[01;38;05;192m"
BACKCOLOR = "\033[0;0;0m"

# Заливаем код в микроконтроллер
load: $(TARGET).bin
	@echo $(COLORIZE)"Заливаем код"$(BACKCOLOR)
	$(LOADER) -o /dev/ttyS0
	$(LOADER) -c -w $(TARGET).bin -g 0x0 /dev/ttyS0

# Извлекаем двоичный код для заливки в микроконтроллер
$(TARGET).bin: $(TARGET).elf
	@$(OC) -Obinary $(TARGET).elf $(TARGET).bin

# Линковка (сборка объектных файлов в один elf-файл)
# Заодно создаем файл карты памяти и посмотрим чего и сколько мы наплодили
$(TARGET).elf: start-up.o blinky.o
	@$(LD) $(LDFLAGS) -o $(TARGET).elf start-up.o blinky.o
	@echo $(COLORIZE)"Результат сборки:"$(BACKCOLOR)
	$(SZ) $(TARGET).elf

# Компиляция (ассемблирование) исходных кодов
# На выходе получаем объектные файлы *.o
%.o: %.S
	@$(AS) $(ASFLAGS) -o $*.o $<

######## Предыдущий способ ассемблировать ########
#start-up.o: start-up.S
#	@$(AS) $(ASFLAGS) -o start-up.o start-up.S
#
#blinky.o: blinky.S
#	@$(AS) $(ASFLAGS) -o blinky.o blinky.S #################################################
clean:
 	@echo $(COLORIZE)"Сейчас наша старательная тетя-Маша поработает своей шваброй на благо директория..."$(BACKCOLOR)
 	-@rm *.o *.elf *.map *.bin *.hex *~ 2>/dev/null
	@echo $(COLORIZE)"Хоп! И чисто"$(BACKCOLOR)

Реклама

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s