Linux
|
2020-05-02
|
782
資料夾結構
第一步,建立三個資料夾 “System”、“OS” 及 “User”
. |-- System | |-- OS | `-- User
|
- System 放驅動程式
- OS 就是作業系統(也可不用)
- User 放的是我們的專案
接著,在每個資料夾底下新增一個 makefile。
. |-- System | `-- makefile | |-- OS | `-- makefile | |-- User | `-- makefile | `-- makefile
|
準備步驟的最後,將所有程式碼正確的擺放。如範例:
. |-- System | |-- STM32 | | |-- src | | `-- inc | | | |-- STM32F429 | | |-- src | | `-- inc | | | |-- CMSIS | | |-- src | | `-- inc | | | `-- makefile | |-- OS | |-- src | |-- inc | `-- makefile | |-- User | |-- src | |-- inc | `-- makefile | `-- makefile
|
在這個例子,我們在 System 底下放了三個驅動,所以需要將程式碼分成三個資料夾。
當然你也可以直接全部放在一起是沒問題的。
最後的最後,別忘了在驅動的底下也加一個 makefile。
. |-- System | |-- STM32 | | |-- src | | |-- inc | | `-- makefile | | | |-- STM32F429 | | |-- src | | |-- inc | | `-- makefile | | | |-- CMSIS | | |-- src | | |-- inc | | `-- makefile | | | `-- makefile | |-- OS | |-- src | |-- inc | `-- makefile | |-- User | |-- src | |-- inc | `-- makefile | `-- makefile
|
下一步,來寫 makefile!
GCC
在所有的 makefile(除了最上層)寫上以下程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| TCPREFIX = arm-none-eabi- CC = $(TCPREFIX)gcc
CFLAGS = -c -Wall -fno-common -O0 -g -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 --specs=nosys.specs
INCFLAG =\ -I. \ -Iinc
CFLAGS += $(INCFLAG)
OBJDIR = obj
OBJS =\ $(OBJDIR)/src.o
all: $(OBJS)
$(OBJDIR)/%.o: src/%.c | $(OBJDIR) @echo "bulid file: $<" $(CC) $(CFLAGS) -MMD -MF$(@:%.o=%.d) -o $@ $<
$(OBJDIR): @echo $(NOW) INFO Make new folder User/$(OBJDIR). mkdir -p $(OBJDIR)
clean: -rm -rf $(OBJDIR)/*.o -rm -rf $(OBJDIR)/*.d
|
- 使用
arm-none-eabi-gcc
來進行編譯
- 為
gcc
加入一些設定,如浮點數處理器。
- 接著設定所有需要連結的 object file
- 將所有
.c
編譯成 .o
- Target
all
將會完成編譯所有檔案
- Target
clean
可以清理所有 object file
接著告訴主要的 makefile 要去底下的 makefile 執行編譯
1 2 3 4
| obj: $(MAKE) all -C System $(MAKE) all -C OS $(MAKE) all -C User
|
-C
意味著要去下層資料夾執行目標,所以第二行等同於:
Startup.o
Startup.o 是必須的,把它放在 User
理,但不要放進 src
;編譯他的道理是類似的
OBJS +=\ startup.o
Startup/startup.o: ./startup.s | $(OBJDIR) @echo "bulid file: $<" $(CC) $(CFLAGS) -MMD -MF$(@:%.o=%.d) -o $@ $<
|
以上建置完成後,能快速的編譯所有程式。接著我們將所有 object file 連結成一個二進位檔。
G++ (Linker)
連結的動作放在主要的 makefile 中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| TCPREFIX = arm-none-eabi- LD = $(TCPREFIX)g++
LFLAGS = -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Os -T$(LDFILE) --specs=nosys.specs LDFILE = ./STM32F429ZI_FLASH.ld
OBJS =\ $(wildcard ./User/obj/*.o) \ $(wildcard ./System/*/obj/*.o) \ $(wildcard ./OS/obj/*.o) \ ./User/startup.o
main.elf: $(OBJS) $(LDFILE) @echo "link file: $@" $(LD) $(LFLAGS) -o $@ $(OBJS)
|
- 使用 wildcard 掃描所有 object file
- 連結成一個
.elf
Objdump and Objcopy
再將 .elf
轉成 .bin
燒錄。
1 2 3 4 5 6 7 8
| TCPREFIX = arm-none-eabi- CP = $(TCPREFIX)objcopy OD = $(TCPREFIX)objdump
main.bin: obj main.elf @echo "copy file main.elf" $(CP) $(CPFLAGS) main.elf $@ $(OD) $(ODFLAGS) main.elf > main.lst
|
Openocd
最後一件事,燒錄;這裡使用 openocd。
1 2 3 4 5 6 7 8 9 10 11 12
| run: main.bin @echo $(YELLOW)"Flash $< into board..."$(RST) openocd -f $(OCDCFG) \ -c "init" \ -c "reset init" \ -c "stm32f2x unlock 0" \ -c "flash probe 0" \ -c "flash info 0" \ -c "flash write_image erase $< 0x8000000" \ -c "reset run" -c shutdown @echo $(GREEN)"Finish flash $< into board."$(RST) @echo ""
|
總結
在主 makefile 寫下以下片段,將所有東西整合吧。
如此以來,只要下指令 make all
就會將所有該編譯的程式碼編譯完成,連結成一個二進位檔,最後燒盡板子。
這是我的一個專案建置的範例,可以參考。