Zephyr连入阿里云物联网平台-移植

Creative Commons
本作品采用知识共享署名

本文说明如何移植Link Kit SDK到zephyr

Link Kit SDK介绍

下面是阿里官网对Link Kit的描述:
Link Kit SDK由阿里云提供给设备厂商集成到设备上,将设备安全的接入到阿里云IoT物联网平台,并让设备可以被阿里云IoT物联网平台进行控制与管理。
阿里物联网云的Link Kit SDK解决方案如下(摘自阿里官方手册)
resolution
当Zephyr iot设备使用Link Kit SDK for C

软件结构如下(摘自阿里官方手册)
struct

1.应用编程接口(API)

Link Kit SDK提供API给设备调用,用于对SDK提供的各个功能模块进行控制, 在zephyr中可直接用于APP的开发

2.功能模块

由Link Kit SDK本身实现,提供了一系列功能模块供设备调用:

  • 设备连云:提供MQTT、CoAP、HTTP/S等多种方式连接阿里云IoT物联网平台
  • 设备身份认证:提供一机一密、一型一密对设备进行身份认证
  • OTA:提供设备固件升级
  • 子设备管理:接入子设备
  • WiFi配网:将无线路由器AP的SSID、密码传输给WiFi设备
  • 设备管理:提供属性、服务、事件来对设备进行管理和控制
  • 用户绑定:提供安全绑定token来支持用户与设备进行绑定
  • 设备本地控制:对于使用WiFi和以太网接入的设备,手机或者网关如果与设备位于同一个局域网,则可以通过局域网对设备进行控制而不是通过云端进行控制,从而让控制更快捷更可靠.

3.硬件适配接口(Hardware Abstraction Layer, HAL)

Link Kit SDK需求的标准接口,由zephyr的API来实现,移植主要是体现在这里

移植

SDK准备

zephyr是C环境,因此下载C-SDK即可

下载

从下面地址下载C-SDK
https://code.aliyun.com/linkkit/c-sdk/repository/archive.zip?spm=a2c4g.11186623.2.15.4eb0492bAnxrUX&ref=v3.0.1

SDK功能配置和剪裁

将下载后的C-SDK解压缩,例如我是加压缩到~/work/project/alisdk, 在解压缩的目录下执行make menuconfig进行配置和剪裁,如下图:
config
对于zephyr选择以下三项,其它的属于功能选项可根据需求配置

1
2
3
PLATFORM_HAS_STDINT
PLATFORM_HAS_DYNMEM
PLATFORM_HAS_OS

进行保存退出

抽取SDK

Link Kid SDK提供SDK编译为库和提取SDK两种移植方法,这里zephyr选择提取SDK,这样源代码可控:
在~/work/project/alisdk下执行./extract.sh 可以看到如下提示

1
2
3
4
5
6
7
 Download request sent, waiting respond ...

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 236k 100 236k 0 0 204k 0 0:00:01 0:00:01 --:--:-- 204k

Please pick up extracted source files in [/home/frank/work/project/alisdk/output]

然后在output内就能看到提取的文件

1
2
3
drwxr-xr-x 7 frank frank 4096 7月  12 10:57 eng
drwxr-xr-x 2 frank frank 4096 7月 12 10:57 examples
-rw-r--r-- 1 frank frank 1968 7月 12 10:57 Makefile

eng是SDK的文件,将其拷贝到你zephyr的app下面

SDK移植

为测试新建一个zephyr的app,例如我放在~/work/project/nrf52_moderate/apps/aliiot下,目录结构如下

1
2
3
4
5
6
7
8
9
10
11
12
.
├── CMakeLists.txt
├── prj.conf
└── src
├── eng
│   ├── dev_model
│   ├── dev_sign
│   ├── infra
│   ├── mqtt
│   ├── sdk_include.h
│   └── wrappers
└── main.c

将提取的eng放到src下

修改CMakeLists.txt

修改CMakeLists.txt,让其能编译到eng下的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(NONE)

