diff --git a/README.md b/README.md index 53a7469..2e8f9ce 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ - at_chat.c at_chat.h list.h 用于无OS版本,使用链式队列及异步回调方式处理AT命令收发,支持URC处理、自定义命令发送与解析作业。 -- at.c at.h at_util.h +- at.c at.h at_util.h comdef.h 用于OS版本, 使用前需要根据at_util.h规定的操作系统相关的接口进行移植,如提供信号量操作、任务延时等操作。 @@ -19,7 +19,7 @@ ### at_chat 模块(无OS) -##### 基本概念 +#### 基本概念 at_chat 模块使用链式队列进行管理,包含2条链表,空闲链表和就绪链表。它们的每一个基本工作单元称为一个作业项,对于将要执行的命令都会放到就绪链表中,命令执行完成之后由空闲链表来进行回收,作业项的定义如下: @@ -41,19 +41,22 @@ typedef struct { /*...未完,待续*/ -##### 基本接口与描述 +#### 基本接口与描述 - at_send_singlline, 发送单行命令,默认等待OK响应,超时3S - at_send_multiline, 多行命令,默认等待OK响应,超时3S - at_do_cmd,支持自定义发送格式与接收匹配串 - at_do_work,支持自定义发送与接收解析 -##### 使用演示 +#### 效果演示 详细使用可以参考Demo程序wifi_task.c模块 ![m169 wifi模组通信效果图](images/wifi.jpg) -```c +#### 使用步骤 + +1.定义AT控制器及通信适配器接口 +```c /* * @brief 定义AT控制器 */ @@ -68,19 +71,18 @@ const at_adapter_t adap = { //AT适配器接口 ``` - -3. 初始化AT控制器 +2. 初始化AT控制器并放入任务中轮询(考虑到处理实时性,建议20ms以下) ```c +/* + * @brief wifi初始化 + */ +void wifi_init(void) +{ + at_obj_init(&at, &adap); + /*...*/ +}driver_init("wifi", wifi_init); -at_obj_init(&at, &adap); - -``` - - -4. 将AT控制器放入任务中轮询(考虑到处理实时性,建议20ms以下) - -```c /* * @brief wifi任务(10ms 轮询1次) */ @@ -92,14 +94,14 @@ void wifi_task(void) ``` -5. 发送单行命令 - -**例子:** +#### 例子演示 +```C +//WIFI IO配置命令 => AT+GPIO_TEST_EN=1\r\n <= OK\r\n - +``` ```c /** @@ -117,17 +119,22 @@ at_send_singlline(&at, test_gpio_callback, "AT+GPIO_TEST_EN=1"); ``` -#### at 模块(OS版本) +### at 模块(OS版本) 由于AT命令通信是一个比较复杂的过程,对于没有OS的环境下处理难度比较大,也很绕,对于不允许阻塞程序,除了使用状态与+回调没有其它更好的办法,所以推荐使用这个模块 -##### 基本接口与描述 +#### 基本接口与描述 - at_do_cmd,执行AT命令,可以通过这个接口进一步封装出一常用的单行命令、多行命令。 - at_split_respond_lines,命令响应分割器。 - at_do_work,适用于发送组合命令,如GPRS模组发送短信或者发送socket数据需要等待"<"或者"CONNECT"提示符,可以通过这个接口自定义收发。 -##### 使用演示(后续会提供一个无线GPRS模块演示程序出来) +#### 演示效果(后续会提供一个无线GPRS模块演示程序出来) + + +#### 使用步骤 + +1.定义AT控制器、通信适配器接口(包含URC回调函数表,接口缓冲区URC) ```c static at_obj_t at; //定义AT控制器对象 @@ -152,7 +159,7 @@ const at_adapter_t adap = { //AT适配器接口 ``` -3. 初始化AT控制器并创建AT接收处理线程 +2.创建AT控制器并创建轮询处理线程 ```c @@ -165,16 +172,18 @@ void at_thread(void) } ``` +#### 例子演示 - -4. 使用例子 -查询GPRS模块信号质量: +##### 例子1(查询无线模组信号质量) +```c +/** at_do_cmd 接口使用演示 + 查询GPRS模组信号质量命令 => AT+CSQ <= +CSQ: 24, 0 <= OK - -```c +*/ + /* * @brief 获取csq值 */ @@ -182,7 +191,7 @@ bool read_csq_value(at_obj_t *at, int *rssi, int *error_rate) { //接收缓冲区 unsigned char recvbuf[32]; - //AT响应 + //AT应答 at_respond_t r = {"OK", recvbuf, sizeof(recvbuf), 3000}; // if (at_do_cmd(at, &r, "AT+CSQ") != AT_RET_OK) @@ -192,8 +201,67 @@ bool read_csq_value(at_obj_t *at, int *rssi, int *error_rate) } +``` +##### 例子2(发送TCP数据) +```C +/** at_do_work 接口使用演示 + 参考自hl8518模组Socket 数据发送命令 + => AT+KTCPSND=, + + <= CONNECT + + => + + <= OK +*/ + +/* + * @brief 数据发送处理 + * @retval none + */ +static bool socket_send_handler(at_work_ctx_t *e) +{ + struct socket_info *i = (struct socket_info *)e->params; + struct ril_sock *s = i->s; + + if (s->type == SOCK_TYPE_TCP) + e->printf(e, "AT+KTCPSND=%d,%d", s->session, i->bufsize); + else + e->printf(e, "AT+KUDPSND=%d,%s,%d,%d",s->session, s->host, + s->port, i->bufsize); + + if (e->wait_resp(e, "CONNECT", 5000) != AT_RET_OK) { //等待提示符 + goto Error; + } + e->write(i->buf, i->bufsize); //发送数据 + + e->write("--EOF--Pattern--", strlen("--EOF--Pattern--")); //发送结束符 + + if (e->wait_resp(e, "OK", 5000) == AT_RET_OK) + return true; + else { +Error: + e->write("--EOF--Pattern--", strlen("--EOF--Pattern--")); + return false; + } +} + +/** + * @brief socket 数据发送 + * @param[in] s - socket + * @param[in] buf - 数据缓冲区 + * @param[in] len - 缓冲区长度 + */ +static bool hl8518_sock_send(ril_obj_t *r, struct ril_sock *s, const void *buf, + unsigned int len) +{ + struct socket_info info = {s, (unsigned char *)buf, len, 0}; + if (len == 0) + return false; + return at_do_work(&r->at, (at_work)socket_send_handler, &info); +} ``` diff --git a/at.c b/at.c index b6c1b90..642c83d 100644 --- a/at.c +++ b/at.c @@ -12,8 +12,8 @@ * 2021-02-05 Morro 1.޸struct at_obj,ȥ * 2.ɾ at_obj_destroyӿ ******************************************************************************/ -#include "at/at.h" -#include "misc/comdef.h" +#include "at.h" +#include "comdef.h" #include #include #include @@ -273,7 +273,7 @@ static void urc_recv_process(at_obj_t *at, const char *buf, unsigned int size) urc_buf[at->urc_cnt] = '\0'; at->urc_cnt = 0; at->adap.debug("urc recv timeout=>%s\r\n", urc_buf); - } + } while (size--) { at->urc_timer = at_get_ms(); diff --git a/comdef.h b/comdef.h new file mode 100644 index 0000000..7b4aad5 --- /dev/null +++ b/comdef.h @@ -0,0 +1,58 @@ +/****************************************************************************** + * @brief ͨú궨 + * + * Copyright (c) 2018~2020, + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-02-01 Morro Initial version. + ******************************************************************************/ + +#ifndef _COM_DEF_H_ +#define _COM_DEF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*Ͷ -----------------------------------------------------------*/ +#define ANONY_CONN(type, var, line) type var##line +#define ANONY_DEF(type,prefix,line) ANONY_CONN(type, prefix, line) +#define ANONY_TYPE(type,prefix) ANONY_DEF(type, prefix, __LINE__) + +/** + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ( \ + (type *)( (char *)(ptr) - offsetof(type,member) )) + + +#if defined(__CC_ARM) || defined(__GNUC__) /* ARM,GCC*/ + #define SECTION(x) __attribute__((section(x))) + #define UNUSED __attribute__((unused)) + #define USED __attribute__((used)) + #define ALIGN(n) __attribute__((aligned(n))) + #define WEAK __attribute__((weak)) +#elif defined (__ICCARM__) /*IAR */ + #define SECTION(x) @ x + #define UNUSED + #define USED __root + #define WEAK __weak +#else + #error "Current tool chain haven't supported yet!" +#endif + +/*Ԫظ ---------------------------------------------------------------*/ +#define ARRAY_COUNT(Array) (sizeof(Array) / sizeof(Array[0])) + +#ifdef __cplusplus +} +#endif + +#endif