eternal-echo / zigbee-gateway-stm32

0 stars 0 forks source link

[linksdk][at] 串口tx进入trap #11

Closed eternal-echo closed 1 year ago

eternal-echo commented 1 year ago

记录


OK
[10499] D/at_port: [tx]: AT

OK
[11515] D/at_port: [tx]: AT+QSCLK=0

OK
psr: 0x21000000
r00: 0x000003fd
r01: 0x00000031
r02: 0x0800fda9
r03: 0x08034ec9
r04: 0x200034cc
r05: 0x20007d74
r06: 0x0a0d0a0d
r07: 0x00000000
r08: 0x00000000
r09: 0xdeadbeef
r10: 0xdeadbeef
r11: 0x00000000
r12: 0x00000000
 lr: 0x08025639
 pc: 0x0802570e
hard fault on thread: mqtttx

thread   pri  status      sp     stack size max used left tick  error
-------- ---  ------- ---------- ----------  ------  ---------- ---
at_uart_   5  suspend 0x0000008c 0x00000400    28%   0x00000001 000
mqtttx     4  running 0x000001b4 0x00000800    27%   0x00000002 000
zigbeerx  24  suspend 0x000000a8 0x00000200    32%   0x0000000a 000
tshell    20  suspend 0x00000088 0x00001000    03%   0x0000000a 000
tidle0    31  ready   0x00000044 0x00000100    35%   0x00000008 000
main      10  ready   0x00000090 0x00000800    12%   0x00000013 -02
bus fault:
SCB_CFSR_BFSR:0x82 PRECISERR SCB->BFAR:0A0D0A0D

image

eternal-echo commented 1 year ago

定位

问题出现在下面代码中的aiot_mqtt_setopt(ali_handle.mqtt, AIOT_MQTTOPT_HOST, (void *)mqtt_host);中,设置opt时,mqtt handle的接口函数都变0了

int32_t demo_mqtt_start(void **handle)
{
    int32_t     res = STATE_SUCCESS;
    uint16_t    port = 443;      /* 无论设备是否使用TLS连接阿里云平台, 目的端口都是443 */
    aiot_sysdep_network_cred_t cred; /* 安全凭据结构体, 如果要用TLS, 这个结构体中配置CA证书等参数 */

    /* 创建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客户端实例并内部初始化默认参数 */
    ali_handle.mqtt = aiot_mqtt_init();
    if (ali_handle.mqtt == NULL) {
        LOG_E("aiot_mqtt_init failed");
        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(ali_handle.mqtt, AIOT_MQTTOPT_HOST, (void *)mqtt_host);
    /* 配置MQTT服务器端口 */
    aiot_mqtt_setopt(ali_handle.mqtt, AIOT_MQTTOPT_PORT, (void *)&port);
    /* 配置设备productKey */
    aiot_mqtt_setopt(ali_handle.mqtt, AIOT_MQTTOPT_PRODUCT_KEY, (void *)product_key);
    /* 配置设备deviceName */
    aiot_mqtt_setopt(ali_handle.mqtt, AIOT_MQTTOPT_DEVICE_NAME, (void *)device_name);
    /* 配置设备deviceSecret */
    aiot_mqtt_setopt(ali_handle.mqtt, AIOT_MQTTOPT_DEVICE_SECRET, (void *)device_secret);
    /* 配置网络连接的安全凭据, 上面已经创建好了 */
    aiot_mqtt_setopt(ali_handle.mqtt, AIOT_MQTTOPT_NETWORK_CRED, (void *)&cred);
    /* 配置MQTT默认消息接收回调函数 */
    aiot_mqtt_setopt(ali_handle.mqtt, AIOT_MQTTOPT_RECV_HANDLER, (void *)demo_mqtt_default_recv_handler);
    /* 配置MQTT事件回调函数 */
    aiot_mqtt_setopt(ali_handle.mqtt, AIOT_MQTTOPT_EVENT_HANDLER, (void *)demo_mqtt_event_handler);

    /* 与服务器建立MQTT连接 */
    res = aiot_mqtt_connect(ali_handle.mqtt);
    if (res < STATE_SUCCESS) {
        /* 尝试建立连接失败, 销毁MQTT实例, 回收资源 */
        aiot_mqtt_deinit(&ali_handle.mqtt);
        LOG_E("aiot_mqtt_connect failed: -0x%04X", -res);
        return -1;
    }

    /* 创建一个单独的线程, 专用于执行aiot_mqtt_process, 它会自动发送心跳保活, 以及重发QoS1的未应答报文 */
    g_mqtt_process_thread_running = 1;
    g_mqtt_process_thread = rt_thread_create("ali_mqtt_process", demo_mqtt_process_thread, ali_handle.mqtt, 1024, 25, 10);
    if(g_mqtt_process_thread == NULL) {
        LOG_E("rt_thread_create demo_mqtt_process_thread failed: %d", res);
        g_mqtt_process_thread_running = 0;
        aiot_mqtt_deinit(&ali_handle.mqtt);
        return -1;
    }

    /* 创建一个单独的线程用于执行aiot_mqtt_recv, 它会循环收取服务器下发的MQTT消息, 并在断线时自动重连 */
    g_mqtt_recv_thread_running = 1;
    g_mqtt_recv_thread = rt_thread_create("ali_mqtt_recv", demo_mqtt_recv_thread, ali_handle.mqtt, 1024, 10, 10);
    if(g_mqtt_recv_thread == NULL) {
        LOG_E("rt_thread_create demo_mqtt_recv_thread failed: %d", res);
        g_mqtt_recv_thread_running = 0;
        rt_thread_delete(g_mqtt_process_thread);
        aiot_mqtt_deinit(&ali_handle.mqtt);
        return -1;
    }

    *handle = ali_handle.mqtt;

    return RT_EOK;
}
eternal-echo commented 1 year ago

解决

停止使用内存池,rtt的内存池是定长数据申请,不适用不定长的动态申请