Files
rt-thread/components/net/at/include/at.h
ryancw ac8fba0129 [drivers][serial_v2]允许阻塞接收超过rx缓冲区大小的数据、增加超时时间、flush、获取缓冲区数据长度命令、数据溢出逻辑修复、稳定性细节优化、添加更多serial_v2测试用例
[components][serial_v2] 优化txflush逻辑、对tx的activated做中断保护

[components][at] at_client适配新版serial_v2

[components][at] at_server适配新版serial_v2

[components][serial_v2] 测试用例增加循环调用,format测试用例

[components][serial_v2] poll模式判断逻辑错误

[components][serial_v2] 测试用例去掉一些非必要延时

[components][serial_v2] 测试例程使用menuconfig进行配置,更新readme

[components][at_client] at_client_getchar返回值错误、at_client解析线程优先级错误设置

[components][at] 错误码应该返回负值

[components][serial_v2] TCFLSH和FIONREAD完善、control函数增加错误返回值

[components][serial_v2] RT_SERIAL_CTRL_GET_RX_DATA_LEN更改为RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT

[utest][serial_v2] TC_UART_SEND_TIMES替换为RT_SERIAL_TC_SEND_ITERATIONS

[components][serial_v2] FIONREAD参数应该是无符号类型

[utest][serial_v2] 完善测试用例

[components][serial_v2] 避免使用三目运算符

[components][serial_v2] 使用clang-format格式化代码

[components][serial_v2] 添加get超时时间命令

[components][serial_v2] 完善posix接口

[components][serial_v2] 阻塞接口添加阻塞时间为0时的处理逻辑、优化RX阻塞接收逻辑

[components][serial_v2] 设置超时时间命令的参数改为指针形式

[components][serial_v2] nbuf发送添加超时时间为0时的逻辑

[components][serial_v2] 完善添加测试用例

[utest][serial_v2] 修复依赖关系

[components][serial_v2] 非阻塞模式下tx_flush错误修复

[components][serial_v2] activated使用原子API

[components][serial_v2] 优化DMA逻辑、没使能DMA时屏蔽DMA逻辑节约资源

[components][serial_v2] 提供写满时丢弃新数据和覆盖旧数据策略,写满丢弃策略效率更高

[components][serial_v2] 部分平台适配写满时两种策略功能

[components][serial_v2] DMA模式暂不支持丢弃新数据策略

[utest][serial_v2] 优化测试代码

[components][serial_v2] DMA模式下使用乒乓缓冲、DMA模式支持丢弃新数据策略

[utest][serial_v2] 适配DMA乒乓缓冲

[bsp][serial_v2] 部分bsp适配DMA下乒乓缓冲

[components][serial_v2] 使用spinlock替换中断,对部分结构体变量使用原子操作

[utest][serial_v2] 更新测试用例

[components][at] 适配new serialv2不再判断RTT版本号

[components][at] 删除多余的中文注释

[utest][serial_v2] 添加交叉echo示例,qemu环境下专用

[bsp][qemu] 适配串口v2并开启fifo

[components][at] 修复合并导致的错误

[bsp][n32] 适配serial_v2,没有经过测试

[components][serial_v2] 格式化代码

[utest][serial_v2] 删除无意义的打印
2025-05-16 09:42:11 +08:00

276 lines
9.0 KiB
C

