C Link SDK相关问题

本文介绍编译3.x和2.3.0版本的C Link SDK时,可能遇到的问题和解决方法。

背景信息

如果您尚未接入物联网平台,推荐使用最新版本的SDK。更多信息,请参见概述

SDK如何进行Make编译?

  1. 编写编译配置文件。

    说明

    如果您的环境为Ubuntu或其他Linux发行版,可以先跳过这一步,直接使用SDK内置的配置文件。

    1. 参考文档示例编写配置文件。具体操作,请参见基于Make的交叉编译示例

    2. 将配置文件保存在目录src/board下。

  2. 通过命令选择配置文件并使其生效。

    1. 在SDK根目录下,执行命令make reconfig

    2. 根据环境配置,输入所选文件config.***.***前的序号,再按回车键运行该文件。

    在Ubuntu环境下,运行文件config.ubuntu.x86,日志信息如下所示:

    $ make reconfig
    SELECT A CONFIGURATION:
    1) config.esp8266.aos    4) config.mk3080.aos    7) config.win7.mingw32
    2) config.macos.x86    5) config.rhino.make    8) config.xboard.make
    3) config.mk3060.aos    6) config.ubuntu.x86
    #? 6
    SELECTED CONFIGURATION:
    VENDOR :   ubuntu
    MODEL  :   x86
    CONFIGURE .............................. [examples]
    CONFIGURE .............................. [src/infra/log]
    CONFIGURE .............................. [src/infra/system]
    CONFIGURE .............................. [src/infra/utils]
    CONFIGURE .............................. [src/protocol/alcs]
    CONFIGURE .............................. [src/protocol/coap/cloud]
    CONFIGURE .............................. [src/protocol/coap/local]
    CONFIGURE .............................. [src/protocol/http]
    CONFIGURE .............................. [src/protocol/http2]
    CONFIGURE .............................. [src/protocol/mqtt]
    CONFIGURE .............................. [src/ref-impl/hal]
    CONFIGURE .............................. [src/ref-impl/tls]
    CONFIGURE .............................. [src/sdk-impl]
    CONFIGURE .............................. [src/services/awss]
    CONFIGURE .............................. [src/services/dev_bind]
    CONFIGURE .............................. [src/services/http2_stream]
    CONFIGURE .............................. [src/services/linkkit/cm]
    CONFIGURE .............................. [src/services/linkkit/dev_reset]
    CONFIGURE .............................. [src/services/linkkit/dm]
    CONFIGURE .............................. [src/services/mdal/mal]
    CONFIGURE .............................. [src/services/mdal/sal]
    CONFIGURE .............................. [src/services/ota]
    CONFIGURE .............................. [src/services/shadow]
    CONFIGURE .............................. [src/services/subdev]
    CONFIGURE .............................. [src/tools/linkkit_tsl_convert]
    BUILDING WITH EXISTING CONFIGURATION:
    VENDOR :   ubuntu
    MODEL  :   x86
    Components: 
    . examples                                          
    . src/ref-impl/tls                                          
    . src/ref-impl/hal                                          
    . src/tools/linkkit_tsl_convert                                          
    . src/protocol/mqtt                                          
    . src/protocol/http                                          
    . src/protocol/coap/local                                          
    . src/protocol/coap/cloud                                          
    . src/protocol/http2                                          
    . src/protocol/alcs                                          
    . src/infra/system                                          
    . src/infra/utils                                          
    . src/infra/log                                          
    . src/services/shadow                                          
    . src/services/http2_stream                                          
    . src/services/dev_bind                                          
    . src/services/linkkit/cm                                          
    . src/services/linkkit/dm                                          
    . src/services/linkkit/dev_reset                                          
    . src/services/subdev                                          
    . src/services/mdal/mal                                          
    . src/services/mdal/sal                                          
    . src/services/ota                                          
    . src/services/awss                                          
    . src/sdk-impl
  3. 使用menuconfig工具配置选项。

    1. 在SDK根目录下,执行命令make menuconfig

    2. 在menuconfig工具窗口,根据业务需要,选中要配置的组件。

    3. 选择Save,保存配置。

    4. 按两次退出键,退出menuconfig工具。

  4. 在SDK根目录下,执行命令make,完成编译SDK代码。

