本文介绍基于Make的交叉编译示例。如果您通过将SDK中的文件抽取出来的方式编译SDK,则可以跳过本章。
本文以将SDK移植到arm-linux
平台为例,演示一个完整的交叉编译移植过程。
对于嵌入式硬件平台,对编译出目标平台的libiot_sdk.a
,需要如下步骤:
在
tools/board/
目录下添加一个对应的配置文件,文件名规范为config.XXX.YYY
,其中XXX
部分就对应后面wrappers/os/XXX
目录的HAL层代码。在配置文件中,需要指定:
交叉编译器
OVERRIDE_CC
的路径。交叉链接器
OVERRIDE_LD
的路径。静态库压缩器
OVERRIDE_AR
的路径。编译选项
CONFIG_ENV_CFLAGS
,用于C文件的编译。链接选项
CONFIG_ENV_LDFLAGS
,用于可执行程序的链接。
编译SDK,对可能出现的跨平台问题进行修正,直到成功产生目标格式的
libiot_sdk.a
。您需要使用编译方式,产生目标架构的
libiot_hal.a
。若目标平台尚未被适配,则
libiot_hal.a
对应的源代码在C Link SDK中并未包含,需要您自行实现HAL_*()
接口。
下面以某款目前未官方适配的arm-linux
目标平台为例,演示如何编译出该平台上可用的libiot_sdk.a
。
安装交叉编译工具链
本示例以Ubuntu16.04开发环境为例。
$ sudo apt-get install -y gcc-arm-linux-gnueabihf
$ arm-linux-gnueabihf-gcc --version
arm-linux-gnueabihf-gcc (Ubuntu/Linaro 4.8.4-2ubuntu1~14.04.1) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
添加配置文件
$ touch tools/board/config.arm-linux.demo
$ ls tools/board/
config.alios.mk3080 config.arm-linux.demo config.ubuntu.x86
编辑配置文件
编辑配置文件需要设置编译选项和工具链,以及跳过编译的目录。
$ vim tools/board/config.arm-linux.demo
CONFIG_ENV_CFLAGS = \
-D_PLATFORM_IS_LINUX_ \
-Wall \
-DNO_EXECUTABLES
CONFIG_ENV_LDFLAGS = \
-lpthread -lrt
OVERRIDE_CC = arm-linux-gnueabihf-gcc
OVERRIDE_AR = arm-linux-gnueabihf-ar
OVERRIDE_LD = arm-linux-gnueabihf-ld
CONFIG_wrappers :=
CONFIG_wrappers :=
表示跳过对wrappers
目录的编译,以及-DNO_EXECUTABLES
不要产生可执行程序。在编译未被适配平台的库可以避免产生过多错误。
选择配置文件
$ make reconfig
SELECT A CONFIGURATION:
1) config.alios.mk3080
2) config.arm-linux.demo
3) config.ubuntu.x86
#? 2
SELECTED CONFIGURATION:
VENDOR : arm-linux
MODEL : demo
交叉编译产生库文件libiot_sdk.a
本步骤不编译HAL,只是验证配置文件中的交叉编译参数是否正确,如果出现错误请对配置文件再次进行修改,直到编译成功。
$ make
BUILDING WITH EXISTING CONFIGURATION:
VENDOR : arm-linux
MODEL : demo
[CC] infra_timer.o <= ...
[CC] infra_json_parser.o <= ...
[CC] infra_preauth.o <= ...
获取交叉编译的产物,包括静态库和头文件
$ ls -1 output/release/lib/
libiot_sdk.a
libiot_tls.a
libiot_sdk.a
文件是编译好的物联网平台SDK,已经是ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV)
格式,也就是arm-linux
格式的交叉编译格式。libiot_tls.a
是一个裁剪过的加解密库,您可以选择使用,也可以选择使用平台自带的加解密库,以减小最终固件的尺寸。
$ ls -1 output/release/include/
dev_model_api.h
dev_sign_api.h
infra
mqtt_api.h
dev_sign_api.h
是使用SDK中设备签名功能需要包含的头文件,类似mqtt_api.h
是使用SDK中MQTT上云功能需要的,infra
下的头文件也请加入编译搜索路径。
开发未适配平台的HAL层
对于实现平台抽象层接口HAL_XXX_YYY()
的库libiot_hal.a
,不限制其编译和产生的方式。
您也可以借助物联网平台设备端C Link SDK的编译系统来开发和产生。
复制一份HAL层实现代码
在wrappers/os
下需要创建一个与tools/board/config.XXX.YYY
中的XXX
一样的目录用于存放HAL实现。
由于目标平台为arm-linux
,因此可以复制Ubuntu下面的HAL实现,下面是操作示例:
$ cd wrappers/os/
$ ls
freertos nos nucleus ubuntu
wrappers/os$ cp -rf ubuntu arm-linux
wrappers/os$ rm -f arm-linux/HAL_UART_linux.c
wrappers/os$ ls
arm-linux freertos nos nucleus ubuntu
wrappers/os$ tree -A arm-linux/
arm-linux/
+-- HAL_AWSS_linux.c
+-- HAL_Crypt_Linux.c
+-- HAL_FS_Linux.c
+-- HAL_KV_linux.c
+-- HAL_OS_linux.c
+-- HAL_TCP_linux.c
+-- HAL_UDP_linux.c
打开之前被关闭的编译开关
$ vim tools/board/config.arm-linux.demo
CONFIG_ENV_CFLAGS = \
-D_PLATFORM_IS_LINUX_ \
-Wall\
-DNO_EXECUTABLES
CONFIG_ENV_LDFLAGS = \
-lpthread -lrt
OVERRIDE_CC = arm-linux-gnueabihf-gcc
OVERRIDE_AR = arm-linux-gnueabihf-ar
OVERRIDE_LD = arm-linux-gnueabihf-ld
# CONFIG_wrappers :=
CONFIG_wrappers :=
前添加了#
符号,表示这一行已被注释,wrappers
将会进入编译过程。
尝试交叉编译被复制的HAL层代码
$ make reconfig
SELECT A CONFIGURATION:
1) config.alios.mk3080
2) config.arm-linux.demo
3) config.ubuntu.x86
#? 2
SELECTED CONFIGURATION:
VENDOR : arm-linux
MODEL : demo
...
$ make
wrappers/os/arm-linux/*.c
编译成功,产生arm-linux
格式的libiot_hal.a
。
交叉编译样例程序
有了
libiot_hal.a
、libiot_tls.a
,以及libiot_sdk.a
,可以尝试交叉编译样例的可执行程序,并在目标嵌入式硬件开发板上运行。去掉
config.arm-linux.demo
里面的-DNO_EXECUTABLES
开关,使*/examples/
目录下的样例源码被编译出来。删掉
-DNO_EXECUTABLES
开关时,将上面一行-Wall
后面的''
符号也删掉。
修改后的config.arm-linux.demo
内容如下所示。
$ vi tools/board/config.arm-linux.demo
CONFIG_ENV_CFLAGS = \
-D_PLATFORM_IS_LINUX_ \
-Wall
CONFIG_ENV_LDFLAGS = \
-lpthread -lrt
OVERRIDE_CC = arm-linux-gnueabihf-gcc
OVERRIDE_AR = arm-linux-gnueabihf-ar
OVERRIDE_LD = arm-linux-gnueabihf-ld
# CONFIG_wrappers :=
在-DNO_EXECUTABLES
开关从CONFIG_ENV_CFLAGS
中已去掉,示例可执行程序进入了编译范围。
重新载入配置文件,交叉编译可执行程序
$ make reconfig
$ make
如果有如下编译输出,则表示mqtt-example
等一系列示例程序已被成功编译,并存放在output/release/bin
目录下。
[LD] dev-sign-example <= ...
[LD] mqtt-example <= ...
[LD] linkkit-example-solo <= ...
$ cd output/release/bin/
$ ls
dev-sign-example linkkit-example-solo mqtt-example
$ file *
dev-sign-example: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked ...
linkkit-example-solo: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked ...
mqtt-example: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked ...
可以用file
命令验证可执行程序是否交叉编译到arm-linux
架构中。
运行示例程序
您可以把示例程序例如mqtt-example
,用SCP
、TFTP
或者其它方式,拷贝下载到您的目标开发板上运行调试。
如果样例程序和同样例程在
Ubuntu
上运行效果相同,则证明wrappers/os/arm-linux
部分的HAL层代码工作正常。如果样例程序运行起来,和同样例程在
Ubuntu
上运行效果不同,则需要再重点修改调试HAL实现。也就是指
wrappers/os/arm-linux
目录的HAL层代码,因为这些代码是从Ubuntu
主机部分复制的,完全可能并不适合arm-linux
。
如此反复直到确保libiot_hal.a
的开发没问题为止。