更新硬件SDK

This commit is contained in:
kerwincui
2023-03-04 03:44:56 +08:00
parent dcdf6e1b7c
commit e39d3d2f03
1900 changed files with 663153 additions and 0 deletions

View File

@@ -0,0 +1,329 @@
/*
* 这个例程适用于`Linux`这类支持task的POSIX设备, 它演示了用SDK配置MQTT参数并建立连接, 之后创建2个线程
*
* + 一个线程用于保活长连接
* + 一个线程用于接收消息, 并在有消息到达时进入默认的数据回调, 在连接状态变化时进入事件回调
*
* 需要用户关注或修改的部分, 已经用 TODO 在注释中标明
*
*/
#include "common_api.h"
#include <stdio.h>
#include <string.h>
#include "aiot_state_api.h"
#include "aiot_sysdep_api.h"
#include "aiot_mqtt_api.h"
#include "luat_mobile.h"
#include "luat_rtos.h"
#include "luat_debug.h"
/* TODO: 替换为自己设备的三元组 */
char *product_key = "${YourProductKey}";
char *device_name = "${YourDeviceName}";
char *device_secret = "${YourDeviceSecret}";
/*
TODO: 替换为自己实例的接入点
对于企业实例, 或者2021年07月30日之后含当日开通的物联网平台服务下公共实例
mqtt_host的格式为"${YourInstanceId}.mqtt.iothub.aliyuncs.com"
其中${YourInstanceId}: 请替换为您企业/公共实例的Id
对于2021年07月30日之前不含当日开通的物联网平台服务下公共实例
需要将mqtt_host修改为: mqtt_host = "${YourProductKey}.iot-as-mqtt.${YourRegionId}.aliyuncs.com"
其中, ${YourProductKey}请替换为设备所属产品的ProductKey。可登录物联网平台控制台在对应实例的设备详情页获取。
${YourRegionId}:请替换为您的物联网平台设备所在地域代码, 比如cn-shanghai等
该情况下完整mqtt_host举例: a1TTmBPIChA.iot-as-mqtt.cn-shanghai.aliyuncs.com
详情请见: https://help.aliyun.com/document_detail/147356.html
*/
char *mqtt_host = "${YourInstanceId}.mqtt.iothub.aliyuncs.com";
/* 位于portfiles/aiot_port文件夹下的系统适配函数集合 */
extern aiot_sysdep_portfile_t g_aiot_sysdep_portfile;
/* 位于external/ali_ca_cert.c中的服务器证书 */
extern const char *ali_ca_cert;
static luat_rtos_task_handle g_mqtt_process_thread = NULL;
static luat_rtos_task_handle g_mqtt_recv_thread = NULL;
static uint8_t g_mqtt_process_thread_running = 0;
static uint8_t g_mqtt_recv_thread_running = 0;
luat_rtos_semaphore_t net_semaphore_handle;
#define NETSTATUS_NORMAL (0x1)
static luat_rtos_task_handle linksdk_task_handle;
void mobile_event_callback(LUAT_MOBILE_EVENT_E event, uint8_t index, uint8_t status){
if (event == LUAT_MOBILE_EVENT_NETIF && status == LUAT_MOBILE_NETIF_LINK_ON){
LUAT_DEBUG_PRINT("netif acivated");
luat_rtos_semaphore_release(net_semaphore_handle);
}
}
/* TODO: 如果要关闭日志, 就把这个函数实现为空, 如果要减少日志, 可根据code选择不打印
*
* 例如: [1577589489.033][LK-0317] mqtt_basic_demo&gb80sFmX7yX
*
* 上面这条日志的code就是0317(十六进制), code值的定义见core/aiot_state_api.h
*
*/
/* 日志回调函数, SDK的日志会从这里输出 */
int32_t demo_state_logcb(int32_t code, char *message)
{
LUAT_DEBUG_PRINT("linksdk message: %s", message);
return 0;
}
/* MQTT事件回调函数, 当网络连接/重连/断开时被触发, 事件定义见core/aiot_mqtt_api.h */
void demo_mqtt_event_handler(void *handle, const aiot_mqtt_event_t *event, void *userdata)
{
switch (event->type) {
/* SDK因为用户调用了aiot_mqtt_connect()接口, 与mqtt服务器建立连接已成功 */
case AIOT_MQTTEVT_CONNECT: {
LUAT_DEBUG_PRINT("AIOT_MQTTEVT_CONNECT\n");
/* TODO: 处理SDK建连成功, 不可以在这里调用耗时较长的阻塞函数 */
}
break;
/* SDK因为网络状况被动断连后, 自动发起重连已成功 */
case AIOT_MQTTEVT_RECONNECT: {
LUAT_DEBUG_PRINT("AIOT_MQTTEVT_RECONNECT\n");
/* TODO: 处理SDK重连成功, 不可以在这里调用耗时较长的阻塞函数 */
}
break;
/* SDK因为网络的状况而被动断开了连接, network是底层读写失败, heartbeat是没有按预期得到服务端心跳应答 */
case AIOT_MQTTEVT_DISCONNECT: {
char *cause = (event->data.disconnect == AIOT_MQTTDISCONNEVT_NETWORK_DISCONNECT) ? ("network disconnect") :
("heartbeat disconnect");
LUAT_DEBUG_PRINT("AIOT_MQTTEVT_DISCONNECT: %s\n", cause);
/* TODO: 处理SDK被动断连, 不可以在这里调用耗时较长的阻塞函数 */
}
break;
default: {
}
}
}
/* MQTT默认消息处理回调, 当SDK从服务器收到MQTT消息时, 且无对应用户回调处理时被调用 */
void demo_mqtt_default_recv_handler(void *handle, const aiot_mqtt_recv_t *packet, void *userdata)
{
switch (packet->type) {
case AIOT_MQTTRECV_HEARTBEAT_RESPONSE: {
LUAT_DEBUG_PRINT("heartbeat response\n");
/* TODO: 处理服务器对心跳的回应, 一般不处理 */
}
break;
case AIOT_MQTTRECV_SUB_ACK: {
LUAT_DEBUG_PRINT("suback, res: -0x%04X, packet id: %d, max qos: %d\n",
-packet->data.sub_ack.res, packet->data.sub_ack.packet_id, packet->data.sub_ack.max_qos);
/* TODO: 处理服务器对订阅请求的回应, 一般不处理 */
}
break;
case AIOT_MQTTRECV_PUB: {
LUAT_DEBUG_PRINT("pub, qos: %d, topic: %.*s\n", packet->data.pub.qos, packet->data.pub.topic_len, packet->data.pub.topic);
LUAT_DEBUG_PRINT("pub, payload: %.*s\n", packet->data.pub.payload_len, packet->data.pub.payload);
/* TODO: 处理服务器下发的业务报文 */
}
break;
case AIOT_MQTTRECV_PUB_ACK: {
LUAT_DEBUG_PRINT("puback, packet id: %d\n", packet->data.pub_ack.packet_id);
/* TODO: 处理服务器对QoS1上报消息的回应, 一般不处理 */
}
break;
default: {
}
}
}
/* 执行aiot_mqtt_process的线程, 包含心跳发送和QoS1消息重发 */
void *demo_mqtt_process_thread(void *args)
{
int32_t res = STATE_SUCCESS;
while (g_mqtt_process_thread_running) {
res = aiot_mqtt_process(args);
if (res == STATE_USER_INPUT_EXEC_DISABLED) {
break;
}
luat_rtos_task_sleep(1000);
}
luat_rtos_task_delete(g_mqtt_process_thread);
return NULL;
}
/* 执行aiot_mqtt_recv的线程, 包含网络自动重连和从服务器收取MQTT消息 */
void *demo_mqtt_recv_thread(void *args)
{
int32_t res = STATE_SUCCESS;
while (g_mqtt_recv_thread_running) {
res = aiot_mqtt_recv(args);
if (res < STATE_SUCCESS) {
if (res == STATE_USER_INPUT_EXEC_DISABLED) {
break;
}
luat_rtos_task_sleep(1);
}
}
luat_rtos_task_delete(g_mqtt_recv_thread);
return NULL;
}
int linksdk_mqtt_task(void *param)
{
int32_t res = STATE_SUCCESS;
void *mqtt_handle = NULL;
uint16_t port = 443; /* 无论设备是否使用TLS连接阿里云平台, 目的端口都是443 */
aiot_sysdep_network_cred_t cred; /* 安全凭据结构体, 如果要用TLS, 这个结构体中配置CA证书等参数 */
luat_rtos_semaphore_create(&net_semaphore_handle, 1);
luat_mobile_event_register_handler(mobile_event_callback);
luat_rtos_semaphore_take(net_semaphore_handle, LUAT_WAIT_FOREVER);
/* 配置SDK的底层依赖 */
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
/* 配置SDK的日志输出 */
aiot_state_set_logcb(demo_state_logcb);
/* 创建SDK的安全凭据, 用于建立TLS连接 */
memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t));
cred.option = AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA; /* 使用RSA证书校验MQTT服务端 */
cred.max_tls_fragment = 16384; /* 最大的分片长度为16K, 其它可选值还有4K, 2K, 1K, 0.5K */
cred.sni_enabled = 1; /* TLS建连时, 支持Server Name Indicator */
cred.x509_server_cert = ali_ca_cert; /* 用来验证MQTT服务端的RSA根证书 */
cred.x509_server_cert_len = strlen(ali_ca_cert); /* 用来验证MQTT服务端的RSA根证书长度 */
/* 创建1个MQTT客户端实例并内部初始化默认参数 */
mqtt_handle = aiot_mqtt_init();
if (mqtt_handle == NULL) {
LUAT_DEBUG_PRINT("aiot_mqtt_init failed\n");
luat_rtos_task_delete(linksdk_task_handle);
return -1;
}
/* TODO: 如果以下代码不被注释, 则例程会用TCP而不是TLS连接云平台 */
/* {
memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t));
cred.option = AIOT_SYSDEP_NETWORK_CRED_NONE;
} */
/* 配置MQTT服务器地址 */
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_HOST, (void *)mqtt_host);
/* 配置MQTT服务器端口 */
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PORT, (void *)&port);
/* 配置设备productKey */
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PRODUCT_KEY, (void *)product_key);
/* 配置设备deviceName */
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_NAME, (void *)device_name);
/* 配置设备deviceSecret */
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_SECRET, (void *)device_secret);
/* 配置网络连接的安全凭据, 上面已经创建好了 */
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_NETWORK_CRED, (void *)&cred);
/* 配置MQTT默认消息接收回调函数 */
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_RECV_HANDLER, (void *)demo_mqtt_default_recv_handler);
/* 配置MQTT事件回调函数 */
aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_EVENT_HANDLER, (void *)demo_mqtt_event_handler);
/* 与服务器建立MQTT连接 */
res = aiot_mqtt_connect(mqtt_handle);
if (res < STATE_SUCCESS) {
/* 尝试建立连接失败, 销毁MQTT实例, 回收资源 */
aiot_mqtt_deinit(&mqtt_handle);
LUAT_DEBUG_PRINT("aiot_mqtt_connect failed: -0x%04X\n\r\n", -res);
LUAT_DEBUG_PRINT("please check variables like mqtt_host, produt_key, device_name, device_secret in demo\r\n");
luat_rtos_task_delete(linksdk_task_handle);
return -1;
}
/* MQTT 订阅topic功能示例, 请根据自己的业务需求进行使用 */
/* {
char *sub_topic = "/sys/${YourProductKey}/${YourDeviceName}/thing/event/+/post_reply";
res = aiot_mqtt_sub(mqtt_handle, sub_topic, NULL, 1, NULL);
if (res < 0) {
LUAT_DEBUG_PRINT("aiot_mqtt_sub failed, res: -0x%04X\n", -res);
luat_rtos_task_delete(linksdk_task_handle);
return -1;
}
} */
/* MQTT 发布消息功能示例, 请根据自己的业务需求进行使用 */
/* {
char *pub_topic = "/sys/${YourProductKey}/${YourDeviceName}/thing/event/property/post";
char *pub_payload = "{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}";
res = aiot_mqtt_pub(mqtt_handle, pub_topic, (uint8_t *)pub_payload, (uint32_t)strlen(pub_payload), 0);
if (res < 0) {
LUAT_DEBUG_PRINT("aiot_mqtt_sub failed, res: -0x%04X\n", -res);
luat_rtos_task_delete(linksdk_task_handle);
return -1;
}
} */
/* 创建一个单独的线程, 专用于执行aiot_mqtt_process, 它会自动发送心跳保活, 以及重发QoS1的未应答报文 */
g_mqtt_process_thread_running = 1;
luat_rtos_task_create(&g_mqtt_process_thread, 4096, 20, "", demo_mqtt_process_thread, mqtt_handle, NULL);
if (g_mqtt_process_thread == NULL) {
LUAT_DEBUG_PRINT("task_create demo_mqtt_process_thread failed: %d\n", res);
luat_rtos_task_delete(linksdk_task_handle);
return -1;
}
/* 创建一个单独的线程用于执行aiot_mqtt_recv, 它会循环收取服务器下发的MQTT消息, 并在断线时自动重连 */
g_mqtt_recv_thread_running = 1;
luat_rtos_task_create(&g_mqtt_recv_thread, 4096, 20, "", demo_mqtt_recv_thread, mqtt_handle, NULL);
if (g_mqtt_recv_thread == NULL) {
LUAT_DEBUG_PRINT("task_create demo_mqtt_recv_thread failed: %d\n", res);
luat_rtos_task_delete(linksdk_task_handle);
return -1;
}
/* 主循环进入休眠 */
while (1) {
luat_rtos_task_sleep(1000);
}
/* 断开MQTT连接, 一般不会运行到这里 */
g_mqtt_process_thread_running = 0;
g_mqtt_recv_thread_running = 0;
luat_rtos_task_sleep(1);
res = aiot_mqtt_disconnect(mqtt_handle);
if (res < STATE_SUCCESS) {
aiot_mqtt_deinit(&mqtt_handle);
LUAT_DEBUG_PRINT("aiot_mqtt_disconnect failed: -0x%04X\n", -res);
luat_rtos_task_delete(linksdk_task_handle);
return -1;
}
/* 销毁MQTT实例, 一般不会运行到这里 */
res = aiot_mqtt_deinit(&mqtt_handle);
if (res < STATE_SUCCESS) {
LUAT_DEBUG_PRINT("aiot_mqtt_deinit failed: -0x%04X\n", -res);
luat_rtos_task_delete(linksdk_task_handle);
return -1;
}
luat_rtos_task_delete(linksdk_task_handle);
return 0;
}
static void task_demo_init(void)
{
luat_rtos_task_create(&linksdk_task_handle, 4096, 20, "", linksdk_mqtt_task, NULL, NULL);
}
INIT_TASK_EXPORT(task_demo_init, "1");

