|
本帖最后由 armstrong 于 2019-12-10 18:01 编辑
坛友之前发过一个AT解析代码,不是很全;而且不能很好的解析传入的参数,我发一个很好用的:
atengine.h
- /*
- 这是作者声明信息:反正源码给你了,随便你怎么改!
- 作者: 洪旭耀
- Q Q: 26750452
- */
- #ifndef __AT_ENGINE_H__
- #define __AT_ENGINE_H__
- ////////////////////////////////////////////////////////////////////////////////
- #ifdef __cplusplus
- extern "C" {
- #endif
- void ATE_Exec(void);
- /* 以下函数需要移植代码来完成适配 */
- void ATE__ConsolePurgeRx(void); // 清空接收缓冲区
- int ATE__ConsoleRead(void); // 从接收缓冲区读取一个字节,返回-1表示EOF
- void ATE__ConsoleWrite(char const* p, unsigned num); // 发送一串数据到AT输出接口
- void ATE__ConsoleFlushTx(void); // 确保发送缓冲区已空
- void ATE__PostInvoke(void (*pf)(void*), void* arg);
- #ifdef __cplusplus
- }
- #endif
- ////////////////////////////////////////////////////////////////////////////////
- #endif /* __AT_ENGINE_H__ */
复制代码
atengine.c
- /*
- 这是作者声明信息:反正源码给你了,随便你怎么改!
- 作者: 洪旭耀
- Q Q: 26750452
- */
- #include "atengine.h"
- #define JSMN_STATIC
- #define JSMN_STRICT
- #include "jsmn.h"
- #include <stdarg.h>
- ////////////////////////////////////////////////////////////////////////////////
- #ifndef CRLF
- #define CRLF "\r\n"
- #endif
- enum {
- ATE_ERR_NONE = 0,
- ATE_ERR_OOM, /* Out Of Memory */
- ATE_ERR_BADCMD, /* Bad Command */
- ATE_ERR_BADARG, /* Bad Argument */
- };
- typedef struct {
- void (*handler)(int argc, char const* argv[]);
- char const* name;
- } ATCmdItem;
- static struct {
- unsigned atCmdInd;
- char atCmdLine[128];
- jsmntok_t tokens[16];
- char const* arglist[16];
- __IO bool_t echoEnable;
- __IO uint8_t errorCode;
- } cobj = {
- .echoEnable = 1,
- };
- static void ATE_Echo(int c);
- static void ATE_SendResult(void);
- static void ATE_ExecuteCommand(void);
- static void ATE_SendString(char const s[]);
- static void ATE_SendStringFormat(char const* fmt, ...);
- static void ATE_ParseCommand(char cl[]);
- static bool_t FTK_IsHeadOfString(char const* strMain, char const* strSub);
- static bool_t FTK_IsHeadOfStringEx(char const* strMain, char const* strSub, int* pLen);
- ////////////////////////////////////////////////////////////////////////////////
- //| |
- //| 函数名称 |: ATE_Exec
- //| 功能描述 |: 执行ATE输入,如果收到CRLF就解析并执行
- //| |:
- //| 参数列表 |:
- //| |:
- //| 返 回 |:
- //| |:
- //| 备注信息 |:
- //| |:
- ////////////////////////////////////////////////////////////////////////////////
- void ATE_Exec(void)
- {
- unsigned i;
- int ch;
- while ((ch = ATE__ConsoleRead()) > 0) {
- cobj.atCmdLine[cobj.atCmdInd++] = ch;
- ATE_Echo(ch);
- if (cobj.atCmdInd < 2) {
- continue;
- }
- i = cobj.atCmdInd;
- if (cobj.atCmdLine[i - 2] == '\r' && cobj.atCmdLine[i - 1] == '\n') {
- // 收到AT命令结束符CRLF
- if (cobj.errorCode == ATE_ERR_NONE) {
- /*
- 把CRLF都修改为0,很重要!
- 因为后续代码里会利用这个 */
- cobj.atCmdLine[i - 2] = 0;
- cobj.atCmdLine[i - 1] = 0;
- ATE_ExecuteCommand();
- }
- ATE_SendResult();
- ATE__ConsolePurgeRx();
- cobj.errorCode = ATE_ERR_NONE;
- cobj.atCmdInd = 0;
- return;
- } else if (i == sizeof(cobj.atCmdLine)) {
- // AT命令缓冲区已满却还没遇到CRLF,记录错误!
- cobj.errorCode = ATE_ERR_OOM;
- cobj.atCmdInd = 0;
- continue;
- }
- }
- }
- static void ATE_SendString(char const s[])
- {
- size_t len = strlen(s);
- ATE__ConsoleFlushTx();
- ATE__ConsoleWrite(s, len);
- }
- static void ATE_SendStringFormat(char const* fmt, ...)
- {
- static char sbuffer[128];
- va_list arp;
- int len;
- ATE__ConsoleFlushTx();
- va_start(arp, fmt);
- len = vsnprintf(sbuffer, sizeof(sbuffer) - 1, fmt, arp);
- va_end(arp);
- if (len > 0) {
- ATE__ConsoleWrite(sbuffer, len);
- }
- }
- static void ATE_Echo(int c)
- {
- static char cbuf[2];
- if (cobj.echoEnable) {
- cbuf[0] = c;
- ATE__ConsoleFlushTx();
- ATE__ConsoleWrite(cbuf, 1);
- }
- }
- static void ATE_SendResult(void)
- {
- if (cobj.errorCode == ATE_ERR_NONE) {
- ATE_SendString("OK"CRLF);
- } else {
- ATE_SendString("ERROR"CRLF);
- }
- }
- static void ATE_ExecuteCommand(void)
- {
- char* pCmdLine = cobj.atCmdLine;
- if (FTK_IsHeadOfString(pCmdLine, "AT+")) {
- pCmdLine += 3;
- ATE_ParseCommand(pCmdLine);
- } else if (!strcmp(pCmdLine, "ATE1")) {
- cobj.echoEnable = TRUE;
- } else if (!strcmp(pCmdLine, "ATE0")) {
- cobj.echoEnable = FALSE;
- } else if (!strcmp(pCmdLine, "AT")) {
- } else {
- cobj.errorCode = ATE_ERR_BADCMD;
- }
- }
- bool_t FTK_IsHeadOfString(char const* strMain, char const* strSub)
- {
- return FTK_IsHeadOfStringEx(strMain, strSub, NULL);
- }
- bool_t FTK_IsHeadOfStringEx(char const* strMain, char const* strSub, int* pLen)
- {
- unsigned i;
- for (i = 0; strSub[i]; i++) {
- if (strMain[i] != strSub[i]) {
- return false;
- }
- }
- if (pLen) {
- *pLen = i;
- }
- return true;
- }
- ////////////////////////////////////////////////////////////////////////////////
- #define DECL_ATCMD(nam) static void ATE_CMD_##nam(int argc, char const* argv[])
- #define REG_ATCMD(nam) { .name = #nam, .handler = ATE_CMD_##nam }
- ////////////////////////////////////////////////////////////////////////////////
- DECL_ATCMD(HELLO);
- static ATCmdItem const atCmdLst[] = {
- REG_ATCMD(HELLO),
- {}
- };
- static void ATE_ParseCommand(char cl[])
- {
- static char arg0[2] = "=";
- ATCmdItem const* cmd;
- jsmn_parser parser;
- jsmntok_t* tok;
- int len;
- for (cmd = atCmdLst; cmd->handler; cmd++) {
- if (FTK_IsHeadOfStringEx(cl, cmd->name, &len)) {
- cl += len;
- if (cl[0] == '\0' || cl[0] == '?') {
- cobj.arglist[0] = cl;
- cmd->handler(1, cobj.arglist);
- return;
- } else if (cl[0] == '=') {
- len = strlen(cl);
- cl[0] = '[';
- cl[len++] = ']';
- jsmn_init(&parser);
- len = jsmn_parse(&parser, cl, len, cobj.tokens, COUNTOF(cobj.tokens));
- if (len <= 0) {
- // 参数解析失败,返回错误!
- cobj.errorCode = ATE_ERR_BADARG;
- return;
- } else {
- cobj.arglist[0] = arg0;
- for (int i = 1; i < len; i++) {
- tok = &cobj.tokens[i];
- cobj.arglist[i] = cl + tok->start;
- cl[tok->end] = 0;
- }
- cmd->handler(len, cobj.arglist);
- }
- return;
- }
- }
- }
- cobj.errorCode = ATE_ERR_BADCMD;
- }
- DECL_ATCMD(HELLO)
- {
- ATE_SendString("The ArgList:"CRLF);
- for (int i = 0; i < argc; i++) {
- ATE_SendStringFormat("[%2u]: %s"CRLF, i, argv[i]);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
复制代码
Win32 Console 演示,串口输入输出适配接口也可参考里面的代码:
编辑理由:更新了代码。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|