phy62xx开发-AT例程串口操作

Viewed 14

串口的数据接收和AT命令的解析程序入口:components\libraries\cli\ble_at_module.c

串口接收中断函数

components\libraries\cli\ble_at_module.c->AT_UART_IRQHandler,在这里解析判断串口数据是AT命令还是普通数据。符合cmdstr[0] == 'A' && cmdstr[1] == 'T' && (cmdstr[cmdlen-3] == '\r') && (cmdstr[cmdlen-2] == '\n') && (cmdstr[cmdlen-1] == '\0')这个条件的都认为是AT命令,如果是AT命令则通过事件AT_PROCESS_UART_RX_CMD_EVT发布出来,如果不是则通过事件AT_PROCESS_TRANSPARENT_SEND发布出来做蓝牙转发。

AT命令处理

1) 预处理

收到串口数据后,长度先减3,去掉\r\n\03个字节,然后原始数据结尾处理t_str[t_len] = '\0';,如下处理

        if (t_len != 0)
        {
            t_len -= 3;
            t_str[t_len] = '\0';
            for (size_t i = 0; i < strlen(t_str); i++)
            {
                log_printf("%02X ", t_str[i]);
            }
            log_printf("\n");
            
            int sta = CLI_process_line_manual(
                        t_str,
                        t_len);
        }

2) 数据分拆

在函数components\libraries\cli\cliface.c->CLI_process_line_manual中解析命令的属性,提取携带的参数。
根据命令的格式,先提取属性值放在argvargv[0]中,携带的第一个参数放在argv[1]中,如下处理:

            if ((*cmd == '=') || (*cmd == ':'))
            {
                argv[argc++] = cmd;
                argv[argc++] = (cmd + 1);
            }

后续其他参数根据分隔符((' ' == (ch)) || ('\t' == (ch)) || ('\r' == (ch)) || ('\n' == (ch)) || (',' == (ch)))来解析分拆出来分别存放在argv中,处理如下:

        else if ('\0' == (*(cmd - 1)))
        {
            argv[argc++] = cmd;
        }

3) 命令匹配

在这里循环判断命令,匹配上对应的命令后,调用g_cli_cmd_list[index].cmd_hdlr(argc, argv)执行对应的方法,这些方法定义在example\ble_peripheral\VG7346T240N0S1-SWPRJ\source\at_ble_cmd.c->ble_at_cmd_list

    for (index = 0; index < g_cli_cmd_len; index++)
    {
        if (0 == memcmp(buffer, g_cli_cmd_list[index].cmd, strlen(g_cli_cmd_list[index].cmd)) && atNameLen==strlen(g_cli_cmd_list[index].cmd))
        {
            // AT_LOG("-- match at fun --\r\n");
            uint8_t atType = CMDT_NONE;
            char typeName[][20] = {"NONE","TEST","READ","WRITE","EXECUTE"};
            if(argv[0][0] == '=' && argv[1][0] != '?' && argv[1][0] != '\0')
            {
                atType = CMDT_WRITE;
            }
            else if(argv[0][0] == '=' && argv[1][0] == '?' && argv[1][1] == '\0')
            {
                atType = CMDT_READ;
            }
            else if(argv[0][0] == '\0' || argc == 0)
            {
                atType = CMDT_EXECUTE;
            }
            else if(argv[0][0] == '?')
            {
                atType = CMDT_TEST;
            }
            else
            {
                matchflag = 0;
            }
            log_printf("argc=%d\r\n", argc);
            log_printf("argv[0][0]=%c(%02X) argv[1][0]=%c(%02X) argv[1][1]=%c(%02X)\r\n", argv[0][0], argv[0][0], argv[1][0], argv[1][0], argv[1][1], argv[1][1]);
            log_printf("atType (%d)= %s\r\n", atType, typeName[atType]);
            if (atType)
            {
                log_printf("match AT=%s\r\n", g_cli_cmd_list[index].cmd);
                g_cli_cmd_list[index].cmd_hdlr(atType, argc, argv);
                matchflag = 1;
                break;
            }
        }
    }

4) 命令处理

如下

static uint16_t at_set_advint(uint8_t at_type, uint32_t argc, unsigned char *argv[])
{
    // argv[1]为第一个参数,以此类推,`,`为分隔符
    switch (at_type)
    {
        case CMDT_TEST:
        {

        }break;
        case CMDT_READ:
        {

        }break;
        case CMDT_WRITE:
        {

        }break;
        case CMDT_EXECUTE:
        {

        }break;
    
    default:
      break;
    }
}
0 Answers
Related