编译成功后,会输出什么样的内容?

编译成功后,会打印类似如下的表格。内容包括每个模块的ROM、静态RAM等占用量的统计。

说明

以下示例中的数据仅供参考,请以实际操作为准。

| RATE  | MODULE NAME                         | ROM       | RAM       | BSS        | DATA   |
|-------|-------------------------------------|-----------|-----------|------------|--------|
| 27.5% | src/services/linkkit/dm             | 58954     | 172       | 160        | 12     |
| 19.5% | src/protocol/alcs                   | 41961     | 213       | 189        | 24     |
| 11.3% | src/infra/utils                     | 24335     | 284       | 264        | 20     |
| 10.3% | src/services/awss                   | 22253     | 1012      | 1000       | 12     |
| 9.75% | src/protocol/mqtt                   | 20888     | 32        | 20         | 12     |
| 7.95% | src/services/linkkit/cm             | 17026     | 79        | 79         | 0      |
| 4.46% | src/services/ota                    | 9563      | 0         | 0          | 0      |
| 4.10% | src/services/dev_bind               | 8792      | 214       | 214        | 0      |
| 2.24% | src/infra/system                    | 4801      | 1480      | 1404       | 76     |
| 1.75% | src/sdk-impl                        | 3750      | 8         | 8          | 0      |
| 0.62% | src/infra/log                       | 1334      | 268       | 0          | 268    |
| 0.39% | src/services/dev_reset              | 856       | 10        | 10         | 0      |
|-------|-------------------------------------|-----------|-----------|------------|--------|
|  100% | - IN TOTAL -                        | 214513    | 3772      | 3348       | 424    |

输出文件在哪个目录下?

编译完成后,输出文件在目录output/release下。

哪些输出文件是值得关注的?

以下目录中的这些输出文件值得关注。

  • output/release/lib

    文件名

    说明

    libiot_hal.a

    HAL接口层的参考实现。提供接口HAL_***()。

    libiot_sdk.a

    SDK的主库。提供接口IOT_***和linkkit_xxx()。

    libiot_tls.a

    裁剪过的Mbed TLS。提供接口mbedtls_***(),支撑libiot_hal.a

  • output/release/include

    文件名

    说明

    iot_import.h

    所有需开发者提供给SDK的底层支撑接口。

    iot_export.h

    所有SDK向开发者提供的底层编程接口。

  • output/release/bin

    文件名

    说明

    linkkit-example-solo

    高级例程。可演示linkkit_***()接口的使用。

    mqtt-example

    基础例程。可演示IOT_***()接口的使用。

如何设置交叉编译的Toolchain?

设置交叉编译的Toolchain方法有两种:

  • 单独设置Toolchain的前缀。

  • 单独设置某个工具的前缀。

打开编译配置文件src/borad/config.***.***,按照下面两种方法修改或添加Toolchain。

# 以arm-none-eabi-为例
# 方法1: 设置Toolchian前缀
CROSS_PREFIX        := arm-none-eabi-
# 方法2: 单独设置某个工具链
OVERRIDE_CC            :=    arm-none-eabi-gcc
OVERRIDE_LD            :=    arm-none-eabi-ld
OVERRIDE_AR            :=    arm-none-eabi-ar
OVERRIDE_STRIP      :=  arm-none-eabi-strip
# 注:当交叉工具链没有共有的前缀或者前缀不符合prefix+gcc|ar|strip类型时, 可用如下代码单独指定strip程序不执行,例如armcc没有对应的strip程序
OVERRIDE_STRIP = true

