mirror of
https://gitee.com/moluo-tech/AT-Command
synced 2025-06-17 07:57:52 +00:00
调整描述
This commit is contained in:
parent
88d9b816c8
commit
d87cbe4ca1
19
at.c
19
at.c
@ -1,18 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* @file at.h
|
||||
* @brief AT命令通信管理
|
||||
/******************************************************************************
|
||||
* @brief AT命令通信管理(OS版本)
|
||||
*
|
||||
* @version 5.0
|
||||
* @date 2020-05-11
|
||||
* @author roger.luo
|
||||
* Copyright (c) 2020, <master_roger@sina.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016-01-22 roger.luo Initial version.
|
||||
* 2017-05-21 roger.luo 1.1 加入任务状态管理
|
||||
* 2018-02-11 roger.luo 3.0
|
||||
* 2020-01-02 roger.luo 4.0 分离os版本
|
||||
*******************************************************************************/
|
||||
* 2020-01-02 Morro Initial version.
|
||||
******************************************************************************/
|
||||
|
||||
#include "at.h"
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
19
at.h
19
at.h
@ -1,18 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* @file at.h
|
||||
* @brief AT命令通信管理
|
||||
/******************************************************************************
|
||||
* @brief AT命令通信管理(OS版本)
|
||||
*
|
||||
* @version 5.0
|
||||
* @date 2020-05-11
|
||||
* @author roger.luo
|
||||
* Copyright (c) 2020, <master_roger@sina.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016-01-22 roger.luo Initial version.
|
||||
* 2017-05-21 roger.luo 1.1 加入任务状态管理
|
||||
* 2018-02-11 roger.luo 3.0
|
||||
* 2020-01-02 roger.luo 4.0 分离os版本
|
||||
*******************************************************************************/
|
||||
* 2020-01-02 Morro Initial version.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _AT_H_
|
||||
#define _AT_H_
|
||||
|
||||
|
228
at_chat.c
228
at_chat.c
@ -1,19 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* @file at_core.h
|
||||
* @brief AT command communications.
|
||||
/******************************************************************************
|
||||
* @brief AT指令通信
|
||||
*
|
||||
* @version 5.0
|
||||
* @date 2020-05-11
|
||||
* @author roger.luo
|
||||
* Copyright (c) 2020, <master_roger@sina.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apathe-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016-01-22 roger.luo Initial version.
|
||||
* 2017-05-21 roger.luo 1.1 加入任务状态管理
|
||||
* 2018-02-11 roger.luo 3.0
|
||||
* 2020-01-02 roger.luo 4.0 os version
|
||||
* 2020-05-21 roger.luo 5.0 无OS版本
|
||||
*******************************************************************************/
|
||||
* 2020-01-02 Morro 初版
|
||||
******************************************************************************/
|
||||
|
||||
#include "at_chat.h"
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
@ -28,78 +24,78 @@
|
||||
#define AT_TYPE_MULTILINE 3 /*多行命令 ----------*/
|
||||
#define AT_TYPE_SINGLLINE 4 /*单行命令 ----------*/
|
||||
|
||||
typedef int (*base_work)(at_core_t *ac, ...);
|
||||
typedef int (*base_work)(at_obj_t *at, ...);
|
||||
|
||||
static void at_send_line(at_core_t *ac, const char *fmt, va_list args);
|
||||
static void at_send_line(at_obj_t *at, const char *fmt, va_list args);
|
||||
|
||||
static const inline at_core_conf_t *__get_adapter(at_core_t *ac)
|
||||
static const inline at_core_conf_t *__get_adapter(at_obj_t *at)
|
||||
{
|
||||
return &ac->cfg;
|
||||
return &at->cfg;
|
||||
}
|
||||
|
||||
static bool is_timeout(at_core_t *ac, unsigned int ms)
|
||||
static bool is_timeout(at_obj_t *at, unsigned int ms)
|
||||
{
|
||||
return AT_IS_TIMEOUT(ac->resp_timer, ms);
|
||||
return AT_IS_TIMEOUT(at->resp_timer, ms);
|
||||
}
|
||||
/*
|
||||
* @brief 发送数据
|
||||
*/
|
||||
static void send_data(at_core_t *ac, const void *buf, unsigned int len)
|
||||
static void send_data(at_obj_t *at, const void *buf, unsigned int len)
|
||||
{
|
||||
ac->cfg.write(buf, len);
|
||||
at->cfg.write(buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief 格式化打印
|
||||
*/
|
||||
static void print(at_core_t *ac, const char *cmd, ...)
|
||||
static void print(at_obj_t *at, const char *cmd, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, cmd);
|
||||
at_send_line(ac, cmd, args);
|
||||
at_send_line(at, cmd, args);
|
||||
va_end(args);
|
||||
}
|
||||
/*
|
||||
* @brief 获取当前数据接收长度
|
||||
*/
|
||||
static unsigned int get_recv_count(at_core_t *ac)
|
||||
static unsigned int get_recv_count(at_obj_t *at)
|
||||
{
|
||||
return ac->rcv_cnt;
|
||||
return at->rcv_cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief 获取数据缓冲区
|
||||
*/
|
||||
static char *get_recv_buf(at_core_t *ac)
|
||||
static char *get_recv_buf(at_obj_t *at)
|
||||
{
|
||||
return (char *)ac->cfg.rcv_buf;
|
||||
return (char *)at->cfg.rcv_buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief 清除数据缓冲区
|
||||
*/
|
||||
static void recv_buf_clear(at_core_t *ac)
|
||||
static void recv_buf_clear(at_obj_t *at)
|
||||
{
|
||||
ac->rcv_cnt = 0;
|
||||
at->rcv_cnt = 0;
|
||||
}
|
||||
|
||||
/*前向查找字串*/
|
||||
static char *search_string(at_core_t *ac, const char *str)
|
||||
static char *search_string(at_obj_t *at, const char *str)
|
||||
{
|
||||
return strstr(get_recv_buf(ac), str);
|
||||
return strstr(get_recv_buf(at), str);
|
||||
}
|
||||
|
||||
/*前向查找字串*/
|
||||
static bool at_isabort(at_core_t *ac)
|
||||
static bool at_isabort(at_obj_t *at)
|
||||
{
|
||||
return ac->cursor ? ac->cursor->abort : 1;
|
||||
return at->cursor ? at->cursor->abort : 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @brief AT执行回调
|
||||
*/
|
||||
static void do_at_callback(at_core_t *a, at_item_t *i, at_callback_t cb, at_return ret)
|
||||
static void do_at_callbatk(at_obj_t *a, at_item_t *i, at_callbatk_t cb, at_return ret)
|
||||
{
|
||||
at_response_t r;
|
||||
if (cb) {
|
||||
@ -115,12 +111,12 @@ static void do_at_callback(at_core_t *a, at_item_t *i, at_callback_t cb, at_retu
|
||||
* @brief AT配置
|
||||
* @param[in] cfg - AT响应
|
||||
*/
|
||||
void at_core_init(at_core_t *ac, const at_core_conf_t cfg)
|
||||
void at_core_init(at_obj_t *at, const at_core_conf_t cfg)
|
||||
{
|
||||
at_env_t *e;
|
||||
ac->cfg = cfg;
|
||||
e = &ac->env;
|
||||
ac->rcv_cnt = 0;
|
||||
at->cfg = cfg;
|
||||
e = &at->env;
|
||||
at->rcv_cnt = 0;
|
||||
|
||||
e->is_timeout = is_timeout;
|
||||
e->printf = print;
|
||||
@ -131,29 +127,27 @@ void at_core_init(at_core_t *ac, const at_core_conf_t cfg)
|
||||
e->abort = at_isabort;
|
||||
}
|
||||
/*添加作业到队列*/
|
||||
static bool add_work(at_core_t *ac, void *params, void *info, int type)
|
||||
static bool add_work(at_obj_t *at, void *params, void *info, int type)
|
||||
{
|
||||
at_item_t *i;
|
||||
ac->cfg.lock();
|
||||
if (list_empty(&ac->ls_idle)) //无空闲at_item
|
||||
if (list_empty(&at->ls_idle)) //无空闲at_item
|
||||
return NULL;
|
||||
i = list_first_entry(&ac->ls_idle, at_item_t, node);//从空闲链中取出作业
|
||||
i = list_first_entry(&at->ls_idle, at_item_t, node);//从空闲链中取出作业
|
||||
i->info = (void *)info;
|
||||
i->param = (void *)params;
|
||||
i->state = AT_STATE_WAIT;
|
||||
i->type = type;
|
||||
i->abort = 0;
|
||||
list_move_tail(&i->node, &ac->ls_ready); //移入就绪链
|
||||
ac->cfg.unlock();
|
||||
list_move_tail(&i->node, &at->ls_ready); //移入就绪链
|
||||
return i != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief 执行任务
|
||||
*/
|
||||
static int do_work_handler(at_core_t *ac)
|
||||
static int do_work_handler(at_obj_t *at)
|
||||
{
|
||||
at_item_t *i = ac->cursor;
|
||||
at_item_t *i = at->cursor;
|
||||
return ((int (*)(at_env_t *e))i->info)(i->param);
|
||||
}
|
||||
|
||||
@ -162,7 +156,7 @@ static int do_work_handler(at_core_t *ac)
|
||||
* @param[in] a - AT管理器
|
||||
* @return 0 - 保持工作,非0 - 结束工作
|
||||
******************************************************************************/
|
||||
static int do_cmd_handler(at_core_t *a)
|
||||
static int do_cmd_handler(at_obj_t *a)
|
||||
{
|
||||
at_item_t *i = a->cursor;
|
||||
at_env_t *e = &a->env;
|
||||
@ -176,18 +170,18 @@ static int do_cmd_handler(at_core_t *a)
|
||||
break;
|
||||
case 1: /*接收状态 ------------------------------------------------------*/
|
||||
if (search_string(a, c->matcher)) {
|
||||
do_at_callback(a, i, c->cb, AT_RET_OK);
|
||||
do_at_callbatk(a, i, c->cb, AT_RET_OK);
|
||||
return true;
|
||||
} else if (search_string(a, "ERROR")) {
|
||||
if (++e->i >= c->retry) {
|
||||
do_at_callback(a, i, c->cb, AT_RET_ERROR);
|
||||
do_at_callbatk(a, i, c->cb, AT_RET_ERROR);
|
||||
return true;
|
||||
}
|
||||
e->state = 2; /*出错之后延时一段时间*/
|
||||
e->reset_timer(a); /*重置定时器*/
|
||||
} else if (e->is_timeout(a, c->timeout)) {
|
||||
if (++e->i >= c->retry) {
|
||||
do_at_callback(a, i, c->cb, AT_RET_TIMEOUT);
|
||||
do_at_callbatk(a, i, c->cb, AT_RET_TIMEOUT);
|
||||
return true;
|
||||
}
|
||||
e->state = 0; /*返回上一状态*/
|
||||
@ -208,12 +202,12 @@ static int do_cmd_handler(at_core_t *a)
|
||||
* @param[in] a - AT管理器
|
||||
* @return 0 - 保持工作,非0 - 结束工作
|
||||
******************************************************************************/
|
||||
static int send_signlline_handler(at_core_t *a)
|
||||
static int send_signlline_handler(at_obj_t *a)
|
||||
{
|
||||
at_item_t *i = a->cursor;
|
||||
at_env_t *e = &a->env;
|
||||
const char *cmd = (const char *)i->param;
|
||||
at_callback_t cb = (at_callback_t)i->info;
|
||||
at_callbatk_t cb = (at_callbatk_t)i->info;
|
||||
|
||||
switch(e->state) {
|
||||
case 0: /*发送状态 ------------------------------------------------------*/
|
||||
@ -224,18 +218,18 @@ static int send_signlline_handler(at_core_t *a)
|
||||
break;
|
||||
case 1: /*接收状态 ------------------------------------------------------*/
|
||||
if (search_string(a, "OK")) {
|
||||
do_at_callback(a, i, cb, AT_RET_OK);
|
||||
do_at_callbatk(a, i, cb, AT_RET_OK);
|
||||
return true;
|
||||
} else if (search_string(a, "ERROR")) {
|
||||
if (++e->i >= 3) {
|
||||
do_at_callback(a, i, cb, AT_RET_ERROR);
|
||||
do_at_callbatk(a, i, cb, AT_RET_ERROR);
|
||||
return true;
|
||||
}
|
||||
e->state = 2; /*出错之后延时一段时间*/
|
||||
e->reset_timer(a); /*重置定时器*/
|
||||
} else if (e->is_timeout(a, 3000 + e->i * 2000)) {
|
||||
if (++e->i >= 3) {
|
||||
do_at_callback(a, i, cb, AT_RET_TIMEOUT);
|
||||
do_at_callbatk(a, i, cb, AT_RET_TIMEOUT);
|
||||
return true;
|
||||
}
|
||||
e->state = 0; /*返回上一状态*/
|
||||
@ -255,16 +249,16 @@ static int send_signlline_handler(at_core_t *a)
|
||||
* @param[in] a - AT管理器
|
||||
* @return 0 - 保持工作,非0 - 结束工作
|
||||
******************************************************************************/
|
||||
static int send_multiline_handler(at_core_t *a)
|
||||
static int send_multiline_handler(at_obj_t *a)
|
||||
{
|
||||
at_item_t *i = a->cursor;
|
||||
at_env_t *e = &a->env;
|
||||
const char **cmds = (const char **)i->param;
|
||||
at_callback_t cb = (at_callback_t)i->info;
|
||||
at_callbatk_t cb = (at_callbatk_t)i->info;
|
||||
switch(e->state) {
|
||||
case 0:
|
||||
if (cmds[e->i] == NULL) { /*命令执行完毕*/
|
||||
do_at_callback(a, i, cb, AT_RET_OK);
|
||||
do_at_callbatk(a, i, cb, AT_RET_OK);
|
||||
return true;
|
||||
}
|
||||
e->printf(a, "%s\r\n", cmds[e->i]);
|
||||
@ -279,13 +273,13 @@ static int send_multiline_handler(at_core_t *a)
|
||||
e->i = 0;
|
||||
} else if (search_string(a, "ERROR")) {
|
||||
if (++e->j >= 3) {
|
||||
do_at_callback(a, i, cb, AT_RET_ERROR);
|
||||
do_at_callbatk(a, i, cb, AT_RET_ERROR);
|
||||
return true;
|
||||
}
|
||||
e->state = 2; /*出错之后延时一段时间*/
|
||||
e->reset_timer(a); /*重置定时器*/
|
||||
} else if (e->is_timeout(a, 3000)) {
|
||||
do_at_callback(a, i, cb, AT_RET_TIMEOUT);
|
||||
do_at_callbatk(a, i, cb, AT_RET_TIMEOUT);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@ -300,27 +294,27 @@ static int send_multiline_handler(at_core_t *a)
|
||||
* @param[in] fmt - 格式化输出
|
||||
* @param[in] args - 如变参数列表
|
||||
*/
|
||||
static void at_send_line(at_core_t *ac, const char *fmt, va_list args)
|
||||
static void at_send_line(at_obj_t *at, const char *fmt, va_list args)
|
||||
{
|
||||
char buf[MAX_AT_CMD_LEN];
|
||||
int len;
|
||||
const at_core_conf_t *adt = __get_adapter(ac);
|
||||
const at_core_conf_t *adt = __get_adapter(at);
|
||||
len = vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
|
||||
recv_buf_clear(ac); //清空接收缓存
|
||||
send_data(ac, buf, len);
|
||||
send_data(ac, "\r\n", 2);
|
||||
recv_buf_clear(at); //清空接收缓存
|
||||
send_data(at, buf, len);
|
||||
send_data(at, "\r\n", 2);
|
||||
}
|
||||
/*
|
||||
* @brief urc 处理总入口
|
||||
* @param[in] urc
|
||||
* @return none
|
||||
*/
|
||||
static void urc_handler_entry(at_core_t *ac, char *urc, unsigned int size)
|
||||
static void urc_handler_entry(at_obj_t *at, char *urc, unsigned int size)
|
||||
{
|
||||
int i, n;
|
||||
utc_item_t *tbl = ac->cfg.utc_tbl;
|
||||
for (i = 0; i < ac->cfg.urc_tbl_count; i++){
|
||||
utc_item_t *tbl = at->cfg.utc_tbl;
|
||||
for (i = 0; i < at->cfg.urc_tbl_count; i++){
|
||||
n = strlen(tbl->prefix);
|
||||
if (strncmp(urc, tbl->prefix, n) == 0)
|
||||
tbl[i].handler(urc, size);
|
||||
@ -332,27 +326,27 @@ static void urc_handler_entry(at_core_t *ac, char *urc, unsigned int size)
|
||||
* @param[in] buf - 数据缓冲区
|
||||
* @return none
|
||||
*/
|
||||
static void urc_recv_process(at_core_t *ac, char *buf, unsigned int size)
|
||||
static void urc_recv_process(at_obj_t *at, char *buf, unsigned int size)
|
||||
{
|
||||
char *urc_buf;
|
||||
unsigned short urc_size;
|
||||
urc_buf = (char *)ac->cfg.urc_buf;
|
||||
urc_size = ac->cfg.urc_bufsize;
|
||||
if (size == 0 && ac->urc_cnt > 0) {
|
||||
if (AT_IS_TIMEOUT(ac->urc_timer, 2000)){
|
||||
urc_handler_entry(ac, urc_buf, ac->urc_cnt);
|
||||
ac->rcv_cnt = 0;
|
||||
urc_buf = (char *)at->cfg.urc_buf;
|
||||
urc_size = at->cfg.urc_bufsize;
|
||||
if (size == 0 && at->urc_cnt > 0) {
|
||||
if (AT_IS_TIMEOUT(at->urc_timer, 2000)){
|
||||
urc_handler_entry(at, urc_buf, at->urc_cnt);
|
||||
at->rcv_cnt = 0;
|
||||
}
|
||||
} else {
|
||||
ac->urc_timer = at_get_ms();
|
||||
at->urc_timer = at_get_ms();
|
||||
while (size--) {
|
||||
if (*buf == '\n') {
|
||||
urc_buf[ac->urc_cnt] = '\0';
|
||||
urc_handler_entry(ac, urc_buf, ac->urc_cnt);
|
||||
urc_buf[at->urc_cnt] = '\0';
|
||||
urc_handler_entry(at, urc_buf, at->urc_cnt);
|
||||
} else {
|
||||
urc_buf[ac->urc_cnt++] = *buf++;
|
||||
if (ac->urc_cnt >= urc_size)
|
||||
ac->urc_cnt = 0;
|
||||
urc_buf[at->urc_cnt++] = *buf++;
|
||||
if (at->urc_cnt >= urc_size)
|
||||
at->urc_cnt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -363,20 +357,20 @@ static void urc_recv_process(at_core_t *ac, char *buf, unsigned int size)
|
||||
* @param[in] buf -
|
||||
* @return none
|
||||
*/
|
||||
static void resp_recv_process(at_core_t *ac, const char *buf, unsigned int size)
|
||||
static void resp_recv_process(at_obj_t *at, const char *buf, unsigned int size)
|
||||
{
|
||||
char *rcv_buf;
|
||||
unsigned short rcv_size;
|
||||
|
||||
rcv_buf = (char *)ac->cfg.rcv_buf;
|
||||
rcv_size = ac->cfg.rcv_bufsize;
|
||||
rcv_buf = (char *)at->cfg.rcv_buf;
|
||||
rcv_size = at->cfg.rcv_bufsize;
|
||||
|
||||
if (ac->rcv_cnt + size >= rcv_size) //接收溢出
|
||||
ac->rcv_cnt = 0;
|
||||
if (at->rcv_cnt + size >= rcv_size) //接收溢出
|
||||
at->rcv_cnt = 0;
|
||||
|
||||
memcpy(rcv_buf + rcv_cnt, buf, size);
|
||||
ac->rcv_cnt += size;
|
||||
rcv_buf[ac->rcv_cnt] = '\0';
|
||||
at->rcv_cnt += size;
|
||||
rcv_buf[at->rcv_cnt] = '\0';
|
||||
|
||||
}
|
||||
|
||||
@ -386,9 +380,9 @@ static void resp_recv_process(at_core_t *ac, const char *buf, unsigned int size)
|
||||
* @param[in] work - AT作业入口
|
||||
* @param[in] params -
|
||||
*/
|
||||
bool at_do_work(at_core_t *ac, int (*work)(at_env_t *e), void *params)
|
||||
bool at_do_work(at_obj_t *at, int (*work)(at_env_t *e), void *params)
|
||||
{
|
||||
return add_work(ac, params, (void *)work, AT_TYPE_WORK);
|
||||
return add_work(at, params, (void *)work, AT_TYPE_WORK);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -396,33 +390,33 @@ bool at_do_work(at_core_t *ac, int (*work)(at_env_t *e), void *params)
|
||||
* @param[in] a - AT管理器
|
||||
* @param[in] cmd - cmd命令
|
||||
*/
|
||||
bool at_do_cmd(at_core_t *ac, void *params, const at_respond_t *cmd)
|
||||
bool at_do_cmd(at_obj_t *at, void *params, const at_respond_t *cmd)
|
||||
{
|
||||
return add_work(ac, params, (void *)cmd, AT_TYPE_CMD);
|
||||
return add_work(at, params, (void *)cmd, AT_TYPE_CMD);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief 发送单行AT命令
|
||||
* @param[in] ac - AT管理器
|
||||
* @param[in] at - AT管理器
|
||||
* @param[in] cb - 执行回调
|
||||
* @param[in] singlline - 单行命令
|
||||
* @note 在命令执行完毕之前,singlline必须始终有效
|
||||
*/
|
||||
bool at_send_singlline(at_core_t *ac, at_callback_t cb, const char *singlline)
|
||||
bool at_send_singlline(at_obj_t *at, at_callbatk_t cb, const char *singlline)
|
||||
{
|
||||
return add_work(ac, (void *)singlline, (void *)cb, AT_TYPE_SINGLLINE);
|
||||
return add_work(at, (void *)singlline, (void *)cb, AT_TYPE_SINGLLINE);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief 发送多行AT命令
|
||||
* @param[in] ac - AT管理器
|
||||
* @param[in] at - AT管理器
|
||||
* @param[in] cb - 执行回调
|
||||
* @param[in] multiline - 单行命令
|
||||
* @note 在命令执行完毕之前,multiline
|
||||
*/
|
||||
bool at_send_multiline(at_core_t *ac, at_callback_t cb, const char **multiline)
|
||||
bool at_send_multiline(at_obj_t *at, at_callbatk_t cb, const char **multiline)
|
||||
{
|
||||
return add_work(ac, multiline, (void *)cb, AT_TYPE_MULTILINE);
|
||||
return add_work(at, multiline, (void *)cb, AT_TYPE_MULTILINE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -438,56 +432,54 @@ void at_item_abort(at_item_t *i)
|
||||
* @brief AT忙判断
|
||||
* @return true - 有AT指令或者任务正在执行中
|
||||
*/
|
||||
bool at_core_busy(at_core_t *ac)
|
||||
bool at_core_busy(at_obj_t *at)
|
||||
{
|
||||
return !list_empty(&ac->ls_ready);
|
||||
return !list_empty(&at->ls_ready);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief AT作业管理
|
||||
******************************************************************************/
|
||||
static void at_work_manager(at_core_t *ac)
|
||||
static void at_work_manager(at_obj_t *at)
|
||||
{
|
||||
register at_item_t *cursor = ac->cursor;
|
||||
at_env_t *e = &ac->env;
|
||||
register at_item_t *cursor = at->cursor;
|
||||
at_env_t *e = &at->env;
|
||||
/*通用工作处理者 ---------------------------------------------------------*/
|
||||
static int (*const work_handler_table[])(at_core_t *) = {
|
||||
static int (*const work_handler_table[])(at_obj_t *) = {
|
||||
do_work_handler,
|
||||
do_cmd_handler,
|
||||
send_signlline_handler,
|
||||
send_multiline_handler
|
||||
};
|
||||
if (ac->cursor == NULL) {
|
||||
if (list_empty(&ac->ls_ready)) //就绪链为空
|
||||
if (at->cursor == NULL) {
|
||||
if (list_empty(&at->ls_ready)) //就绪链为空
|
||||
return;
|
||||
e->i = 0;
|
||||
e->j = 0;
|
||||
e->state = 0;
|
||||
e->params = cursor->param;
|
||||
e->recvclr(ac);
|
||||
e->reset_timer(ac);
|
||||
ac->cursor = list_first_entry(&ac->ls_ready, at_item_t, node);
|
||||
e->recvclr(at);
|
||||
e->reset_timer(at);
|
||||
at->cursor = list_first_entry(&at->ls_ready, at_item_t, node);
|
||||
}
|
||||
/*工作执行完成,则将它放入到空闲工作链 ------------------------------------*/
|
||||
if (work_handler_table[cursor->type](ac) || cursor->abort) {
|
||||
ac->cfg.lock();
|
||||
list_move_tail(&ac->cursor->node, &ac->ls_idle);
|
||||
ac->cursor = NULL;
|
||||
ac->cfg.unlock();
|
||||
if (work_handler_table[cursor->type](at) || cursor->abort) {
|
||||
list_move_tail(&at->cursor->node, &at->ls_idle);
|
||||
at->cursor = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* @brief AT轮询任务
|
||||
*/
|
||||
void at_poll_task(at_core_t *ac)
|
||||
void at_poll_task(at_obj_t *at)
|
||||
{
|
||||
char rbuf[32];
|
||||
int read_size;
|
||||
read_size = __get_adapter(ac)->read(rbuf, sizeof(rbuf));
|
||||
urc_recv_process(ac, rbuf, read_size);
|
||||
resp_recv_process(ac, rbuf, read_size);
|
||||
at_work_manager(ac);
|
||||
read_size = __get_adapter(at)->read(rbuf, sizeof(rbuf));
|
||||
urc_recv_process(at, rbuf, read_size);
|
||||
resp_recv_process(at, rbuf, read_size);
|
||||
at_work_manager(at);
|
||||
}
|
||||
|
||||
|
||||
|
72
at_chat.h
72
at_chat.h
@ -1,20 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* Copyright(C)20 roger.luo
|
||||
* All rights reserved.
|
||||
* @file atchat.h
|
||||
* @brief AT command communications.
|
||||
/******************************************************************************
|
||||
* @brief AT指令通信
|
||||
*
|
||||
* @version 3.0
|
||||
* @date 2018-02-11
|
||||
* @author roger.luo
|
||||
* Copyright (c) 2020, <master_roger@sina.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apathe-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016-01-22 roger.luo Initial version.
|
||||
* 2017-05-21 roger.luo 1.1 加入任务状态管理
|
||||
* 2018-02-11 roger.luo 3.0
|
||||
* 2020-01-02 roger.luo 4.0 os version
|
||||
*******************************************************************************/
|
||||
* 2020-01-02 Morro 初版
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _ATCHAT_H_
|
||||
#define _ATCHAT_H_
|
||||
|
||||
@ -24,7 +19,7 @@
|
||||
|
||||
#define MAX_AT_CMD_LEN 128
|
||||
|
||||
struct at_core;
|
||||
struct at_obj;
|
||||
|
||||
/*urc处理项 -----------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
@ -35,8 +30,6 @@ typedef struct {
|
||||
typedef struct {
|
||||
unsigned int (*write)(const void *buf, unsigned int len); /*发送接口*/
|
||||
unsigned int (*read)(void *buf, unsigned int len); /*接收接口*/
|
||||
void (*lock)(void); /*加锁,针对OS*/
|
||||
void (*unlock)(void); /*解锁,针对OS*/
|
||||
/*Events -----------------------------------------------------------------*/
|
||||
void (*before_at)(void); /*开始执行AT*/
|
||||
void (*after_at)(void);
|
||||
@ -47,20 +40,20 @@ typedef struct {
|
||||
unsigned short urc_tbl_count;
|
||||
unsigned short urc_bufsize; /*urc缓冲区大小*/
|
||||
unsigned short rcv_bufsize; /*接收缓冲区*/
|
||||
}at_core_conf_t;
|
||||
}at_obj_conf_t;
|
||||
|
||||
/*AT作业运行环境*/
|
||||
typedef struct {
|
||||
int i,j,state;
|
||||
void *params;
|
||||
void (*reset_timer)(struct at_core *ac);
|
||||
bool (*is_timeout)(struct at_core *ac, unsigned int ms); /*时间跨度判断*/
|
||||
void (*printf)(struct at_core *ac, const char *fmt, ...);
|
||||
char * (*find)(struct at_core *ac, const char *expect);
|
||||
char * (*recvbuf)(struct at_core *ac); /*指向接收缓冲区*/
|
||||
unsigned int(*recvlen)(struct at_core *ac); /*缓冲区总长度*/
|
||||
void (*recvclr)(struct at_core *ac); /*清空接收缓冲区*/
|
||||
bool (*abort)(struct at_core *ac); /*终止执行*/
|
||||
void (*reset_timer)(struct at_obj *at);
|
||||
bool (*is_timeout)(struct at_obj *at, unsigned int ms); /*时间跨度判断*/
|
||||
void (*printf)(struct at_obj *at, const char *fmt, ...);
|
||||
char * (*find)(struct at_obj *at, const char *expect);
|
||||
char * (*recvbuf)(struct at_obj *at); /*指向接收缓冲区*/
|
||||
unsigned int(*recvlen)(struct at_obj *at); /*缓冲区总长度*/
|
||||
void (*recvclr)(struct at_obj *at); /*清空接收缓冲区*/
|
||||
bool (*abort)(struct at_obj *at); /*终止执行*/
|
||||
}at_env_t;
|
||||
|
||||
/*AT命令响应码*/
|
||||
@ -79,7 +72,7 @@ typedef struct {
|
||||
at_return ret;
|
||||
}at_response_t;
|
||||
|
||||
typedef void (*at_callback_t)(at_response_t *r);
|
||||
typedef void (*at_callbatk_t)(at_response_t *r);
|
||||
|
||||
/*AT状态 */
|
||||
typedef enum {
|
||||
@ -99,8 +92,8 @@ typedef struct {
|
||||
}at_item_t;
|
||||
|
||||
/*AT管理器 ------------------------------------------------------------------*/
|
||||
typedef struct at_core{
|
||||
at_core_conf_t cfg;
|
||||
typedef struct at_obj{
|
||||
at_obj_conf_t cfg;
|
||||
at_env_t env;
|
||||
at_item_t tbl[10];
|
||||
at_item_t *cursor;
|
||||
@ -111,37 +104,36 @@ typedef struct at_core{
|
||||
//urc接收计数, 命令响应接收计数器
|
||||
unsigned short urc_cnt, rcv_cnt;
|
||||
unsigned char suspend: 1;
|
||||
}at_core_t;
|
||||
}at_obj_t;
|
||||
|
||||
typedef struct {
|
||||
void (*sender)(at_env_t *e); /*自定义发送器 */
|
||||
const char *matcher; /*接收匹配串 */
|
||||
at_callback_t cb; /*响应处理 */
|
||||
at_callbatk_t cb; /*响应处理 */
|
||||
unsigned char retry; /*错误重试次数 */
|
||||
unsigned short timeout; /*最大超时时间 */
|
||||
}at_cmd_t;
|
||||
|
||||
void at_core_init(at_core_t *ac, const at_core_conf_t cfg);
|
||||
void at_obj_init(at_obj_t *at, const at_obj_conf_t cfg);
|
||||
|
||||
/*发送单行AT命令*/
|
||||
bool at_send_singlline(at_core_t *ac, at_callback_t cb, const char *singlline);
|
||||
bool at_send_singlline(at_obj_t *at, at_callbatk_t cb, const char *singlline);
|
||||
/*发送多行AT命令*/
|
||||
bool at_send_multiline(at_core_t *ac, at_callback_t cb, const char **multiline);
|
||||
bool at_send_multiline(at_obj_t *at, at_callbatk_t cb, const char **multiline);
|
||||
/*执行AT命令*/
|
||||
bool at_do_cmd(at_core_t *ac, void *params, const at_cmd_t *cmd);
|
||||
bool at_do_cmd(at_obj_t *at, void *params, const at_cmd_t *cmd);
|
||||
/*自定义AT作业*/
|
||||
bool at_do_work(at_core_t *ac, int (*work)(at_env_t *e), void *params);
|
||||
bool at_do_work(at_obj_t *at, int (*work)(at_env_t *e), void *params);
|
||||
|
||||
void at_item_abort(at_item_t *it); /*终止当前作业*/
|
||||
|
||||
bool at_core_busy(at_core_t *ac);
|
||||
bool at_obj_busy(at_obj_t *at); /*忙判断*/
|
||||
|
||||
void at_suspend(at_core_t *ac);
|
||||
void at_suspend(at_obj_t *at);
|
||||
|
||||
void at_resume(at_core_t *ac);
|
||||
void at_resume(at_obj_t *at);
|
||||
|
||||
|
||||
void at_poll_task(at_core_t *ac);
|
||||
void at_poll_task(at_obj_t *at);
|
||||
|
||||
|
||||
#endif
|
||||
|
72
at_util.h
Normal file
72
at_util.h
Normal file
@ -0,0 +1,72 @@
|
||||
/******************************************************************************
|
||||
* @brief at模块OS相关移植接口
|
||||
*
|
||||
* Copyright (c) 2020, <master_roger@sina.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-01-02 Morro 初版
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _ATUTIL_H_
|
||||
#define _ATUTIL_H_
|
||||
|
||||
#include "os.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct os_semaphore at_sem_t; /*信号量*/
|
||||
|
||||
/*
|
||||
* @brief 获取当前系统毫秒数
|
||||
*/
|
||||
static inline unsigned int at_get_ms(void)
|
||||
{
|
||||
return ril_get_ms();
|
||||
}
|
||||
/*
|
||||
* @brief 超时判断
|
||||
* @retval true | false
|
||||
*/
|
||||
static inline bool at_istimeout(unsigned int start_time, unsigned int timeout)
|
||||
{
|
||||
return at_get_ms() - start_time > timeout;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief 毫秒延时
|
||||
* @retval none
|
||||
*/
|
||||
static inline void at_delay(uint32_t ms)
|
||||
{
|
||||
os_delay(ms);
|
||||
}
|
||||
/*
|
||||
* @brief 初始化信号量
|
||||
* @retval none
|
||||
*/
|
||||
static inline void at_sem_init(at_sem_t *s, int value)
|
||||
{
|
||||
os_sem_init(s, value);
|
||||
}
|
||||
/*
|
||||
* @brief 获取信号量
|
||||
* @retval none
|
||||
*/
|
||||
static inline bool at_sem_wait(at_sem_t *s, uint32_t timeout)
|
||||
{
|
||||
return os_sem_wait(s, timeout);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief 释放信号量
|
||||
* @retval none
|
||||
*/
|
||||
static inline void at_sem_post(at_sem_t *s)
|
||||
{
|
||||
os_sem_post(s);
|
||||
}
|
||||
|
||||
#endif
|
18
list.h
18
list.h
@ -1,14 +1,9 @@
|
||||
#ifndef _LINUX_LIST_H
|
||||
#define _LINUX_LIST_H
|
||||
|
||||
#ifndef _LINUX_LIST_H_
|
||||
#define _LINUX_LIST_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define typeof (struct list_head)
|
||||
|
||||
|
||||
#undef offsetof
|
||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
||||
|
||||
/**
|
||||
* container_of - cast a member of a structure out to the containing structure
|
||||
* @ptr: the pointer to the member.
|
||||
@ -16,16 +11,9 @@
|
||||
* @member: the name of the member within the struct.
|
||||
*
|
||||
*/
|
||||
#ifdef __ICCARM__ /* IAR, and the 'ptr' must be 'struct list_head *' type, 'member' must be 'struct list_head' type */
|
||||
#define container_of(ptr, type, member) ( \
|
||||
(type *)( (char *)(ptr) - offsetof(type,member) ))
|
||||
#else
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||
#endif
|
||||
|
||||
/* copy from <linux/poison.h>, */
|
||||
/*
|
||||
* used to verify that nobody uses non-initialized list entries.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user