4.AT 通信源码分析
- /**
- * AT命令初始化
- */
- void at_init(void)
- {
- sCommand* pCmd = NULL;
- int i = 0;
- //初始化参数
- pCmd = g_pCommandSet[i];
- while (pCmd != NULL)
- {
- //执行一个指令子集下的初始化函数
- while (pCmd->CmdType != CMDSET_END)
- {
- if (pCmd->pCmdParameterInit != NULL)
- {
- pCmd->pCmdParameterInit((void *)pCmd);
- }
- pCmd++;
- }
- pCmd = g_pCommandSet[++i];
- }//匹配命令-end
- }
复制代码at_init子模块主要是将at指令参数初始化,首先要获AT的指令集,这里的指令集为NetCmdset,然后再获取指令集中的每一条指令。这个模块的功能就是将Net指令集保存到进行参数初始化处理。方便用户使用,用户调用这个接口函数可以处理AT指令的初始化参数配置。如下图所示。 图1 at_init流程框图 - /**
- * 创建AT命令任务
- */
- int lsdat_cmd_init()
- {
- at_init();
- xQueueUart2AT = xQueueCreate(1, sizeof(uartBuf_typeDef *));
- if (xQueueUart2AT == NULL)
- {
- printf("xQueueUart2AT create failed\n");
- return -1;
- }
- xTaskCreate(at_cmd_task, (uint8_t const *)"at_cmd", ATCMD_STACK_SIZE, NULL, UART_AT_CMD_TASK_PRIORITY, NULL);
- }
复制代码
lsdat_cmd_init子模块主要是将at指令初始化之后,创建一个串口数据队列xQueueUart2AT,主要是采用FreeRTOS 操作系统下的xQueueCreate函数实现,创建xQueueUart2AT用于缓存串口接收的数据。创建好队列后就需要创建一个任务函数,还是采用FreeRTOS操作系统的xTaskCreate函数,分配给这个任务的内存大小为320Kb,任务优先级为4。如下图所示。 图2 lsdat_cmd_init流程框图 - /**
- * 发送AT命令的API函数
- * @param cmd 发送的AT命令,以‘\r’结尾
- * @param cmd_len 发送AT命令的长度
- * @param rsp 处理AT命令后回显buf
- * @param rsp_len rsp的长度
- * @return 发送AT命令结果
- *@retval LSD_ERR_OK:发送成功
- *@retval LSD_ERR_ERROR:发送失败
- */
- int lsdat_send_cmd(char *cmd, int cmd_len, char *rsp, int rsp_len)
- {
- sCommand* pCmd = NULL;
- int i = 0;
- char at_cmd[30] = { 0 };
- char cmd_bak[100] = { 0 };
- char ch;
- char findAT = 0;
- if( (cmd_len > 100) || (NULL == rsp) )
- {
- return LSD_ERR_ERROR;
- }
- strcpy(cmd_bak, cmd);
- findAT = 0;
- while (!findAT)
- {
- pCmd = g_pCommandSet[i];
- while (pCmd->CmdType != CMDSET_END)
- {
- memset(at_cmd, 0, sizeof(at_cmd));
- memcpy(at_cmd, cmd_bak, strlen(pCmd->Cmd));
- toUpperCase(at_cmd, strlen(pCmd->Cmd));
- if (strncmp(at_cmd, pCmd->Cmd, strlen(pCmd->Cmd)) == 0)
- {
- ch = cmd_bak[strlen(pCmd->Cmd)];
- if ((ch == '\r') || (ch == '='))
- {
- if (0 == strncmp(at_cmd, "AT+NETP", strlen("AT+NETP")) || 0 == strncmp(at_cmd, "at+netp", strlen("at+netp"))
- || 0 == strncmp(at_cmd, "AT+TCPLK", strlen("AT+TCPLK")) || 0 == strncmp(at_cmd, "AT+tcplk", strlen("AT+tcplk"))
- || 0 == strncmp(at_cmd, "AT+TCPDIS", strlen("AT+TCPDIS")) || 0 == strncmp(at_cmd, "at+tcpdis", strlen("at+tcpdis"))
- || 0 == strncmp(at_cmd, "AT+SOCKB", strlen("AT+SOCKB")) || 0 == strncmp(at_cmd, "AT+sockb", strlen("AT+sockb"))
- || 0 == strncmp(at_cmd, "AT+TCPLKB", strlen("AT+TCPLKB")) || 0 == strncmp(at_cmd, "at+tcplkb", strlen("at+tcplkb"))
- || 0 == strncmp(at_cmd, "AT+TCPDISB", strlen("AT+TCPDISB")) || 0 == strncmp(at_cmd, "at+tcpdisb", strlen("at+tcpdisb"))
- || 0 == strncmp(at_cmd, "AT+PING", strlen("AT+PING")) || 0 == strncmp(at_cmd, "at+ping", strlen("at+ping")))
- {
- }
- else
- {
- toUpperCase(cmd_bak, strlen(cmd_bak));
- }
- pCmd->pCmdParameterStr = cmd_bak + strlen(pCmd->Cmd);
- g_p_at_cmd_api = rsp;
- pCmd->CallBack(pCmd);
- g_p_at_cmd_api = NULL;
- findAT = 1;
- break;
- }
- }
- pCmd++;
- }
- i++;
- }
- return LSD_ERR_OK;
- }
复制代码
lsdat_send_cmd子模块主要用于发送AT指令,本API主要是将传入的AT指令发送出去。这里传入的指令是来自串口接收到的AT指令,所以先判断AT指令的长度,如果长度超过100个字节,那么就返回错误。数据长度正确后将指令转化为大写符号。每个指令后面都应该以“\r\n”结尾,所以要判断是不是以“\r\n”就可以知道指令是否接受完成。接受完成之后再将指令字符传入参数字符串中,这段程序才算执行完。如下图所示。 图3 lsdat_send_cmd流程框图
|