Еще один шаблон проекта под STM32 на gcc

Наиболее интересный момент
# Компиляция
#-------------------------------------------------------------------------------
%.o: %.c
@$(CC) $(CFLAGS) -MD -c $< -o [email protected]
# Сгенерированные gcc зависимости
#-------------------------------------------------------------------------------
include $(wildcart *.d)
Ключ -MD заставляет генерировать gcc файлы зависимостей. Подсмотрел здесь.
Архив с проектом в аттаче.
Собственно Makefile
# Имя проекта
#-------------------------------------------------------------------------------
TARGET = template
# Используемые модули библиотеки периферии
#-------------------------------------------------------------------------------
# PERIPHDRIVERS += stm32f10x_adc
# PERIPHDRIVERS += stm32f10x_bkp
# PERIPHDRIVERS += stm32f10x_can
# PERIPHDRIVERS += stm32f10x_cec
# PERIPHDRIVERS += stm32f10x_crc
# PERIPHDRIVERS += stm32f10x_dbgmcu
# PERIPHDRIVERS += stm32f10x_exti
# PERIPHDRIVERS += stm32f10x_flash
# PERIPHDRIVERS += stm32f10x_fsmc
PERIPHDRIVERS += stm32f10x_gpio
# PERIPHDRIVERS += stm32f10x_i2c
# PERIPHDRIVERS += stm32f10x_iwdg
# PERIPHDRIVERS += stm32f10x_pwr
PERIPHDRIVERS += stm32f10x_rcc
# PERIPHDRIVERS += stm32f10x_rtc
# PERIPHDRIVERS += stm32f10x_sdio
# PERIPHDRIVERS += stm32f10x_spi
# PERIPHDRIVERS += stm32f10x_tim
# PERIPHDRIVERS += stm32f10x_usart
# PERIPHDRIVERS += stm32f10x_wwdg
# PERIPHDRIVERS += misc.c
# Дефайны
#-------------------------------------------------------------------------------
DEFINES += USE_STDPERIPH_DRIVER
DEFINES += STM32F10X_MD_VL
DEFINES += GCC_ARMCM3
DEFINES += VECT_TAB_FLASH
# Инструменты
#-------------------------------------------------------------------------------
AS = arm-none-eabi-gcc
CC = arm-none-eabi-gcc
LD = arm-none-eabi-gcc
CP = arm-none-eabi-objcopy
SZ = arm-none-eabi-size
RM = rm
# Пути к CMSIS, StdPeriph Lib
#-------------------------------------------------------------------------------
CMSIS_PATH = cmsis
STDPERIPH_INC_PATH = stdperiph/inc
STDPERIPH_SRC_PATH = stdperiph/src
# startup файл
#-------------------------------------------------------------------------------
STARTUP = startup/startup_stm32f10x_md_vl.s
# Пути поиска исходных файлов
#-------------------------------------------------------------------------------
SOURCEDIRS := src
SOURCEDIRS += $(CMSIS_PATH)
# Пути поиска хидеров
#-------------------------------------------------------------------------------
INCLUDES += .
INCLUDES += $(SOURCEDIRS)
INCLUDES += $(CMSIS_PATH)
INCLUDES += $(STDPERIPH_INC_PATH)
# Библиотеки
#-------------------------------------------------------------------------------
LIBPATH +=
LIBS +=
# Настройки компилятора
#-------------------------------------------------------------------------------
CFLAGS += -mthumb -mcpu=cortex-m3 # архитектура и система комманд
CFLAGS += -std=gnu99 # стандарт языка С
CFLAGS += -Wall -pedantic # Выводить все предупреждения
CFLAGS += -Os # Оптимизация
CFLAGS += -ggdb # Генерировать отладочную информацию для gdb
CFLAGS += -fno-builtin
CFLAGS += $(addprefix -I, $(INCLUDES))
CFLAGS += $(addprefix -D, $(DEFINES))
# Скрипт линкера
#-------------------------------------------------------------------------------
LDSCR_PATH = ld-scripts
LDSCRIPT = stm32f100rb.ld
# Настройки линкера
#-------------------------------------------------------------------------------
LDFLAGS += -nostartfiles
LDFLAGS += -L$(LDSCR_PATH)
LDFLAGS += -T$(LDSCR_PATH)/$(LDSCRIPT)
LDFLAGS += $(addprefix -L, $(LIBPATH))
LDFLAGS += $(LIBS)
# Настройки ассемблера
#-------------------------------------------------------------------------------
AFLAGS += -ahls -mapcs-32
# Список объектных файлов
#-------------------------------------------------------------------------------
OBJS += $(patsubst %.c, %.o, $(wildcard $(addsuffix /*.c, $(SOURCEDIRS))))
OBJS += $(addprefix $(STDPERIPH_SRC_PATH)/, $(addsuffix .o, $(PERIPHDRIVERS)))
OBJS += $(patsubst %.s, %.o, $(STARTUP))
# Пути поиска make
#-------------------------------------------------------------------------------
VPATH := $(SOURCEDIRS)
# Список файлов к удалению командой "make clean"
#-------------------------------------------------------------------------------
TOREMOVE += *.elf *.hex
TOREMOVE += $(addsuffix /*.o, $(SOURCEDIRS))
TOREMOVE += $(addsuffix /*.d, $(SOURCEDIRS))
TOREMOVE += $(STDPERIPH_SRC_PATH)/*.o
TOREMOVE += $(patsubst %.s, %.o, $(STARTUP))
TOREMOVE += $(TARGET)
# Собрать все
#-------------------------------------------------------------------------------
all: $(TARGET).hex size
# Очистка
#-------------------------------------------------------------------------------
clean:
@$(RM) -f $(TOREMOVE)
# Создание .hex файла
#-------------------------------------------------------------------------------
$(TARGET).hex: $(TARGET).elf
@$(CP) -Oihex $(TARGET).elf $(TARGET).hex
# Показываем размер
#-------------------------------------------------------------------------------
size:
@echo "---------------------------------------------------"
@$(SZ) $(TARGET).elf
# Линковка
#-------------------------------------------------------------------------------
$(TARGET).elf: $(OBJS)
@$(LD) $(LDFLAGS) $^ -o [email protected]
# Компиляция
#-------------------------------------------------------------------------------
%.o: %.c
@$(CC) $(CFLAGS) -MD -c $< -o [email protected]
%.o: %.s
@$(AS) $(AFLAGS) -c $< -o [email protected]
# Сгенерированные gcc зависимости
#-------------------------------------------------------------------------------
include $(wildcart *.d)
- +4
- 11 апреля 2012, 13:24
- storm_ua
- 1
Файлы в топике:
stm32-gcc-template.zip
А не могли бы вы написать какую-нибудь вводную статью по этим make-файлам?
Меня как новичка интересует не взгляд гуру, который может детально описать каждую мелочь, а более общее описание, на пальцах буквально. Что значат все эти $, %, @ и почему в такой последовательности. Ну или ткните меня в какую-нибудь готовую статью, если есть.
Меня как новичка интересует не взгляд гуру, который может детально описать каждую мелочь, а более общее описание, на пальцах буквально. Что значат все эти $, %, @ и почему в такой последовательности. Ну или ткните меня в какую-нибудь готовую статью, если есть.
Краткий туториал с первой страницы гугла
Но новичку я бы рекомендовал использовать eclipse для stm32
Но новичку я бы рекомендовал использовать eclipse для stm32
Согласен, я немного неправильно сформулировал свою просьбу. Статей, подобных той что по ссылке, немало, но как правило они сводятся к виду «вот смотрите это комментарий, это таргет, это команда, а все остальное — в офф.документации».
Думаю документацию могут почитать все, она доступна. Поэтому меня больше интересуют не сами возможные команды и параметры, а практики их использования. Вот например для DVCS mercurial есть очень подробная документация, с примерами. Но найти хороший workflow для работы с этой системой на порядок сложнее.
Грубо говоря, вопрос не «как» а «почему»
Думаю документацию могут почитать все, она доступна. Поэтому меня больше интересуют не сами возможные команды и параметры, а практики их использования. Вот например для DVCS mercurial есть очень подробная документация, с примерами. Но найти хороший workflow для работы с этой системой на порядок сложнее.
Грубо говоря, вопрос не «как» а «почему»
Статью не напишу, ибо чукча скорее читатель чем писатель =)
Вот пара ссылок:
Перевод Makefile Mini HOWTO
Как устроен Makefile и что это такое?
GNU Make
Эффективное использование GNU Make
Вот пара ссылок:
Перевод Makefile Mini HOWTO
Как устроен Makefile и что это такое?
GNU Make
Эффективное использование GNU Make
Где карта, Билли содержимое линкер скрипта?
И как, поправив одну строчку, сменить используемый МК.
Ещё, советую отказаться от явного указания используемой перифирии, а собрать всю библиотеку, после чего собирать всё с функцией исключения неиспользованных функций.
И как, поправив одну строчку, сменить используемый МК.
Ещё, советую отказаться от явного указания используемой перифирии, а собрать всю библиотеку, после чего собирать всё с функцией исключения неиспользованных функций.
Я думал раз линкуется библиотека, так линкуется полностью…Именно такой эффект даёт несогласованное в Delphi сочетание RTTI, VCL и оптимизатора. Один из больших минусов Delphi — гиганские exe-шники.
Скорее это не минус Delphi, а минус собственно VCL. В Delphi вместо стандартной VCL можно использовать сторонние библиотеки KOL и MCK, которые и дадут маленький размер exe-шника. Но, на мой взгляд, в наше время маленький размер программы уже не особо важен (конечно, если это не десятки и сотни Мб для простой программы).
либо exe на пару сотен кило и dll с тулкитом на 10-15 метров весомВ этом плане в пингвинах все умно сдеалано ;). Там .so с библиотекой — одна на всю систему будет. Ну а в виндовсе все как обычно…
Причина не в виндовсе, а в том, что в линухе эта библиотека в 95% случаев уже будет установлена в системе, а в оставшихся 5% ее доустановит менеджер пакетов.
Под виндой Qt/GTK/wx относительно редки и рассчитывать на их наличие в системе не приходится. На менеджер пакетов рассчитывать тоже не приходится, так как его нету. Приходится тащить библиотеку с собой.
Ну а раз библиотека у всех с собой — ее незачем класть в публичное место. Можно положить рядом с собой. Тем более сей библиотеки версий куча, и не факт что с другой версией будет работать. У того же линукса тоже в библиотеках запросто могут лежать libqt-2.0.so, libqt-3.0.so (вроде принцип именования там немного другой, но похожий, а конкретно я не помню).
А вот с библиотеками от M$, вроде ActiveX контролов и иже с ними — как раз дела обстоят примерно как в линуксе.
Под виндой Qt/GTK/wx относительно редки и рассчитывать на их наличие в системе не приходится. На менеджер пакетов рассчитывать тоже не приходится, так как его нету. Приходится тащить библиотеку с собой.
Ну а раз библиотека у всех с собой — ее незачем класть в публичное место. Можно положить рядом с собой. Тем более сей библиотеки версий куча, и не факт что с другой версией будет работать. У того же линукса тоже в библиотеках запросто могут лежать libqt-2.0.so, libqt-3.0.so (вроде принцип именования там немного другой, но похожий, а конкретно я не помню).
А вот с библиотеками от M$, вроде ActiveX контролов и иже с ними — как раз дела обстоят примерно как в линуксе.
Во первых, я бы не назвал «гигантским» ехе файл на 400кб. Достаточно взглянуть на любой другой GUI-тулкит (wxWidgets, Qt, LCL...) — размеры ехе начинаются от 4МБ (либо exe на пару сотен кило и dll с тулкитом на 10-15 метров весом).
Во вторых, смарт-линкер в дельфи работает отлично. И не прикручен через костыли, как в GCC. Просто VCL специально написана так, чтобы код контролов компилировался полностью (иначе создается из формы кнопка и тут опа — а половины ее кода нету).
В третьих, главная причина размера ехе-файлов дельфи — это не RTTI и даже не VCL, а DFM. Формы в Delphi создаются динамически по DFM-файлу (он лежит в ресурсах exe), поэтому в ехе компилируется весь код всех контролов, которые могут встретиться в DFM. Зато VCL позволяет загружать формы в реалтайме и откуда угодно, подменять ресурсы форм (на этом основан встроенный механизм локализации приложений, который правда никто не использует) и так далее.
Все эти KOL и иже с ними основаны именно на замене десериализатора форм на код вида
В VCL же достаточно нарисовать в дизайнере форму и загрузить ее вызовом Application.CreateForm(TForm1, Form1). Из альтернатив только KOL/MCK предоставляет автоматический генератор этого кода — библиотеку MCK. Но у нее свои минусы (оно прикручено к дельфи через костыли и регулярно глючит). Кроме того, все эти библиотеки как правило не обладают ни функционалом, ни гибкостью VCL.
Во вторых, смарт-линкер в дельфи работает отлично. И не прикручен через костыли, как в GCC. Просто VCL специально написана так, чтобы код контролов компилировался полностью (иначе создается из формы кнопка и тут опа — а половины ее кода нету).
В третьих, главная причина размера ехе-файлов дельфи — это не RTTI и даже не VCL, а DFM. Формы в Delphi создаются динамически по DFM-файлу (он лежит в ресурсах exe), поэтому в ехе компилируется весь код всех контролов, которые могут встретиться в DFM. Зато VCL позволяет загружать формы в реалтайме и откуда угодно, подменять ресурсы форм (на этом основан встроенный механизм локализации приложений, который правда никто не использует) и так далее.
Все эти KOL и иже с ними основаны именно на замене десериализатора форм на код вида
Form1:=TForm1.Create;
Form1.Left:=100;
Form1.Width:=640;
...
Form1.Button1:=TButton.Create;
Form1.Button1.Left:=10;
Form1.Button1.Top:=10;
Form1.Button1.Width=75;
...
В VCL же достаточно нарисовать в дизайнере форму и загрузить ее вызовом Application.CreateForm(TForm1, Form1). Из альтернатив только KOL/MCK предоставляет автоматический генератор этого кода — библиотеку MCK. Но у нее свои минусы (оно прикручено к дельфи через костыли и регулярно глючит). Кроме того, все эти библиотеки как правило не обладают ни функционалом, ни гибкостью VCL.
Эх, всё это правильные опровдания, конечно.
Хоть я Дельфю и критикую, но 95% моих PC программ — на ней, и 95% из них на VCL.
А на ассемблере только 1%. Остальное С++.
Просто, в душе понимаешь, что в твой ехе-шник напихали много лишнего, что программа никогда не будет использовать. А душа стремится к совершенству. :)
Хоть я Дельфю и критикую, но 95% моих PC программ — на ней, и 95% из них на VCL.
А на ассемблере только 1%. Остальное С++.
Просто, в душе понимаешь, что в твой ехе-шник напихали много лишнего, что программа никогда не будет использовать. А душа стремится к совершенству. :)
А с чего ты взял, что оно не используется? То, что на API можно написать программу, которая так же выглядит и работает и весит в 10 раз меньше (правда, такого соотношения размеров можно получить только на мелких программах — строк до тысячи) не значит, что остальные 90% кода не используются.
Практически никто не знает дельфи и как он внутри устроен, но все кричат про гигантские exe и неиспользуемый код.
Практически никто не знает дельфи и как он внутри устроен, но все кричат про гигантские exe и неиспользуемый код.
Код-то видно. Заходишь в отладку, включаешь окно CPU. Смотришь на дизасемблер. Весь код методов классов, которые я не использовал — откомпилирован. А там их целая помойка, замаешся листать. Ставь точки останова — они никогда не сработают. Я ставил, проверял. :)
Да и просто-же, вот как расчитывают КПД? Энергии вкочали — ВО! Полезной работы — тююю. И не надо разбираться как внутри установка устроена.
Да и просто-же, вот как расчитывают КПД? Энергии вкочали — ВО! Полезной работы — тююю. И не надо разбираться как внутри установка устроена.
Если класс включен — значит, он тем или иным образом может использоваться.
В частности, классы VCL включаются из-за того, что они используются в автовызываемой процедуре Register. Будут ли они использованы для чего-то еще — зависит уже не от кода программы, а от внешних данных.
В частности, классы VCL включаются из-за того, что они используются в автовызываемой процедуре Register. Будут ли они использованы для чего-то еще — зависит уже не от кода программы, а от внешних данных.
Да и просто-же, вот как расчитывают КПД? Энергии вкочали — ВО! Полезной работы — тююю. И не надо разбираться как внутри установка устроена.Вот только энергия и работа измеряются в одних единицах, в отличие от программ, так что сравнение не очень-то корректно. Этот размер расходуется на удобство программирования. Не нравится — от VCL всегда можно отказаться. Правда, писать будет сложнее и не факт что ты вообще закончишь прогу, да и ошибок тем больше, чем сложнее программу писать.
И да, если отказаться от GUI-тулкита, то можно писать на WinAPI мелкие exe — от 16 килобайт (это размер CRT — базовой библиотеки поддержки языка). Если CRT модифицировать — можно создавать exe от пары килобайт (правда, половина фишек языка отвалится — вроде строк, исключений, стандартного ввода-вывода и прочего).
Я бы добавил еще информативности при сборке/очистке проекта
# Собрать все
#-------------------------------------------------------------------------------
all: start $(TARGET).hex size stop
# Очистка
#-------------------------------------------------------------------------------
clean: start rmfile stop
# Старт
#-------------------------------------------------------------------------------
start:
@echo "Start ---------------------------------------------------------------"
# Стоп
#-------------------------------------------------------------------------------
stop:
@echo "Stop ----------------------------------------------------------------"
# Удаление
#-------------------------------------------------------------------------------
rmfile:
@echo $(RM) -f $(TOREMOVE)
@$(RM) -f $(TOREMOVE)
# Создание .hex файла
#-------------------------------------------------------------------------------
$(TARGET).hex: $(TARGET).elf
@echo "Create HEX =>" $(CP) -Oihex $(TARGET).elf $(TARGET).hex
@$(CP) -Oihex $(TARGET).elf $(TARGET).hex
# Показываем размер
#-------------------------------------------------------------------------------
size:
@echo "Size ----------------------------------------------------------------"
@$(SZ) $(TARGET).elf
# Линковка
#-------------------------------------------------------------------------------
$(TARGET).elf: $(OBJS)
@echo "Linking =>" $^
@$(LD) $(LDFLAGS) $^ -o [email protected]
# Компиляция
#-------------------------------------------------------------------------------
%.o: %.c
@echo "Compilling C source =>" $<
@$(CC) $(CFLAGS) -MD -c $< -o [email protected]
%.o: %.s
@echo "Compilling ASM source =>" $<
@$(AS) $(AFLAGS) -c $< -o [email protected]
main$ make clean all
/dev/shm/tmp/sun/ccEkB5Qs.s: Assembler messages:
/dev/shm/tmp/sun/ccEkB5Qs.s:579: Error: registers may not be the same -- `strexb r0,r0,[r1]'
/dev/shm/tmp/sun/ccEkB5Qs.s:608: Error: registers may not be the same -- `strexh r0,r0,[r1]'
Makefile:149: recipe for target 'cmsis/core_cm3.o' failed
make: *** [cmsis/core_cm3.o] Error 1
slackware 14.2 x64
arm_gcc-10.2.0
arm_binutils-2.35
arm_gdb-10.1
+
arm-toolchain-10.3.1
Комментарии (32)
RSS свернуть / развернуть