上一个分享的编译过程是最简单的 blinky 工程作为测试。这次来编译一个BLE的应用,它用到了BLE的API.
属于这个工程的 C 源文件一共有6个,逐一编译即可。使用到的头文件除了 SDK include 目录下的头文件外,还要用到其三个子目录:bb (无线基带), ble (低功耗蓝牙), kernel (系统内核) 当中的文件。
除了同 blinky 工程一样要需要编译链接几个启动、硬件设备相关的模块之外,BLE部分还需要 SDK 的 source\firmware\ble_abstraction_layer 下面的 C 源文件和头文件。不难在 ble_peripheral_server_hrp.rteconfig 工程配置文件中找到线索。
但并不意味着所有的代码都在这些 C 源文件中了。因为 RSL10 BLE 协议栈还不是开源的,实际上SDK的 BLE API 大都以二进制库的形式提供,在 SDK 的 lib 目录下面,有若干个 .a 的二进制库文件。
lib
├─ble_core
│ ├─Release
│ │ libblelib.a
│ │ libkelib.a
│ │ libweak_prf.a
│ │
│ ├─Release_HCI
│ │ libblelib.a
│ │ libkelib.a
│ │ libweak_prf.a
│ │
│ └─Release_Light
│ libblelib.a
│ libkelib.a
│ libweak_prf.a
│
├─ble_profiles
│ ├─Release
│ │ libanpc.a
│ │ libanps.a
│ │ libbasc.a
│ │ libbass.a
│ │ libblpc.a
│ │ libblps.a
│ │ libcgmc.a
│ │ ......
│ │
│ └─Release_HCI
│ libanpc.a
│ libanps.a
│ libbasc.a
│ libbass.a
│ libblpc.a
│ libblps.a
│ ......
│
└─Release
fota.bin
libfota.a
这些库文件有重名的,就是有同一个库不同版本。区别是什么我还不了解。
链接的的时候用 -l 参数指定要使用的库(不用后缀,也不用最前面的 lib 三个字母),用 -L 参数指定库文件的路径。我先尝试将 lib/ble_core/Release 下面的三个库文件加进来( -lblelib -lkelib -lweak_prf ),链接就成功了,得到 ELF 文件。
然而我将镜像文件烧进 RSL10 以后,运行了却扫描不到设备。按照说明设备广播的时候 LED 是要亮的却并没有亮。哪里出了问题?
我检查了导出镜像文件的内存地址,和 ELF 文件对应也无错误,链接过程也没有报告任何符号缺失。
最后我和IDE的工程文件里面涉及到的SDK当中文件进行核对,发现库文件使用部分有所不同:
<component Capiversion="1.0.0" Cclass="Device" Cgroup="Bluetooth Core" Csub="BLE Stack" Cvariant="release" Cvendor="ONSemiconductor" Cversion="3.5.285" deviceDependent="1">
<package name="RSL10" url="www.onsemi.com" vendor="ONSemiconductor" version="3.5.285"/>
<file category="doc" deviceDependent="1" name="documentation/RSL10_firmware_reference.pdf"/>
<file category="library" deviceDependent="1" name="lib/ble_core/Release/libblelib.a"/>
</component>
<component Capiversion="1.0.0" Cclass="Device" Cgroup="Bluetooth Core" Csub="Kernel" Cvariant="release" Cvendor="ONSemiconductor" Cversion="3.5.285" deviceDependent="1">
<package name="RSL10" url="www.onsemi.com" vendor="ONSemiconductor" version="3.5.285"/>
<file category="doc" deviceDependent="1" name="documentation/RSL10_firmware_reference.pdf"/>
<file category="library" deviceDependent="1" name="lib/ble_core/Release/libkelib.a"/>
</component>
<component Cclass="Device" Cgroup="Bluetooth Profiles" Csub="BASS" Cvariant="release" Cvendor="ONSemiconductor" Cversion="3.5.285" deviceDependent="1">
<package name="RSL10" url="www.onsemi.com" vendor="ONSemiconductor" version="3.5.285"/>
<file category="doc" deviceDependent="1" name="documentation/ceva/RW-BLE-PRF-BAS-IS.pdf"/>
<file category="header" deviceDependent="1" name="include/ble/profiles/bass.h"/>
<file category="library" deviceDependent="1" name="lib/ble_profiles/Release/libbass.a"/>
</component>
<component Cclass="Device" Cgroup="Bluetooth Profiles" Csub="DISS" Cvariant="release" Cvendor="ONSemiconductor" Cversion="3.5.285" deviceDependent="1">
<package name="RSL10" url="www.onsemi.com" vendor="ONSemiconductor" version="3.5.285"/>
<file category="doc" deviceDependent="1" name="documentation/ceva/RW-BLE-PRF-DIS-IS.pdf"/>
<file category="header" deviceDependent="1" name="include/ble/profiles/diss.h"/>
<file category="library" deviceDependent="1" name="lib/ble_profiles/Release/libdiss.a"/>
</component>
<component Cclass="Device" Cgroup="Bluetooth Profiles" Csub="HRPS" Cvariant="release" Cvendor="ONSemiconductor" Cversion="3.5.285" deviceDependent="1">
<package name="RSL10" url="www.onsemi.com" vendor="ONSemiconductor" version="3.5.285"/>
<file category="doc" deviceDependent="1" name="documentation/ceva/RW-BLE-PRF-HRP-IS.pdf"/>
<file category="header" deviceDependent="1" name="include/ble/profiles/hrps.h"/>
<file category="library" deviceDependent="1" name="lib/ble_profiles/Release/libhrps.a"/>
</component>
也就是范例工程并没有使用 libweak_prf.a,而比我多用了 libbass.a, libdiss.a, libhrps.a 三个库。我不知道这几个库分别的作用,那么就换一下试试。结果,就成功了。
Makefile 确定如下:
default: app.elf
INC = -Iinc -Iinc/kernel -Iinc/bb -Iinc/ble -Iinc/ble/profiles
APP_OBJ = app.o app_bass.o app_config.o app_hrps.o app_msg_handler.o app_trace.o
APP_OPTS = -DRSL10_CID=101 \
-DCFG_PRF_DISS=1 \
-DCFG_PRF_HRPS=1 \
-DSECURE_CONNECTION \
-DAPP_BONDLIST_SIZE=28 \
-DCFG_BOND_LIST_IN_NVR2=true \
-DCFG_BLE=1 \
-DCFG_ALLROLES=1 \
-DCFG_APP \
-DCFG_APP_BATT \
-DCFG_ATTS=1 \
-DCFG_CON=8 \
-DCFG_EMB=1 \
-DCFG_HOST=1 \
-DCFG_RF_ATLAS=1 \
-DCFG_ALLPRF=1 \
-DCFG_PRF=1 \
-DCFG_NB_PRF=8 \
-DCFG_CHNL_ASSESS=1 \
-DCFG_SEC_CON=1 \
-DCFG_EXT_DB \
-DCFG_PRF_BASS=1
SYSOBJ = rsl10_romvect.o \
rsl10_sys_asrc.o \
rsl10_sys_audio.o \
rsl10_sys_clocks.o \
rsl10_sys_crc.o \
rsl10_sys_dma.o \
rsl10_sys_flash.o \
rsl10_sys_power.o \
rsl10_sys_power_modes.o \
rsl10_sys_rffe.o \
rsl10_sys_timers.o \
rsl10_sys_uart.o \
rsl10_sys_version.o \
rsl10_protocol.o \
sbrk.o \
start.o \
system_rsl10.o \
startup_rsl10.o
BLEOBJ = ble_gap.o \
ble_gatt.o \
ble_l2c.o \
msg_handler.o \
ble_bass.o \
ble_diss.o \
ble_hrps.o \
stubprf.o
CFLAGS = -std=gnu99 -mcpu=cortex-m3 -mthumb -O2 $(APP_OPTS) -ffunction-sections -fdata-sections
LDFLAGS = -Llib -lblelib -lkelib -lbass -ldiss -lhrps -Tsections.ld -nostartfiles -Wl,--gc-sections
%.o : %.c
arm-none-eabi-gcc -c -I. -Ible $(INC) $(CFLAGS) $<
%.o : ble/%.c
arm-none-eabi-gcc -c -I. -Ible $(INC) $(CFLAGS) $<
%.o : sys/%.c
arm-none-eabi-gcc -c $(INC) $(CFLAGS) $<
%.o : sys/%.S
arm-none-eabi-gcc -c $(CFLAGS) $<
app.elf : $(APP_OBJ) $(SYSOBJ) $(BLEOBJ)
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb $^ $(LDFLAGS) -o $@
编译结果,代码占用超过 128kB. 已静态分配的RAM略大于16kB.
app.elf: file format elf32-littlearm
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00024720 00100000 00100000 00010000 2**3
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .ARM.exidx.reset 00000008 00124720 00124720 00034720 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .systemclock 00000004 20000000 20000000 00050000 2**2
ALLOC
3 .data 000008cc 20000008 00124728 00040008 2**3
CONTENTS, ALLOC, LOAD, DATA
4 .bss 000039cc 200008d4 00124ff4 000408d4 2**2
ALLOC
5 .noinit 00000000 200042a0 200042a0 000408d4 2**0
CONTENTS
6 ._stack 00000400 200042a0 001289c0 000408d4 2**0
ALLOC