eternal-echo / zigbee-gateway-stm32

0 stars 0 forks source link

[bc26] tcp连接云端后传输数据出错 #8

Closed eternal-echo closed 1 year ago

eternal-echo commented 1 year ago

日志

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

[7645] D/mqtt_adapter: code: -0x0313, [7645.000][L[rx]:

K-0313] MQTT user calls aiot_mq[rx]: OK

tt_connect api, connect

[7660] D/mqtt_adapter: code: -0x032A, [7660.000][LK-032A] mqtt host: hcixxJENrUz.iot-as-mqtt.cn-shanghai.aliyuncs.com

[7672] D/mqtt_adapter: code: -0x0317, [7672.000][LK-0317] user name: coordinator0&hcixxJENrUz

[7681] D/mqtt_adapter: code: -0x0318, [7681.000][LK-0318] password: 28A9EF458ADC6225EC73ABB8273B6522DC0E89301D9C2134EB5688
[7785] D/at_port: [tx]: AT+QIOPEN=0,1,"TCP","hcixxJENrUz.iot-as-mqtt.cn-shanghai.aliyuncs.com",443,0,1

[rx]:

[rx]: OK

[8387] D/at_port: [tx]: AT+QIOPEN=0,1,"TCP","hcixxJENrUz.iot-as-mqtt.cn-shanghai.aliyuncs.com",443,0,1

[rx]:

[rx]: ERROR

[rx]:

[rx]: +QIOPEN: 1,0

[8989] D/at_port: [tx]: AT+QIOPEN=0,1,"TCP","hcixxJENrUz.iot-as-mqtt.cn-shanghai.aliyuncs.com",443,0,1

[rx]:

[rx]: ERROR

[9022] D/at_port: [tx]: AT+QISEND=1,235

[rx]:

[rx]: >
[rx]:

[9048] D/at_port: [tx]: AT+QISEND=1,235

[9321] D/at_port: [tx]: ▒
[rx]:

[rx]: OK

[rx]:

[rx]: SEND OK

[rx]:

id 0, len 63, res 1
[rx]: "

[rx]:

[rx]: +QIURC: "closed",1

[10098] D/at_port: [tx]: ▒
[10101] D/mqtt_adapter: code: -0x1000, [10101.000][LK-1000] adapter_network_deinit

[10126] D/at_port: [tx]: AT+QICLOSE=1

[rx]:

[rx]: ERROR

[10646] D/at_port: [tx]: AT+QICLOSE=1

[rx]:

[rx]: OK

[rx]:

[10669] D/at_port: [tx]: AT+QICLOSE=1

[10673] E/mqtt_adapt[rx]: CLOSE OK

er: aiot_mqtt_connect[rx]:

 failed: -0x0301
[1[rx]: OK

0683] E/m[rx]:

qtt_adapter: demo_mqtt_start failed
[10691] E/APP.tx: mqtt connect failed: -1
[rx]: CLOSE OK

问题

AT+QIOPEN=0,1,"TCP","hcixxJENrUz.iot-as-mqtt.cn-shanghai.aliyuncs.com",443,0,1连接云平台指令的OK未被解析

eternal-echo commented 1 year ago

流程分析

rx

core_at_hal_process函数中,将串口接收到的入参数据复制到缓冲区&at_handle.rsp_buf[at_handle.rsp_buf_offset]中,然后判断是否为urc数据。如果属于响应数据,首先查询是否为一行,是的话就调用core_at_process_line(at_handle.rsp_buf, line_len);进行处理。
core_at_process_line中会把这一行数据写入ringbuffercore_ringbuf_write(&at_handle.rsp_rb, (uint8_t *)line, len);

tx and parse

static int32_t core_at_commands_send_sync(const core_at_cmd_item_t *cmd_list, uint16_t cmd_num)
{
    uint16_t i = 0;
    int32_t res = STATE_SUCCESS;
    uint16_t retry_cnt = AIOT_AT_CMD_RETRY_TIME;

    if (NULL == cmd_list || 0 == cmd_num) {
        return STATE_USER_INPUT_NULL_POINTER;
    }
    os_api->mutex_lock(at_handle.cmd_mutex);
    core_ringbuf_reset(&at_handle.rsp_rb);
    for (; i < cmd_num; i++) {
        /* 发送AT命令 */
        /*
        core_log_hexdump(-1, 1, (unsigned char *)cmd_list[i].cmd, cmd_list[i].cmd_len);
        */
        at_handle.cmd_content = &cmd_list[i];
        res = core_at_uart_tx((uint8_t *)cmd_list[i].cmd, cmd_list[i].cmd_len, at_handle.tx_timeout);
        if (res != cmd_list[i].cmd_len) {
            res = STATE_AT_UART_TX_FAILED;
            break;
        }
        res = core_at_wait_resp(at_handle.cmd_content);
        if (res < 0) {
            if (--retry_cnt > 0) {
                i--;
                continue;
            } else {
                break;
            }
        }

        retry_cnt = AIOT_AT_CMD_RETRY_TIME;
        at_handle.cmd_content = NULL;
        res = STATE_SUCCESS;
    }
    os_api->mutex_unlock(at_handle.cmd_mutex);
    return res;
}

首先reset ringbuffer,然后开始尝试多次发送AT指令。在core_at_wait_resp函数中,需要获取当前ringbuffer可用空间,若可用空间为0,则说明用户没有调用aiot_at_hal_recv_handle接口传输数据到ringbuffer中。那么会选择休眠AIOT_AT_RINGBUF_RETRY_INTERVALms,跳过本次循环,进行第二次尝试。

eternal-echo commented 1 year ago

解决

  1. 增大延迟时间。原先的延迟时间只有5ms,太短。
  2. 修复时间接口bug,由于时间接口的计算有误,导致所有指令都等待一次就超时了,会发送的第二次。同时,时间变量改为static防止编译器优化,避免错误。
  3. 增大发送和连接的等待时间。这两个指令响应时间比较久,设置超时时间为10s