MCU接入阿里物联网平台遇到的各种坑

使用阿里物联网sdk3.2.0

1.cJson相关坑,修改了cJSON_malloc和cJSON_free的指向以后,忘记修改realloc的指向了,结果csjon创建字符串的时候调用了系统的realloc函数,导致一堆问题,创建几次json字符串就卡死了,因为csjon创建字符串是默认realloc指针不为空的话会优先调用realloc,见下面代码的赋值,解决方法就是把static internal_hooks global_hooks = { HAL_Malloc, HAL_Free ,realloc};改成static internal_hooks global_hooks = { HAL_Malloc, HAL_Free };让json创建时去调用我指定的HAL_Malloc。

extern void *HAL_Malloc(uint32_t size);
extern void HAL_Free(void *ptr);
static internal_hooks global_hooks = { HAL_Malloc, HAL_Free ,realloc};

 

2.开启SDK的app配网和本地控制功能后,只能在网关上添加34个设备,添加第35个设备会导致sdk陷入死循环。调试发现是下面这段代码在搞怪,位于CoAPResource_register中的判断,如下

if (ctx->resource.count >= ctx->resource.maxcount) 
{ 
    HAL_MutexUnlock(ctx->resource.list_mutex); 
    COAP_INFO("The resource count exceeds limit, cur %d, max %d", ctx->resource.count, ctx->resource.maxcount); 
    return COAP_ERROR_DATA_SIZE; 
} 

ctx->resource.maxcount设置为255,然后添加第35个设备的时候ctx->resource.count 就已经达到255了,然后返回报错,会导致dm_server_subscribe_all函数陷入无限死循环。目前做法就是直接注释掉,解除限制。

 

3.使用app本地搜索网关时,如果网关刚启动,能够搜索到设备,如果已经运行一段时间了,则搜不到设备了。 原因是sdk使用udp推送设备信息有次数限制,目前宏定义设置120次,我没有去修改宏定义,而是直接把判断做了修改。

#define BIND_NOTIFY_MAX            120
            if (g_context->notify_cnt > BIND_NOTIFY_MAX) {
                break;
            }
            if (g_context->notify_cnt > BIND_NOTIFY_MAX) {
				g_context->notify_cnt=0;
//                break;
            }

4.网关在将子设备推送到云平台上线的时候非常卡,每隔几秒都要卡在将近十几秒,最后排查发现是因为我每隔10秒调用了sdk的获取拓扑关系接口,而由于我在网关上挂载了几十个设备,拓扑关系的报文非常长,大概几万个字节,mcu的性能又不好,所有会导致处理起来非常慢,后来改成只在程序启动的时候读取一次就好了。下面是获取拓扑关系的接口。

IOT_Linkkit_Query(user_example_ctx->master_devid, ITM_MSG_QUERY_TOPOLIST, NULL, 0);

5.由于把sdk移植到了mcu中,所以一些hal接口都必须自己实现,偷懒没有实现HAL_Kv_Get、HAL_Kv_Set、HAL_Kv_Del接口,发现程序也能正常的上线,控制,所以就没去管它。但是后来在调试中发现,如果不实现这几个接口,sdk会由于HAL_Kv_Set失败一直不停的发送thing.lan.prefix.get方法给云平台,设备一多的话每秒都会发送好几次,非常影响正常的功能,所以就把发送的函数屏蔽了,反正我也没有用。 因为事先接口太麻烦了,要把数据写入到mcu的flash中去,而且也没大用,不影响我正常功能就不管他了。

把alcs_mqtt_subdev_prefix_get函数中的__alcs_mqtt_publish(topic, 1, msg_pub, strlen(msg_pub));注释掉就可以了,这个函数是用来发送报文给云平台的。

alcs_mqtt_status_e alcs_mqtt_subdev_prefix_get(const char *product_key, const char *device_name)
{
    /* int ret = 0; */
    char *msg_pub = NULL;
    uint16_t msg_len = 0;
    char topic[ALCS_MQTT_TOPIC_MAX_LEN] = {0};
    alcs_mqtt_ctx_t *ctx =  __alcs_mqtt_get_ctx();
    alcs_mqtt_status_e status = ALCS_MQTT_STATUS_SUCCESS;
    int id = ctx->send_id++;

    if (product_key == NULL || strlen(product_key) > IOTX_PRODUCT_KEY_LEN ||
        device_name == NULL || strlen(device_name) > IOTX_DEVICE_NAME_LEN) {
        return ALCS_MQTT_STATUS_ERROR;
    }

    COAP_INFO("Subdevice, PK: %s, DN: %s\n", product_key, device_name);
    HAL_Snprintf(topic, ALCS_MQTT_TOPIC_MAX_LEN, ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_GET_FMT,
                 ctx->product_key, ctx->device_name);

    msg_len = strlen(ALCS_MQTT_THING_ALCS_SUBDEV_REQUEST) + 10 + strlen(product_key) + strlen(device_name) + 1;
    if ((msg_pub = ALCS_ADAPTER_malloc(msg_len)) == NULL) {
        return ALCS_MQTT_STATUS_ERROR;
    }

    HAL_Snprintf(msg_pub, msg_len, ALCS_MQTT_THING_ALCS_SUBDEV_REQUEST, id,
                 (int)strlen(product_key), product_key, (int)strlen(device_name), device_name);

    COAP_ERR("ALCS Prefix Get, Topic: %s, Payload: %s", topic, msg_pub);
	//zc
//    status = __alcs_mqtt_publish(topic, 1, msg_pub, strlen(msg_pub));

    ALCS_free(msg_pub);

    return status;
}

6.本文所说的问题都是在物联网sdk3.2.0中出现的,这里不得不吐槽一下,阿里的技术支持建议如果是接入生活物联网平台(飞燕平台)的话,使用专用的飞燕版本SDK,但是我下载下来试用了一下,简直太不人性化了,超级不好用。make以后生成的库文件和头文件,我用他们自己的试例代码编译,竟然还报错,头文件找不到,一查发现output文件夹中的头文件竟然不是全部,难道要我自己去源代码一个一个把头文件拿过来用嘛,而且这个sdk竟然不支持裁剪功能,像阿里物联网平台sdk支持功能裁剪,然后生成裁剪后的源代码文件夹,使用起来非常方便,直接把源码加入工程就可以了。而飞燕sdk必须交叉编译成静态库再使用,感觉非常不方便。 自己交叉编译可能会遇到一堆问题不说,keil还得改成gcc编译,又是一堆坑。所以果断不考虑飞燕sdk了。虽然阿里技术一直推荐使用,说是飞燕sdk与生活物联网平台对接功能更加完善,但是至少也得sdk好用才行啊!

你可能感兴趣的:(MCU接入阿里物联网平台遇到的各种坑)