View File

@@ -0,0 +1,872 @@
/***************
demo_sysdep_api_test
****************/
/*
* 这个例程用于用户在移植后验证是否移植成功的。
* 通过一系列的测试case验证移植的相关接口是否正常工作
* + 正常结束后会输出TEST SUCCESS其它会输出TEST ERROR + ERRORCODE
* + 如遇长时间卡住也为测试失败
*
* 该测试工具会使用多线程/多任务的能力在RTOS下使用需要自行适配任务创建。
* 需要用户关注或修改的部分, 已经用 TODO 在注释中标明
*
*/
#include "common_api.h"
#include "aiot_sysdep_api.h"
#include "aiot_state_api.h"
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "luat_rtos.h"
#include "luat_debug.h"
/* 定义入口函数类型 */
typedef void *(*TASK_FUNC)(void* argv);
/*TODO: 堆最大空间,单位字节 */
#define HEAP_MAX ( 20 * 1024 )
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< TODO END <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
/**
* 系统接口测试结果
*/
typedef enum {
TEST_SUCCESS,
TEST_ERR_RANDOM,
TEST_ERR_MALLOC,
TEST_ERR_HEAP,
TEST_ERR_SLEEP,
TEST_ERR_MUTEX,
TEST_ERR_NETWORK,
TEST_ERR_GENERIC,
} sysdep_test_result_t;
static const char *result_string[] = {
"TEST_SUCCESS",
"TEST_ERR_RANDOM",
"TEST_ERR_MALLOC",
"TEST_ERR_HEAP",
"TEST_ERR_SLEEP",
"TEST_ERR_MUTEX",
"TEST_ERR_NETWORK",
"TEST_ERR_GENERIC",
};
typedef struct {
aiot_sysdep_portfile_t *sysdep;
void* user_data;
char* name;
} task_handler_input_t;
/**
* sysdep测试入口原型定义
*/
typedef sysdep_test_result_t (*sysdep_test_func)(aiot_sysdep_portfile_t* sysdep);
typedef struct
{
uint32_t total_size;//堆总大小
} heap_cfg_t;
typedef struct
{
uint16_t count;
/* 最大重复次数 */
uint16_t repeat_cnt_max;
} random_cfg_t;
typedef struct
{
uint64_t sleep_ms;
uint8_t sleep_end;
} time_cfg_t;
typedef struct
{
void* mutex;
int32_t value;
uint32_t timeout_ms;
} mutex_cfg_t;
typedef struct
{
char* host;
uint16_t port;
uint32_t connect_timeout_ms;
uint32_t recv_timeout_ms;
int32_t recv_buf_len;
uint32_t send_timeout_ms;
uint32_t cycle_test_times;
} network_cfg_t;
static luat_rtos_task_handle sleep_task_handle1;
static luat_rtos_task_handle sleep_task_handle2;
static luat_rtos_task_handle mutex_task_handle1;
static luat_rtos_task_handle mutex_task_handle2;
static luat_rtos_task_handle linksdk_task_handle;
/**
* 随机生成随机数列表,重复出现次数不高于指定值
*/
static sysdep_test_result_t random_repeat_test(aiot_sysdep_portfile_t* sysdep, random_cfg_t* rd)
{
typedef uint8_t random_value_t;
random_value_t *random_values = NULL;
int count = 0;
random_value_t temp = 0;
sysdep_test_result_t ret = TEST_SUCCESS;
/* 差值 */
int diff = 0;
/* 递变标志 */
int flag = 0;
random_values = sysdep->core_sysdep_malloc(sizeof(random_value_t) * rd->count, NULL);
if(random_values == NULL){
LUAT_DEBUG_PRINT("[linksdk]\r\nmalloc fail");
ret = TEST_ERR_MALLOC;
goto end;
}
memset(random_values, 0, sizeof(random_value_t) * rd->count);
/* 生成随机数,并统计重复次数 计算差值*/
for(count = 0; count < rd->count; count++) {
sysdep->core_sysdep_rand((uint8_t*)&temp, sizeof(random_value_t));
temp %= rd->count;
/* 检测是否为规律递变 */
if(count == 1 ){
diff = random_values[count] - random_values[count - 1];
}else if (count >= 2){
if(diff == random_values[count] - random_values[count - 1]){
flag++;
}
}
if(random_values[temp] <= rd->repeat_cnt_max) {
random_values[temp]++;
}
else {
LUAT_DEBUG_PRINT("[linksdk]randowm value [%d] times [%d] over max counter [%d]", temp, random_values[temp], rd->repeat_cnt_max);
ret = TEST_ERR_RANDOM;
goto end;
}
}
/* 规律递变则返回错误 */
if(rd->count >= 3 && flag >= rd->count - 2){
LUAT_DEBUG_PRINT("[linksdk]random value error");
ret = TEST_ERR_RANDOM;
goto end;
}
ret = TEST_SUCCESS;
end:
if(random_values != NULL){
sysdep->core_sysdep_free(random_values);
}
return ret;
}
/**
* 随机数测试入口
*/
sysdep_test_result_t random_test(aiot_sysdep_portfile_t* sysdep)
{
random_cfg_t rd;
/* 随机数接口要求生成的随机数按字节随机 */
rd.count = 256;
/* 随机数重复次数不能超过该值 */
rd.repeat_cnt_max = 10;
return random_repeat_test(sysdep, &rd);
}
static sysdep_test_result_t heap_malloc_max_test(aiot_sysdep_portfile_t* sysdep, heap_cfg_t* hp)
{
/**
* 最大空间申请、释放
*/
uint32_t user_malloc_max = hp->total_size - 100;
void * ptr = sysdep->core_sysdep_malloc(user_malloc_max, "");
if(ptr == NULL) {
LUAT_DEBUG_PRINT("[linksdk]malloc error");
return TEST_ERR_MALLOC;
}
/* 空间读写测试 */
uint8_t read_value;
for(int i = 0; i < user_malloc_max; i++) {
((uint8_t*)ptr)[i] = (uint8_t)i;
read_value = ((uint8_t*)ptr)[i];
if(read_value != (uint8_t)i) {
sysdep->core_sysdep_free(ptr);
LUAT_DEBUG_PRINT("[linksdk]heap read and write fail");
return TEST_ERR_MALLOC;
}
}
sysdep->core_sysdep_free(ptr);
return TEST_SUCCESS;
}
/**
* 堆回收测试
*/
static sysdep_test_result_t heap_recycle_test(aiot_sysdep_portfile_t* sysdep, heap_cfg_t* hp)
{
/* 待申请的堆空间大小 */
const uint32_t size_list[]= {1,2,4,8,16,32,64,128,256,512,1024,10*1024};
/* 存储堆指针 */
void* malloc_list[sizeof(size_list) / sizeof(uint32_t)] = {NULL};
int malloc_list_size = sizeof(size_list) / sizeof(uint32_t);
/* 申请空间 */
int malloc_cnt = 0;
int i = 0;
for(i = 0; i < malloc_list_size; i++) {
malloc_list[i] = sysdep->core_sysdep_malloc(size_list[i], "");
if(malloc_list[i] == NULL) {
break;
}
}
malloc_cnt = i;
/**
* 非相邻空间释放
*/
for(i = 0; i < malloc_cnt; i+=2) {
sysdep->core_sysdep_free(malloc_list[i]);
}
for(i = 1; i < malloc_cnt; i+=2) {
sysdep->core_sysdep_free(malloc_list[i]);
}
/**
* 最后申请最大空间
*/
return heap_malloc_max_test(sysdep, hp);
}
/**
* 堆测试入口
*/
sysdep_test_result_t heap_test(aiot_sysdep_portfile_t* sysdep)
{
sysdep_test_result_t ret = TEST_SUCCESS;
heap_cfg_t hp;
hp.total_size = HEAP_MAX;
ret = heap_malloc_max_test(sysdep,&hp);
if(ret != TEST_SUCCESS) {
return ret;
}
return heap_recycle_test(sysdep, &hp);
}
static sysdep_test_result_t network_tcp_test(aiot_sysdep_portfile_t* sysdep, network_cfg_t* cfg)
{
void* network_hd = sysdep->core_sysdep_network_init();
core_sysdep_socket_type_t type = CORE_SYSDEP_SOCKET_TCP_CLIENT;
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_SOCKET_TYPE, &type);
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_HOST, cfg->host);
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_PORT, (void*)&cfg->port);
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_CONNECT_TIMEOUT_MS, &cfg->connect_timeout_ms);
/**
* 建连测试
*/
if(0 != sysdep->core_sysdep_network_establish(network_hd)) {
LUAT_DEBUG_PRINT("[linksdk]network establish test error:%d", TEST_ERR_NETWORK);
return TEST_ERR_NETWORK;
}
/**
* 接收等待超时测试
*/
char* buf = sysdep->core_sysdep_malloc(cfg->recv_buf_len + 1, "");
if(buf == NULL){
LUAT_DEBUG_PRINT("[linksdk]malloc fail");
return TEST_ERR_MALLOC;
}
uint64_t start = sysdep->core_sysdep_time();
sysdep->core_sysdep_network_recv(network_hd, (uint8_t*)buf, cfg->recv_buf_len, cfg->recv_timeout_ms, NULL);
uint64_t stop = sysdep->core_sysdep_time();
if(stop - start < cfg->recv_timeout_ms) {
LUAT_DEBUG_PRINT("[linksdk]network receive test error:%d, start [%ld], end [%ld]", TEST_ERR_NETWORK, start, stop);
return TEST_ERR_NETWORK;
}
/**
* 通过Http Get请求来验证TCP是否工作正常
*/
char* http_get = "GET / HTTP/1.1\r\n"\
"Host: www.aliyun.com\r\n"\
"Connection: keep-alive\r\n"\
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36\r\n"\
"Origin: https://www.aliyun.com\r\n"\
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n"\
"\r\n";
int32_t send_len = strlen(http_get);
int32_t send_result = sysdep->core_sysdep_network_send(network_hd, (uint8_t*)http_get, send_len, cfg->send_timeout_ms, NULL);
if(send_result != send_len) {
LUAT_DEBUG_PRINT("[linksdk]network send length test error:%d, send [%d], result [%d]", TEST_ERR_NETWORK, send_len, send_result);
return TEST_ERR_NETWORK;
}
int32_t buf_len = 0;
uint8_t byte_read;
int32_t content_len = 0;
int32_t ret;
char* str_ptr = NULL;
char* target_str = "Content-Length:";
int state = 0;
while(1) {
ret = sysdep->core_sysdep_network_recv(network_hd, (uint8_t*)&byte_read, 1, cfg->recv_timeout_ms, NULL);
/* 需支持按字节读取 */
if(ret == 1) {
if(state == 0) {
/* 提取一行 */
buf[buf_len++] = byte_read;
if(byte_read != '\n') {
continue;
}
buf[buf_len] = '\0';
/*空行表示header结束*/
if(buf_len == 2 && buf[0] == '\r' && buf[1] == '\n') {
state = 1;
buf_len = 0;
continue;
}
/*搜索应答长度*/
str_ptr = strstr(buf,target_str);
if(str_ptr == NULL) {
buf_len = 0;
continue;
}
str_ptr += strlen(target_str);
if(str_ptr >= &buf[buf_len]) {
buf_len = 0;
continue;
}
if( 1 == sscanf(str_ptr,"%d",&content_len)) {
buf_len = 0;
}
} else {
buf[buf_len++] = byte_read;
}
}
else {
break;
}
}
sysdep->core_sysdep_network_deinit(&network_hd);
sysdep->core_sysdep_free(buf);
buf = NULL;
if(network_hd != NULL){
LUAT_DEBUG_PRINT("[linksdk]network deinit error");
return TEST_ERR_NETWORK;
}
/* http的正文长度校验 */
if(buf_len == 0 || buf_len != content_len) {
LUAT_DEBUG_PRINT("[linksdk][NETWORK_TEST.RECV] test error:%d, send [%d], result [%d]", TEST_ERR_NETWORK, buf_len, content_len);
return TEST_ERR_NETWORK;
} else {
LUAT_DEBUG_PRINT("[linksdk][NETWORK_TEST.RECV] test success");
return TEST_SUCCESS;
}
}
sysdep_test_result_t network_tcp_cycle_test(aiot_sysdep_portfile_t* sysdep, network_cfg_t* cfg)
{
void* network_hd = NULL;
int count = cfg->cycle_test_times;
while(count-- > 0) {
network_hd = sysdep->core_sysdep_network_init();
if(network_hd == NULL) {
LUAT_DEBUG_PRINT("[linksdk]network tcp init test error");
return TEST_ERR_NETWORK;
}
core_sysdep_socket_type_t type = CORE_SYSDEP_SOCKET_TCP_CLIENT;
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_SOCKET_TYPE, &type);
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_HOST, cfg->host);
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_PORT, (void*)&cfg->port);
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_CONNECT_TIMEOUT_MS, &cfg->connect_timeout_ms);
if(0 != sysdep->core_sysdep_network_establish(network_hd)) {
LUAT_DEBUG_PRINT("[linksdk]network tcp establish test error:%d", TEST_ERR_NETWORK);
return TEST_ERR_NETWORK;
}
sysdep->core_sysdep_network_deinit(&network_hd);
}
if( TEST_SUCCESS != heap_test(sysdep) ) {
LUAT_DEBUG_PRINT("[linksdk]network deinit then heap test error:%d", TEST_ERR_NETWORK);
return TEST_ERR_NETWORK;
} else {
return TEST_SUCCESS;
}
}
static sysdep_test_result_t network_tcp_send_length_test(aiot_sysdep_portfile_t* sysdep, network_cfg_t* cfg)
{
sysdep_test_result_t ret = TEST_SUCCESS;
void* network_hd = sysdep->core_sysdep_network_init();
core_sysdep_socket_type_t type = CORE_SYSDEP_SOCKET_TCP_CLIENT;
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_SOCKET_TYPE, &type);
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_HOST, cfg->host);
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_PORT, (void*)&cfg->port);
sysdep->core_sysdep_network_setopt(network_hd, CORE_SYSDEP_NETWORK_CONNECT_TIMEOUT_MS, &cfg->connect_timeout_ms);
/**
* 建连测试
*/
if(0 != sysdep->core_sysdep_network_establish(network_hd)) {
LUAT_DEBUG_PRINT("[linksdk]network establish test error:%d", TEST_ERR_NETWORK);
return TEST_ERR_NETWORK;
}
/**
* 通过Http Get请求来验证TCP发送接口是否具备长包发送能力
*/
const char* http_get = "GET / HTTP/1.1\r\n"\
"Host: www.aliyun.com\r\n"\
"Connection: keep-alive\r\n"\
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36\r\n"\
"Origin: https://www.aliyun.com\r\n"\
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n"\
"\r\n"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,"\
"invalid test append data,invalid test append data,invalid test append data,invalid test append data,";
int32_t send_len = strlen(http_get);
int32_t send_result = sysdep->core_sysdep_network_send(network_hd, (uint8_t*)http_get, send_len, cfg->send_timeout_ms, NULL);
if(send_result != send_len) {
LUAT_DEBUG_PRINT("[linksdk]network send length test error:%d, send [%d], result [%d]", TEST_ERR_NETWORK, send_len, send_result);
ret = TEST_ERR_NETWORK;
}
sysdep->core_sysdep_network_deinit(&network_hd);
return ret;
}
sysdep_test_result_t network_test(aiot_sysdep_portfile_t* sysdep)
{
sysdep_test_result_t ret;
sysdep->core_sysdep_sleep(100);
network_cfg_t cfg;
cfg.host = "www.aliyun.com";
cfg.port = 80;
cfg.connect_timeout_ms = 5000;
cfg.recv_timeout_ms = 5000;
cfg.recv_buf_len = 1024;
cfg.send_timeout_ms = 5000;
cfg.cycle_test_times = 10;
ret = network_tcp_test(sysdep, &cfg);
if(ret != TEST_SUCCESS) {
return ret;
}
ret = network_tcp_send_length_test(sysdep,&cfg);
if(ret != TEST_SUCCESS){
return ret;
}
ret = network_tcp_cycle_test(sysdep, &cfg);
return ret;
}
static void enter_sleep1(void* user_data)
{
task_handler_input_t* user = (task_handler_input_t*)user_data;
time_cfg_t* tm = user->user_data;
LUAT_DEBUG_PRINT("[linksdk]%s enter wanna sleep: %ldms", user->name, tm->sleep_ms);
user->sysdep->core_sysdep_sleep(tm->sleep_ms);
tm->sleep_end = 1;
luat_rtos_task_delete(sleep_task_handle1);
return 0;
}
static void enter_sleep2(void* user_data)
{
task_handler_input_t* user = (task_handler_input_t*)user_data;
time_cfg_t* tm = user->user_data;
LUAT_DEBUG_PRINT("[linksdk]%s enter wanna sleep: %ldms", user->name, tm->sleep_ms);
user->sysdep->core_sysdep_sleep(tm->sleep_ms);
tm->sleep_end = 1;
luat_rtos_task_delete(sleep_task_handle2);
return 0;
}
sysdep_test_result_t time_sleep_test(aiot_sysdep_portfile_t* sysdep)
{
uint64_t start,stop;
time_cfg_t time_cfg;
sysdep_test_result_t ret= TEST_SUCCESS;
time_cfg_t* sleep1 = NULL;
time_cfg_t* sleep2 = NULL;
task_handler_input_t input1;
task_handler_input_t input2;
int64_t wait_total;
uint64_t temp;
time_cfg.sleep_ms = 10 * 1000;
LUAT_DEBUG_PRINT("[linksdk]sleep %ldms test",time_cfg.sleep_ms);
start = sysdep->core_sysdep_time();
sysdep->core_sysdep_sleep(time_cfg.sleep_ms);
stop = sysdep->core_sysdep_time();
LUAT_DEBUG_PRINT("[linksdk]sleep start %ld stop %ld ms test",start,stop);
/* 睡眠异常 */
if((stop - start) * 1.1 < time_cfg.sleep_ms) {
LUAT_DEBUG_PRINT("[linksdk]sleep test error: %d",TEST_ERR_SLEEP);
ret = TEST_ERR_SLEEP;
goto end;
}
/* 睡眠时间超过10% */
if(stop - start > (uint64_t)(time_cfg.sleep_ms * 1.1)) {
LUAT_DEBUG_PRINT("[linksdk]sleep test error: %d",TEST_ERR_SLEEP);
ret = TEST_ERR_SLEEP;
goto end;
}
/**
* 并发睡眠测试,两个并发睡眠消耗的时间应小于两次睡眠时间之和
*/
sleep1 = sysdep->core_sysdep_malloc(sizeof(time_cfg_t),"");
sleep2 = sysdep->core_sysdep_malloc(sizeof(time_cfg_t),"");
if(sleep1 == NULL || sleep2 == NULL){
ret = TEST_ERR_SLEEP;
goto end;
}
sleep1->sleep_ms = 10 * 1000;
sleep1->sleep_end = 0;
sleep2->sleep_ms = 10 * 1000;
sleep2->sleep_end = 0;
input1.name = "sleep_test_task_1";
input1.sysdep = sysdep;
input1.user_data = sleep1;
input2.name = "sleep_test_task_2";
input2.sysdep = sysdep;
input2.user_data = sleep2;
start = sysdep->core_sysdep_time();
luat_rtos_task_create(&sleep_task_handle1, 1024, 20, "", enter_sleep1, &input1, NULL);
luat_rtos_task_create(&sleep_task_handle2, 1024, 20, "", enter_sleep2, &input2, NULL);
/**
* 等待睡眠结束
*/
wait_total = sleep1->sleep_ms + sleep2->sleep_ms + 100;
while((sleep1->sleep_end == 0 || sleep2->sleep_end == 0) && wait_total-- > 0) {
sysdep->core_sysdep_sleep(1);
}
/**
* 检查所有线程是否都退出
*/
while (sleep1->sleep_end == 0 || sleep2->sleep_end == 0){
sysdep->core_sysdep_sleep(1);
}
/* 两个线程应该在规定时间内退出 */
if(wait_total < 0) {
LUAT_DEBUG_PRINT("[linksdk]concurrent sleep test error: wait sleep timeout fail");
ret = TEST_ERR_SLEEP;
goto end;
}
/* 总睡眠时间应小于各睡眠时间之和 */
stop = sysdep->core_sysdep_time();
temp = sleep1->sleep_ms + sleep2->sleep_ms;
if(stop - start >= temp) {
LUAT_DEBUG_PRINT("[linksdk]sleep %ldms start:[%ld] stop:[%ld]\r\n unexpected ", sleep1->sleep_ms, start, stop);
ret = TEST_ERR_SLEEP;
}
else {
LUAT_DEBUG_PRINT("[linksdk]sleep %ldms start:[%ld] stop:[%ld] expected ", sleep1->sleep_ms, start, stop);
ret = TEST_SUCCESS;
}
end:
if(sleep1 != NULL)
sysdep->core_sysdep_free(sleep1);
if(sleep2 != NULL)
sysdep->core_sysdep_free(sleep2);
return ret;
}
static void mutex_synchronize_test1(void* user_data)
{
task_handler_input_t* input = (task_handler_input_t*)user_data;
mutex_cfg_t* cfg = input->user_data;
while(1) {
input->sysdep->core_sysdep_mutex_lock(cfg->mutex);
if(cfg->value < 0) {
input->sysdep->core_sysdep_mutex_unlock(cfg->mutex);
break;
}
cfg->value++;
input->sysdep->core_sysdep_mutex_unlock(cfg->mutex);
input->sysdep->core_sysdep_sleep(cfg->timeout_ms);
}
luat_rtos_task_delete(mutex_task_handle1);
return NULL;
}
static void mutex_synchronize_test2(void* user_data)
{
task_handler_input_t* input = (task_handler_input_t*)user_data;
mutex_cfg_t* cfg = input->user_data;
while(1) {
input->sysdep->core_sysdep_mutex_lock(cfg->mutex);
if(cfg->value < 0) {
input->sysdep->core_sysdep_mutex_unlock(cfg->mutex);
break;
}
cfg->value++;
input->sysdep->core_sysdep_mutex_unlock(cfg->mutex);
input->sysdep->core_sysdep_sleep(cfg->timeout_ms);
}
luat_rtos_task_delete(mutex_task_handle2);
return NULL;
}
/**
* 互斥锁测试
*/
sysdep_test_result_t mutex_test(aiot_sysdep_portfile_t* sysdep)
{
sysdep_test_result_t ret;
void* mutex = NULL;
mutex_cfg_t *mutex_cfg_2 = NULL;
task_handler_input_t *input_1 = NULL;
task_handler_input_t *input_2 = NULL;
int32_t wait_ms = 3000;
/**
* 互斥锁申请释放及内存泄漏测试
*/
for(int i = 0; i < 1000; i++) {
mutex = sysdep->core_sysdep_mutex_init();
sysdep->core_sysdep_mutex_lock(mutex);
sysdep->core_sysdep_mutex_unlock(mutex);
sysdep->core_sysdep_mutex_deinit(&mutex);
}
if( TEST_SUCCESS != heap_test(sysdep)) {
LUAT_DEBUG_PRINT("[linksdk][MUTEX_TEST.CYCLE] test failed\r\n");
return ret = TEST_ERR_MUTEX;
}
/**
* 互斥锁功能测试
*/
mutex_cfg_t *mutex_cfg_1 = sysdep->core_sysdep_malloc(sizeof(mutex_cfg_t), "");
if(mutex_cfg_1 == NULL) {
LUAT_DEBUG_PRINT("[linksdk]mutex test but malloc fail");
ret = TEST_ERR_MUTEX;
goto end;
}
mutex_cfg_1->mutex = sysdep->core_sysdep_mutex_init();
if(mutex_cfg_1->mutex == NULL) {
ret = TEST_ERR_MALLOC;
LUAT_DEBUG_PRINT("[linksdk][MUTEX_TEST]malloc fail:%d", ret);
goto end;
}
input_1 = sysdep->core_sysdep_malloc(sizeof(task_handler_input_t), "");
if(input_1 == NULL){
LUAT_DEBUG_PRINT("[linksdk]mutex test but malloc fail");
ret = TEST_ERR_MALLOC;
goto end;
}
input_1->name = "mutex_test_task1";
input_1->sysdep = sysdep;
input_1->user_data = mutex_cfg_1;
mutex_cfg_1->timeout_ms = 100;
mutex_cfg_1->value = 0;
luat_rtos_task_create(&mutex_task_handle1, 1024, 20, "", mutex_synchronize_test1, input_1, NULL);
mutex_cfg_2 = sysdep->core_sysdep_malloc(sizeof(mutex_cfg_t), "");
if(mutex_cfg_2 == NULL) {
ret = TEST_ERR_MALLOC;
LUAT_DEBUG_PRINT("[linksdk][MUTEX_TEST]malloc fail:%d", ret);
goto end;
}
mutex_cfg_2->mutex = sysdep->core_sysdep_mutex_init();
if(mutex_cfg_2->mutex == NULL) {
ret = TEST_ERR_MALLOC;
LUAT_DEBUG_PRINT("[linksdk][MUTEX_TEST]malloc fail:%d", ret);
goto end;
}
input_2 = sysdep->core_sysdep_malloc(sizeof(task_handler_input_t), "");
input_2->name = "mutex_test_task2";
input_2->sysdep = sysdep;
input_2->user_data = mutex_cfg_2;
mutex_cfg_2->timeout_ms = 100;
mutex_cfg_2->value = 0;
luat_rtos_task_create(&mutex_task_handle2, 1024, 20, "", mutex_synchronize_test2, input_2, NULL);
sysdep->core_sysdep_sleep(wait_ms);
/**
* 对mutex_cfg_1->mutex加锁mutex_test_task1会被锁住mutex_cfg_1->value应该不会发生变化
*/
int32_t v1,v2;
LUAT_DEBUG_PRINT("[linksdk]mutex lock task1, unlock task2 %d ms", wait_ms);
sysdep->core_sysdep_mutex_lock(mutex_cfg_1->mutex);
v1 = mutex_cfg_1->value;
v2 = mutex_cfg_2->value;
sysdep->core_sysdep_sleep(wait_ms);
int32_t v1_,v2_;
v1_ = mutex_cfg_1->value;
v2_ = mutex_cfg_2->value;
LUAT_DEBUG_PRINT("[linksdk]task1 value [%d --> %d], task2 value [%d --> %d] ", v1, v1_, v2, v2_);
if(v1 != v1_ || v2 == v2_) {
LUAT_DEBUG_PRINT("[linksdk]mutex test failed ");
ret = TEST_ERR_MUTEX;
goto end;
}
sysdep->core_sysdep_mutex_unlock(mutex_cfg_1->mutex);
/**
* 对mutex_cfg_2->mutex加锁mutex_test_task2会被锁住mutex_cfg_2->value应该不会发生变化
*/
LUAT_DEBUG_PRINT("[linksdk]unlock task1, lock task2 %d ms", wait_ms);
sysdep->core_sysdep_mutex_lock(mutex_cfg_2->mutex);
v1 = mutex_cfg_1->value;
v2 = mutex_cfg_2->value;
sysdep->core_sysdep_sleep(wait_ms);
v1_ = mutex_cfg_1->value;
v2_ = mutex_cfg_2->value;
LUAT_DEBUG_PRINT("[linksdk]task1 value [%d --> %d], task2 value [%d --> %d] ", v1, v1_, v2, v2_);
if(v1 == v1_ || v2 != v2_) {
LUAT_DEBUG_PRINT("[linksdk]mutex test failed");
ret = TEST_ERR_MUTEX;
goto end;
}
sysdep->core_sysdep_mutex_unlock(mutex_cfg_2->mutex);
/**
* mutex_cfg_2->mutex不加锁mutex_cfg_1->mutex不加锁对应value应该正常变化
*/
LUAT_DEBUG_PRINT("[linksdk]unlock task1, lock task2 %d ms\r\n", wait_ms);
v1 = mutex_cfg_1->value;
v2 = mutex_cfg_2->value;
sysdep->core_sysdep_sleep(wait_ms);
v1_ = mutex_cfg_1->value;
v2_ = mutex_cfg_2->value;
LUAT_DEBUG_PRINT("[linksdk]task1 value [%d --> %d], task2 value [%d --> %d]\r\n", v1, v1_, v2, v2_);
if(v1 == v1_ || v2 == v2_) {
LUAT_DEBUG_PRINT("[linksdk][MUTEX_TEST.UNLOCK] test failed \r\n");
ret = TEST_ERR_MUTEX;
goto end;
}
end:
/**
* 线程退出,回归
*/
if(mutex_cfg_1 != NULL) {
mutex_cfg_1->value = -10;
sysdep->core_sysdep_sleep(500);
if(mutex_cfg_1->mutex != NULL){
sysdep->core_sysdep_mutex_deinit(&(mutex_cfg_1->mutex));
}
sysdep->core_sysdep_free(mutex_cfg_1);
}
if(mutex_cfg_2 != NULL){
mutex_cfg_2->value = -10;
sysdep->core_sysdep_sleep(500);
if(mutex_cfg_2->mutex != NULL){
sysdep->core_sysdep_mutex_deinit(&(mutex_cfg_2->mutex));
}
sysdep->core_sysdep_free(mutex_cfg_2);
}
if(input_1 != NULL){
sysdep->core_sysdep_free(input_1);
}
if(input_2 != NULL){
sysdep->core_sysdep_free(input_2);
}
return TEST_SUCCESS;
}
typedef struct {
char* name;
sysdep_test_func func;
} sysdep_test_suite;
/**
* 测试项列表
*/
sysdep_test_suite test_list[]= {
{"RANDOM_TEST ", random_test},
{"HEAP_TEST ", heap_test},
{"TIME_TEST ", time_sleep_test},
{"NETWORK_TEST", network_test},
{"MUTEX_TEST ", mutex_test},
};
/**
* sysdep的接口实现包含系统时间、内存管理、网络、锁、随机数、等接口实现
*/
extern aiot_sysdep_portfile_t g_aiot_sysdep_portfile;
static void demo_sysdep_api_test(void *param)
{
luat_rtos_task_sleep(1000);
aiot_sysdep_portfile_t *sysdep = &g_aiot_sysdep_portfile;
int32_t size = sizeof(test_list) / sizeof(test_list[0]);
sysdep_test_result_t ret = TEST_SUCCESS;
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
LUAT_DEBUG_PRINT("[linksdk]TOTAL TEST START");
for(int32_t i = 0; i < size; i++) {
LUAT_DEBUG_PRINT("[linksdk]TEST [%d/%d] [%s] .....................................[START]", i + 1, size, test_list[i].name);
ret = (test_list[i].func)(sysdep);
if(TEST_SUCCESS != ret) {
LUAT_DEBUG_PRINT("[linksdk]TEST [%d/%d] [%s] .....................................[FAILED] [%s]", i + 1, size, test_list[i].name, result_string[ret]);
break;
} else {
LUAT_DEBUG_PRINT("[linksdk]TEST [%d/%d] [%s] .....................................[SUCCESS]", i + 1, size, test_list[i].name);
}
}
if(ret == TEST_SUCCESS) {
LUAT_DEBUG_PRINT("[linksdk]TOTAL TEST SUCCESS");
} else {
LUAT_DEBUG_PRINT("[linksdk]TOTAL TEST FAILED %s", result_string[ret]);
}
luat_rtos_task_delete(linksdk_task_handle);
}
static void task_demo_init(void)
{
luat_rtos_task_create(&linksdk_task_handle, 4096, 20, "", demo_sysdep_api_test, NULL, NULL);
}
INIT_TASK_EXPORT(task_demo_init, "1");