FILE(GLOB app_sources src/*.c
src/eng/dev_model/*.c
src/eng/dev_sign/*.c
src/eng/infra/*.c
src/eng/mqtt/*.c
src/eng/wrappers/*.c)
target_sources(app PRIVATE ${app_sources})
zephyr_include_directories(${BOARD_DIR})

zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src/eng/dev_model)
zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src/eng/dev_sign)
zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src/eng/infra)
zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src/eng/mqtt)
zephyr_include_directories(${APPLICATION_SOURCE_DIR}/src/eng/wrappers)

实现wrapper.c

使用zephyr提供的API实现eng/wrappers/wrapper.c要求的函数即可, wrapper.c需求的函数不多,大约是下面几种
1.操作系统函数–封装mutex,time,sleep等函数
2.内存分配函数–封装malloc,free函数
3.TCP函数–封装TCP读写函数
4.标准C封装–printf,随机树等函数
5.device信息–device的name/key/secret/version等
1~4大多实现都是简单封装,这里不做详述。以提交PR到Ali-iotkit,等待merge,可以参考 https://github.com/aliyun/iotkit-embedded/pull/150 ,不过该项目好像不活跃提交了4天还没人review。

Device信息API实现说明

Device信息API有如下几个

1
2
3
4
int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN + 1])
int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN + 1])
int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN + 1])
int HAL_GetProductSecret(char product_secret[IOTX_PRODUCT_SECRET_LEN + 1])

这些是zephyr作为device在aliyun上唯一识别和认证的信息,需要从aliyun上找到并写入这些函数,由这些函数提供给SDK。
在云端需要创建product和device。你可以拥有多个product,每个product下有多个device,例如:
1.智能家居可以做为一个product,这个product下可以有:客厅温湿度device, 卧室温湿度device,厨房燃气device,灯光控制device等等
2.智能大棚可以做为一个product,这product下可以有:玉米大棚device,草莓大棚device,葡萄大棚device等等
aliyun上如何创建product和device不是本篇重点,可参考 https://help.aliyun.com/document_detail/73705.html?spm=a2c4g.11174283.2.1.3a8b1668UuBEFk 进行。
当创建好product和device后,我们看下如何取得上面4个API需要的信息:
product
登录入阿里云物联网平台在”设备管理->产品”下点击查看你的product:
P
在product的详情也中能找到productkey和productsecret:
pd

device
在”设备管理->设备”下点击查看你的device:
d
在device的详情中能找到devicename和devicesecret:
dd

prj.conf修改

zephyr的app中prj.conf中主要是开启TCP/IP和LIBC的支援

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# RX/TX buffer要给得足够大,避免网络通讯出问题
CONFIG_NET_PKT_RX_COUNT=34
CONFIG_NET_PKT_TX_COUNT=34
CONFIG_NET_BUF_RX_COUNT=34
CONFIG_NET_BUF_TX_COUNT=34
CONFIG_NET_CONTEXT_NET_PKT_POOL=y

CONFIG_NET_UDP=y
CONFIG_NET_TCP=y
CONFIG_NET_MAX_CONTEXTS=10

# 移植TCP相关函数使用了socket,因此必须开启socket支援
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_DNS_RESOLVER=y
CONFIG_NET_CONFIG_SETTINGS=y

# 我的环境需要ipv4
CONFIG_NET_IPV4=y
CONFIG_NET_CONFIG_NEED_IPV4=y
CONFIG_NET_DHCPV4=y

# SDK要使用libc函数,开启zephyr libc导入
CONFIG_NEWLIB_LIBC=y

编译

编译方法同一般的zephyr app,编译结果如下

1
2
3
4
5
make -j
Memory region Used Size Region Size %age Used
FLASH: 186277 B 512 KB 35.53%
SRAM: 40724 B 64 KB 62.14%
IDT_LIST: 136 B 2 KB 6.64%

SDK和其中各部分的占比如下

1
2
make rom_report | grep eng
eng 21290 11.43%

按前面的配置可以看到SDK大约占512kx35.53%x11.43%=21K

参考

https://help.aliyun.com/product/93051.html?spm=a2c4g.11186623.6.540.4eb0492bAnxrUX