如何添加编译和连接选项?

打开编译配置文件src/borad/config.***.***,分别在CONFIG_ENV_CFLAGS和CONFIG_ENV_LDFLAGS中添加您的编译选项。添加完毕后,运行make reconfig使配置文件生效。

如何编译动态库?

在文件src/borad/config.***.***中,添加CONFIG_LIB_EXPORT := dynamic配置选项。添加完毕后,执行make all命令,进行编译。在目录output/release/lib/下查看动态库。

menuconfig配置保存后,重新进入时,为何仍是默认的选项?

menuconfig每次运行均展示默认配置。若需查看末次配置的具体信息,请使用Load功能,加载已保存的配置文件。

重新配置已保存的menuconfig配置文件,无法加载,该如何自查?

默认名称的配置文件会被清除,请检查保存的配置文件的名称。确保配置文件的名称已修改,且加载的配置文件名称和所在目录是正确的。

如何在配置文件中修改SDK的配置?

在SDK文件src/board/config.***.***中,以CONFIG_ENV_CFLAGS += -D*****的语法新增自定义CFLAGS。其中*****代表具体的宏名称,覆盖SDK中默认的可配置参数。

以下示例代码,在config.***.***文件中,增加参数的定义,配置MQTT的接收Buffer参数等。

CONFIG_ENV_CFLAGS   += \
           -DCONFIG_MQTT_RX_MAXLEN=5000 \
        -DCONFIG_MBEDTLS_DEBUG_LEVEL=0 \

menuconfig出现错误时,常见自查方法有哪些?

2.3.0版本的SDK仅支持Linux环境下进行menuconfig;3.x版本支持Linux、Mac和Windows环境下进行menuconfig。

  • Windows环境:

    执行config.bat脚本。

  • Ubuntu 16.04桌面环境:

  • 其他Linux环境:

    • 请检查您的权限。在Windows环境下解压的文件上传至Linux,可能导致工具出现权限问题。建议在Linux环境,直接下载并解压源码包。

    • 请检查环境变量。您可以通过以下命令,临时添加这两个环境变量。

      export TERMINFO=/usr/share/terminfo
      export TERM=xterm-basic
  • 在非Linux环境下,menuconfig工具目前不支持SDK 2.3.0版本。请直接修改make.settings对应的选项,完成配置。

如何让编译系统屏蔽编译指定模块?

在交叉编译的移植过程中,通常需要手动先屏蔽一些目录不编译。

以目录examples/和HAL默认实现的目录为例,可以在文件src/borad/config.***.***中,增加格式为CONFIG_*****:=的代码来屏蔽相应的目录。其中*****代表相对SDK根目录的路径。

下面是屏蔽目录src/ref-impl/tls/ src/ref-impl/hal/examples/src/tools/linkkit_tsl_convert/下模块的示例代码。

CONFIG_src/ref-impl/tls         :=
CONFIG_src/ref-impl/hal         :=
CONFIG_examples                 :=
CONFIG_src/tools/linkkit_tsl_convert :=

如何通过代码提取功能,从云端下载代码?

为了提高提取代码的速度,SDK脚本默认会根据配置从云端获取代码。若希望在本地代码基础上进行抽取或裁剪,方法如下:

  • Linux或Mac:

    在Link SDK根目录下,执行以下命令:

    cd c-sdk
    ./extract.sh local
  • Windows:

    1. 打开./config.bat文件,将运行脚本代码"%SHELL%" extract.sh修改为"%SHELL%" extract.sh local

    2. 双击执行./config.bat

3.x版本的SDK如何打开日志功能?

3.x版本的SDK默认关闭了日志功能。在编译前,您可以通过不选中Log Configurations配置项中的以下设置,打开日志功能。

开启日志功能

为何设备断电20分钟后,云端才显示离线?

