使用阿里物联网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好用才行啊!