|
STEVAL-IDB007V1 演示工程代码结构和编译
[复制链接]
本帖最后由 cruelfox 于 2018-1-10 17:21 编辑
安装了 BlueNRG-1_2 DK 2.5.0 软件包以后,可以看到 Project\BLE_Examples 目录下有若干个现成的例子目录树。也就是 Firmware 目录中的演示内容的 .HEX 文件对应的工程文件在这里了。我把已经烧写体验过的 BLE_SensorDemo 作为测试对象来分析一番。目录结构是这样的:
BLE_SensorDemo
├─EWARM
│ ├─BlueNRG-1
│ └─BlueNRG-2
├─inc
├─MDK-ARM
│ ├─BlueNRG-1
│ └─BlueNRG-2
├─src
└─TrueSTUDIO
├─BlueNRG-1
│ └─.settings
└─BlueNRG-2
└─.settings
例子分别提供了 IAR, Keil, TrueStudio 三种开发环境的工程文件。如果熟悉的开发工具是这三者之一,可以直接导入进来,和开发STM32的流程就一样了。我本人习惯的是用 GCC 自己手工操作来编译,所以嘛仍然要需要转换一下。TrueStudio是用GCC的编译器,所以支持是没有问题的。我的电脑上没有安装TrueStudio,就自己手工拆解移植一个看看了。
在 TrueStudio\BlueNRG-1 子目录下有 BlueNRG1.ld 这个文件,它是给GNU ld (linker, 链接器)的脚本,说明编译后代码如何组织,RAM和ROM的地址和大小等等。用GCC开发单片机必须要有这样的文件,实在没有就得自己编写。在这个目录里还有 .project 和 .cproject 两个文本文件,是给 TrueStudio 用的,工程包含的文件、设置选项之类,可以看一下里面的内容来确定需要用到哪些文件,减少查找难度。
这个 Demo 例子的源代码在 src 和 inc 子目录下,文件数不多。
├─inc
│ BlueNRG1_conf.h
│ BlueNRG1_it.h
│ gatt_db.h
│ sensor.h
│ SensorDemo_config.h
│
├─src
│ BlueNRG1_it.c
│ gatt_db.c
│ sensor.c
│ SensorDemo_main.c
于是我可以把它们copy出来放到自己的一个目录下面,写一个初步的 Makefile 了:
- default: demo.hex
- CC =arm-none-eabi-gcc -c
- LD =arm-none-eabi-gcc -nostdlib
- CFLAGS =-g -O2 -Wall -mcpu=cortex-m0 -mthumb
- LDFLAGS=-mcpu=cortex-m0 -mthumb -T ../BlueNRG1.ld
- INC =-I../../CMSIS
- APP_OBJ = sensor.o BlueNRG1_it.o gatt_db.o SensorDemo_main.o
- demo.elf : $(APP_OBJ)
- $(LD) $(LDFLAGS) $^ -o $@ -lc
- %.o : %.c
- $(CC) $(CFLAGS) $(INC) $<
- %.hex : %.elf
- arm-none-eabi-objcopy -Oihex $< $@
复制代码
但是这样必然不能得到编译结果,还缺很多东西,因为还没有把支持的库放进来。这会儿执行 make 肯定报错。
首先是报告 xxxxx.h 头文件找不到。可以搜索一下,其实需要的头文件都在和 Project 并列的 Library 目录下面了,这里面的源文件是所有工程共用的。
Library
├─BlueNRG1_Periph_Driver
│ ├─inc
│ └─src
├─Bluetooth_LE
│ ├─inc
│ ├─library
│ ├─OTA
│ │ ├─inc
│ │ └─src
│ └─Profile_Framework_Central
│ ├─includes
│ ├─library
│ └─profiles
│ └─ble_profile
├─CMSIS
│ ├─Device
│ │ └─ST
│ │ └─BlueNRG1
│ │ ├─Include
│ │ └─Source
│ └─Include
├─hal
│ ├─inc
│ └─src
├─SDK_Eval_BlueNRG1
│ ├─inc
│ └─src
所以首先需要告诉 GCC 在哪些目录下去查找 .h 头文件,可以在 gcc 命令行使用 -I 参数添加。分析下,Library 目录下面的文件组成部分:
(1) BlueNRG1_Periph_Driver 这里面是片上设备的驱动函数库,相当于 STM32 Standard Periphral Driver 库的内容。
(2) Bluetooth_LE 这里应该就是 BLE 协议栈的库了,只有头文件和编译好的库文件,不提供源代码。
(3) CMSIS 开发ARM Cortex-m都需要的,基本的寄存器定义在这里面
(4) hal 猜测是 Hardware Abstract Layer 意思吧,但是和STM32相比,文件少多了,并不是STM32 HAL库的对应。
(5) SDK_Eval_BlueNRG1 和开发板有关的内容,比如板载的传感器支持
把这几个目录里面的 inc 目录都加到 GCC 头文件搜索路径里面去以后,可以顺利编译源代码中的 .c 文件了,得到对应的 .o 目标文件。
当然,还不能生成最后的程序,因为还有很多函数找不到,它们在 library 的 src 目录里面。参考下 TrueStudio 工程文件里面列出的 .c 文件,可以把这些文件都编译成模块,加到工程里面。最终我的 Makefile 是这个样子的:
- default: demo.hex
- CC =arm-none-eabi-gcc -c
- LD =arm-none-eabi-gcc -nostdlib
- CFLAGS =-g -O2 -Wall -mcpu=cortex-m0 -mthumb -std=c99 -fshort-wchar
- LDFLAGS=-mcpu=cortex-m0 -mthumb -T ../BlueNRG1.ld
- INC =-I../../ST -I../../CMSIS -I. -I../hal/inc -I../Driver/inc -I../BLE/inc -I../SDK_Eval/inc
- APP_OBJ = sensor.o BlueNRG1_it.o gatt_db.o SensorDemo_main.o
- SYS_OBJ = system_bluenrg1.o
- HAL_OBJ = \
- lib/clock.o \
- lib/osal.o \
- lib/sleep.o \
- lib/context_switch.o
- DRV_OBJ = \
- lib/BlueNRG1_adc.o \
- lib/BlueNRG1_dma.o \
- lib/BlueNRG1_flash.o \
- lib/BlueNRG1_gpio.o \
- lib/BlueNRG1_i2c.o \
- lib/BlueNRG1_mft.o \
- lib/BlueNRG1_pka.o \
- lib/BlueNRG1_rng.o \
- lib/BlueNRG1_rtc.o \
- lib/BlueNRG1_spi.o \
- lib/BlueNRG1_sysCtrl.o \
- lib/BlueNRG1_uart.o \
- lib/BlueNRG1_wdg.o \
- lib/BlueNRG1_pka.o \
- lib/misc.o
- SDK_OBJ = \
- lib/LPS25HB.o \
- lib/LSM6DS3.o \
- lib/SDK_EVAL_Button.o \
- lib/SDK_EVAL_Com.o \
- lib/SDK_EVAL_Config.o \
- lib/SDK_EVAL_I2C.o \
- lib/SDK_EVAL_Led.o \
- lib/SDK_EVAL_SPI.o
- BLE_LIB = ../BLE/lib/libbluenrg1_stack.a
- demo.elf : $(APP_OBJ) $(HAL_OBJ) $(DRV_OBJ) $(SDK_OBJ) $(SYS_OBJ)
- $(LD) $(LDFLAGS) $^ $(BLE_LIB) -o $@ -lc
- %.o : %.c
- $(CC) $(CFLAGS) $(INC) $<
- %.o : ../%.c
- $(CC) $(CFLAGS) $(INC) $< -o $@
- lib/%.o : ../hal/src/%.c
- $(CC) $(CFLAGS) $(INC) $< -o $@
- lib/%.o : ../hal/src/%.S
- $(CC) $(CFLAGS) $< -o $@
- lib/%.o : ../Driver/src/%.c
- $(CC) $(CFLAGS) $(INC) $< -o $@
- lib/%.o : ../SDK_Eval/src/%.c
- $(CC) $(CFLAGS) $(INC) $< -o $@
- %.hex : %.elf
- arm-none-eabi-objcopy -Oihex $< $@
复制代码
我把 DK 中 Library 部分也 copy 了一份到我自己的目录下,并且修改了其中的目录名(目的是把路径书写简化),有的子目录调整了一下。库中的C代码编译之后放在工程的 lib 子目录下,是为了和 Demo 工程专有的代码区分。
还要注意的是 hal 目录有一个汇编文件 context_switch.s 它不能用 GNU as 直接汇编,而要通过 gcc 预处理(打开看就发现它使用了C语言的 #include, #define 之类指令),所以需要把文件名改为大写的 .S 后缀。我在这里疑惑了一阵。
此外,在 link 的时候会遇到一个警告,意思是 wchar_t 类型是4字节还是2字节,在某几个模块里和最后的输出文件不一样。我没有在单片机上用过wchar_t,网上搜索了下,最后是决定把gcc编译选项加上 -fshort-wchar 然后忽略link的警告。
代码搬过来后直接用 make 命令就可以按照我写的 Makefile 规则进行编译了,处理成功后可得到 .HEX 文件。
附件是我移植过来的GCC纯命令行编译可操作的工程目录压缩包。
|
赞赏
-
1
查看全部赞赏
-
|