默认情况下,通过配置项CORE_MQTT_DEFAULT_KEEPALIVE_S,Link SDK的云端心跳值为1200s,即20分钟。如果您需要修改心跳间隔时间,可在应用层设置MQTT的配置项,示例代码如下:

 uint16_t keepalive = 60;//数据类型: (uint16_t *) 取值范围: 30 ~ 1200s 默认值: 1200s
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_KEEPALIVE_SEC, &keepalive);

如何设置MQTT连接的配置项?

您可以调用aiot_mqtt_setopt,设置配置项参数。更多信息,请参见aiot_mqtt_option_t

如果在上述信息中,您未找到要设置的配置项,您可以在/core/utils/core_mqtt.h中,找到SDK的默认配置项。

重要

请勿随意更改配置项的值。

/* default configuration */
#define CORE_MQTT_MODULE_NAME                      "MQTT"
#define CORE_MQTT_DEINIT_INTERVAL_MS               (100)

#define CORE_MQTT_DEFAULT_KEEPALIVE_S              (1200)
#define CORE_MQTT_DEFAULT_CLEAN_SESSION            (1)
#define CORE_MQTT_DEFAULT_CONNECT_TIMEOUT_MS       (10 * 1000)
#define CORE_MQTT_DEFAULT_HEARTBEAT_INTERVAL_MS    (25 * 1000)
#define CORE_MQTT_DEFAULT_HEARTBEAT_MAX_LOST_TIMES (2)
#define CORE_MQTT_DEFAULT_SEND_TIMEOUT_MS          (5 * 1000)
#define CORE_MQTT_DEFAULT_RECV_TIMEOUT_MS          (5 * 1000)
#define CORE_MQTT_DEFAULT_REPUB_TIMEOUT_MS         (3 * 1000)
#define CORE_MQTT_DEFAULT_RECONN_ENABLED           (1)
#define CORE_MQTT_DEFAULT_RECONN_INTERVAL_MS       (2 * 1000)
#define CORE_MQTT_DEFAULT_RECONN_RANDLIMIT_MS      (1 * 1000)
#define CORE_MQTT_DEFAULT_RECONN_MAX_COUNTERS      (60)       /*mqtt 断线重连退避算法的最大计数*/
#define CORE_MQTT_DEFAULT_DEINIT_TIMEOUT_MS        (2 * 1000)

#define CORE_MQTT_DIAG_TLV_MQTT_CONNECTION         (0x0010)
#define CORE_MQTT_DIAG_TLV_MQTT_HEARTBEAT          (0x0020)

#define CORE_MQTT_NWKSTATS_RTT_THRESHOLD           (10000)

/* default settings for mqtt 5.0 */
#define CORE_TX_PKT_MAX_LENGTH                      (1024 * 256)
#define CORE_DEFAULT_SERVER_RECEIVE_MAX             (10)
#define CORE_MQTT_USER_PROPERTY_KEY_MAX_LEN         (128)  /* max key length for user property */
#define CORE_MQTT_USER_PROPERTY_VALUE_MAX_LEN       (128)  /* max value length for user property */

如何使用UsernamePassword实现MQTT连云

在一型一密接入方式中,其中免预注册的方式(即设备首次连接物联网平台时,平台自动创建设备身份并下发密钥给设备) 下发的密钥不是Produckey、DeviceName、DeviceSecret,而是ClientId、Username、Password。

对于这种情况,LinkSDK 4.x提供了三个设置选项供设备接入,分别是:AIOT_MQTTOPT_USERNAME, AIOT_MQTTOPT_PASSWORD, AIOT_MQTTOPT_CLIENTID

示例代码如下:

    char *user_name  = "demo_user_name";
    char *password = "demo_passwd";
    char *client_id = "demo_client_id";
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_USERNAME, user_name);
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PASSWORD, password);
    aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_CLIENTID, client_id);

用户再调用aiot_mqtt_connect就可将设备连接至物联网平台。