查看: 979|回复: 0

[技术交流] Wi-Fi SOC AT指令通信源码分析和实例分析(3)

[复制链接]

185

主题

204

帖子

596

积分

利尔达员工

Rank: 9Rank: 9Rank: 9

积分
596
发表于 2020-8-24 14:26:00 | 显示全部楼层 |阅读模式
4.AT 通信源码分析

  1. /**
  2. * AT命令初始化
  3. */
  4. void at_init(void)
  5. {
  6.     sCommand* pCmd = NULL;
  7.     int i = 0;

  8.     //初始化参数
  9.     pCmd = g_pCommandSet[i];
  10.     while (pCmd != NULL)
  11.     {
  12.         //执行一个指令子集下的初始化函数
  13.         while (pCmd->CmdType != CMDSET_END)
  14.         {
  15.             if (pCmd->pCmdParameterInit != NULL)
  16.             {
  17.                 pCmd->pCmdParameterInit((void *)pCmd);
  18.             }
  19.             pCmd++;
  20.         }
  21.         pCmd = g_pCommandSet[++i];
  22.    }//匹配命令-end
  23. }
复制代码
at_init子模块主要是将at指令参数初始化,首先要获AT的指令集,这里的指令集为NetCmdset,然后再获取指令集中的每一条指令。这个模块的功能就是将Net指令集保存到进行参数初始化处理。方便用户使用,用户调用这个接口函数可以处理AT指令的初始化参数配置。如下图所示。
图1 at_init流程框图
  1. /**
  2. * 创建AT命令任务
  3. */
  4. int lsdat_cmd_init()
  5. {
  6.     at_init();
  7.     xQueueUart2AT = xQueueCreate(1, sizeof(uartBuf_typeDef *));
  8.     if (xQueueUart2AT == NULL)
  9.     {
  10.         printf("xQueueUart2AT create failed\n");
  11.         return -1;
  12.     }
  13.     xTaskCreate(at_cmd_task, (uint8_t const *)"at_cmd", ATCMD_STACK_SIZE, NULL, UART_AT_CMD_TASK_PRIORITY, NULL);
  14. }
复制代码

lsdat_cmd_init子模块主要是将at指令初始化之后,创建一个串口数据队列xQueueUart2AT,主要是采用FreeRTOS 操作系统下的xQueueCreate函数实现,创建xQueueUart2AT用于缓存串口接收的数据。创建好队列后就需要创建一个任务函数,还是采用FreeRTOS操作系统的xTaskCreate函数,分配给这个任务的内存大小为320Kb,任务优先级为4。如下图所示。
图2 lsdat_cmd_init流程框图
  1. /**
  2. * 发送AT命令的API函数
  3. * @param cmd   发送的AT命令,以‘\r’结尾
  4. * @param cmd_len   发送AT命令的长度
  5. * @param rsp   处理AT命令后回显buf
  6. * @param rsp_len   rsp的长度
  7. * @return 发送AT命令结果
  8. *@retval LSD_ERR_OK:发送成功
  9. *@retval LSD_ERR_ERROR:发送失败
  10. */
  11. int lsdat_send_cmd(char *cmd, int cmd_len, char *rsp, int rsp_len)
  12. {  
  13.     sCommand* pCmd = NULL;
  14.     int i = 0;
  15.     char at_cmd[30] = { 0 };
  16.     char cmd_bak[100] = { 0 };
  17.     char ch;
  18.     char findAT = 0;
  19.     if( (cmd_len > 100) || (NULL == rsp) )
  20.     {
  21.         return LSD_ERR_ERROR;
  22.     }
  23.     strcpy(cmd_bak, cmd);
  24.     findAT = 0;
  25.     while (!findAT)
  26.     {
  27.         pCmd = g_pCommandSet[i];
  28.         while (pCmd->CmdType != CMDSET_END)
  29.         {
  30.              memset(at_cmd, 0, sizeof(at_cmd));
  31.              memcpy(at_cmd, cmd_bak, strlen(pCmd->Cmd));
  32.              toUpperCase(at_cmd, strlen(pCmd->Cmd));
  33.              if (strncmp(at_cmd, pCmd->Cmd, strlen(pCmd->Cmd)) == 0)
  34.              {
  35.                  ch = cmd_bak[strlen(pCmd->Cmd)];
  36.                  if ((ch == '\r') || (ch == '='))
  37.                  {
  38.                      if (0 == strncmp(at_cmd, "AT+NETP", strlen("AT+NETP")) || 0 == strncmp(at_cmd, "at+netp", strlen("at+netp"))
  39.                             || 0 == strncmp(at_cmd, "AT+TCPLK", strlen("AT+TCPLK")) || 0 == strncmp(at_cmd, "AT+tcplk", strlen("AT+tcplk"))
  40.                             || 0 == strncmp(at_cmd, "AT+TCPDIS", strlen("AT+TCPDIS")) || 0 == strncmp(at_cmd, "at+tcpdis", strlen("at+tcpdis"))
  41.                             || 0 == strncmp(at_cmd, "AT+SOCKB", strlen("AT+SOCKB")) || 0 == strncmp(at_cmd, "AT+sockb", strlen("AT+sockb"))
  42.                             || 0 == strncmp(at_cmd, "AT+TCPLKB", strlen("AT+TCPLKB")) || 0 == strncmp(at_cmd, "at+tcplkb", strlen("at+tcplkb"))
  43.                             || 0 == strncmp(at_cmd, "AT+TCPDISB", strlen("AT+TCPDISB")) || 0 == strncmp(at_cmd, "at+tcpdisb", strlen("at+tcpdisb"))
  44.                             || 0 == strncmp(at_cmd, "AT+PING", strlen("AT+PING")) || 0 == strncmp(at_cmd, "at+ping", strlen("at+ping")))
  45.                       {
  46.                       }
  47.                       else
  48.                       {
  49.                           toUpperCase(cmd_bak, strlen(cmd_bak));
  50.                       }
  51.                       pCmd->pCmdParameterStr = cmd_bak + strlen(pCmd->Cmd);
  52.                       g_p_at_cmd_api = rsp;
  53.                       pCmd->CallBack(pCmd);
  54.                       g_p_at_cmd_api = NULL;
  55.                       findAT = 1;
  56.                       break;
  57.                   }
  58.               }
  59.               pCmd++;
  60.         }
  61.         i++;
  62.     }
  63.     return LSD_ERR_OK;
  64. }
复制代码

       lsdat_send_cmd子模块主要用于发送AT指令,本API主要是将传入的AT指令发送出去。这里传入的指令是来自串口接收到的AT指令,所以先判断AT指令的长度,如果长度超过100个字节,那么就返回错误。数据长度正确后将指令转化为大写符号。每个指令后面都应该以“\r\n”结尾,所以要判断是不是以“\r\n”就可以知道指令是否接受完成。接受完成之后再将指令字符传入参数字符串中,这段程序才算执行完。如下图所示。
图3 lsdat_send_cmd流程框图




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表