/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-03-30 chenyong first version
* 2018-08-17 chenyong multiple client support
*/
#ifndef __AT_H__
#define __AT_H__
#include <stddef.h>
#include <rtthread.h>
#include <rtdevice.h>
#ifdef __cplusplus
extern "C" {
#endif
#define AT_SW_VERSION "1.3.1"
#define AT_CMD_NAME_LEN 16
#ifndef AT_SERVER_RECV_BUFF_LEN
#define AT_SERVER_RECV_BUFF_LEN 256
#endif
#ifndef AT_SERVER_DEVICE
#define AT_SERVER_DEVICE "uart2"
#endif
/* the maximum number of supported AT clients */
#ifndef AT_CLIENT_NUM_MAX
#define AT_CLIENT_NUM_MAX 1
#endif
#define AT_CMD_EXPORT(_name_, _args_expr_, _test_, _query_, _setup_, _exec_) \
rt_used static const struct at_cmd __at_cmd_##_test_##_query_##_setup_##_exec_ rt_section("RtAtCmdTab") = \
{ \
_name_, \
_args_expr_, \
_test_, \
_query_, \
_setup_, \
_exec_, \
};
enum at_status
{
AT_STATUS_UNINITIALIZED = 0,
AT_STATUS_INITIALIZED,
AT_STATUS_CLI,
};
typedef enum at_status at_status_t;
#ifdef AT_USING_SERVER
enum at_result
{
AT_RESULT_OK = 0, /* AT result is no error */
AT_RESULT_FAILE = -1, /* AT result have a generic error */
AT_RESULT_NULL = -2, /* AT result not need return */
AT_RESULT_CMD_ERR = -3, /* AT command format error or No way to execute */
AT_RESULT_CHECK_FAILE = -4, /* AT command expression format is error */
AT_RESULT_PARSE_FAILE = -5, /* AT command arguments parse is error */
};
typedef enum at_result at_result_t;
struct at_cmd
{
char name[AT_CMD_NAME_LEN];
char *args_expr;
at_result_t (*test)(void);
at_result_t (*query)(void);
at_result_t (*setup)(const char *args);
at_result_t (*exec)(void);
};
typedef struct at_cmd *at_cmd_t;
struct at_server
{
rt_device_t device;
at_status_t status;
rt_err_t (*get_char)(struct at_server *server, char *ch, rt_int32_t timeout);
rt_bool_t echo_mode;
char send_buffer[AT_SERVER_SEND_BUFF_LEN];
char recv_buffer[AT_SERVER_RECV_BUFF_LEN];
rt_size_t cur_recv_len;
#if (!defined(RT_USING_SERIAL_V2))
rt_sem_t rx_notice;
#endif
rt_thread_t parser;
void (*parser_entry)(struct at_server *server);
};
typedef struct at_server *at_server_t;
#endif /* AT_USING_SERVER */
#ifdef AT_USING_CLIENT
enum at_resp_status
{
AT_RESP_OK = 0, /* AT response end is OK */
AT_RESP_ERROR = -1, /* AT response end is ERROR */
AT_RESP_TIMEOUT = -2, /* AT response is timeout */
AT_RESP_BUFF_FULL= -3, /* AT response buffer is full */
};
typedef enum at_resp_status at_resp_status_t;
struct at_response
{
/* response buffer */
char *buf;
/* the maximum response buffer size, it set by `at_create_resp()` function */
rt_size_t buf_size;
/* the length of current response buffer */
rt_size_t buf_len;
/* the number of setting response lines, it set by `at_create_resp()` function
* == 0: the response data will auto return when received 'OK' or 'ERROR'
* != 0: the response data will return when received setting lines number data */
rt_size_t line_num;
/* the count of received response lines */
rt_size_t line_counts;
/* the maximum response time */
rt_int32_t timeout;
};
typedef struct at_response *at_response_t;
struct at_client;
/* URC(Unsolicited Result Code) object, such as: 'RING', 'READY' request by AT server */
struct at_urc
{
const char *cmd_prefix;
const char *cmd_suffix;
void (*func)(struct at_client *client, const char *data, rt_size_t size);
};
typedef struct at_urc *at_urc_t;
struct at_urc_table
{
size_t urc_size;
const struct at_urc *urc;
};
typedef struct at_urc *at_urc_table_t;
struct at_client
{
rt_device_t device;
at_status_t status;
char end_sign;
char *send_buf;
/* The maximum supported send cmd length */
rt_size_t send_bufsz;
/* The length of last cmd */
rt_size_t last_cmd_len;
/* the current received one line data buffer */
char *recv_line_buf;
/* The length of the currently received one line data */
rt_size_t recv_line_len;
/* The maximum supported receive data length */
rt_size_t recv_bufsz;
#if (!defined(RT_USING_SERIAL_V2))
rt_sem_t rx_notice;
#endif
rt_mutex_t lock;
at_response_t resp;
rt_sem_t resp_notice;
at_resp_status_t resp_status;
struct at_urc_table *urc_table;
rt_size_t urc_table_size;
const struct at_urc *urc;
rt_thread_t parser;
};
typedef struct at_client *at_client_t;
#endif /* AT_USING_CLIENT */
#ifdef AT_USING_SERVER
/* AT server initialize and start */
int at_server_init(void);
/* AT server send command execute result to AT device */
void at_server_printf(const char *format, ...);
void at_server_printfln(const char *format, ...);
void at_server_print_result(at_result_t result);
rt_size_t at_server_send(at_server_t server, const char *buf, rt_size_t size);
rt_size_t at_server_recv(at_server_t server, char *buf, rt_size_t size, rt_int32_t timeout);
/* AT server request arguments parse */
int at_req_parse_args(const char *req_args, const char *req_expr, ...);
#endif /* AT_USING_SERVER */
#ifdef AT_USING_CLIENT
/* AT client initialize and start*/
int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bufsz);
/* ========================== multiple AT client function ============================ */
/* get AT client object */
at_client_t at_client_get(const char *dev_name);
at_client_t at_client_get_first(void);
/* AT client wait for connection to external devices. */
int at_client_obj_wait_connect(at_client_t client, rt_uint32_t timeout);
/* AT client send or receive data */
rt_size_t at_client_obj_send(at_client_t client, const char *buf, rt_size_t size);
rt_size_t at_client_obj_recv(at_client_t client, char *buf, rt_size_t size, rt_int32_t timeout);
/* set AT client a line end sign */
void at_obj_set_end_sign(at_client_t client, char ch);
/* Set URC(Unsolicited Result Code) table */
int at_obj_set_urc_table(at_client_t client, const struct at_urc * table, rt_size_t size);
/* AT client send commands to AT server and waiter response */
int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr, ...);
int at_obj_exec_cmd_format(at_client_t client, at_response_t resp, const char* format, const char *cmd_expr, ...);
/* AT response object create and delete */
at_response_t at_create_resp(rt_size_t buf_size, rt_size_t line_num, rt_int32_t timeout);
void at_delete_resp(at_response_t resp);
at_response_t at_resp_set_info(at_response_t resp, rt_size_t buf_size, rt_size_t line_num, rt_int32_t timeout);
/* AT response line buffer get and parse response buffer arguments */
const char *at_resp_get_line(at_response_t resp, rt_size_t resp_line);
const char *at_resp_get_line_by_kw(at_response_t resp, const char *keyword);
int at_resp_parse_line_args(at_response_t resp, rt_size_t resp_line, const char *resp_expr, ...);
int at_resp_parse_line_args_by_kw(at_response_t resp, const char *keyword, const char *resp_expr, ...);
/* ========================== single AT client function ============================ */
/**
* NOTE: These functions can be used directly when there is only one AT client.
* If there are multiple AT Client in the program, these functions can operate on the first initialized AT client.
*/
#define at_exec_cmd(resp, ...) at_obj_exec_cmd(at_client_get_first(), resp, __VA_ARGS__)
#define at_exec_cmd_format(resp, format, ...) at_obj_exec_cmd_format(at_client_get_first(), resp, format, __VA_ARGS__)
#define at_client_wait_connect(timeout) at_client_obj_wait_connect(at_client_get_first(), timeout)
#define at_client_send(buf, size) at_client_obj_send(at_client_get_first(), buf, size)
#define at_client_recv(buf, size, timeout) at_client_obj_recv(at_client_get_first(), buf, size, timeout)
#define at_set_end_sign(ch) at_obj_set_end_sign(at_client_get_first(), ch)
#define at_set_urc_table(urc_table, table_sz) at_obj_set_urc_table(at_client_get_first(), urc_table, table_sz)
#endif /* AT_USING_CLIENT */
/* ========================== User port function ============================ */
#ifdef AT_USING_SERVER
/* AT server device reset */
void at_port_reset(void);
/* AT server device factory reset */
void at_port_factory_reset(void);
#endif
#ifdef __cplusplus
}
#endif
#endif /* __AT_H__ */