AT 功能的实现需要 AT Server 和 AT Client 两个部分共同完成:AT Server 主要用于接收 AT Client 发送的命令请求,判断接收的命令及参数格式,并下发对应的响应数据,或者主动下发URC数据(Unsolicited Result Code,常在AT Server出现比如 WIFI 连接断开、TCP 接收数据等特殊情况时,通知AT Client做出相应的操作);AT Client 主要用于发送命令、等待 AT Server 响应,并对 AT Server响应数据或主动发送的URC数据进行解析处理,获取相关信息。
AT Server 和 AT Client 之间支持多种数据通讯的方式(UART、SPI 等),目前最常用的是串口 UART 通讯方式(包括RS232、RS485等)。随着 AT 命令的逐渐普及,越来越多的嵌入式产品上使用了 AT 命令,AT 命令作为主芯片和通讯模块的协议接口,硬件接口一般为串口,这样主控设备可以通过简单的命令和硬件设计完成多种操作。
1.1 AT组件简介
虽然 AT 命令已经形成了一定的标准化,但是不同的芯片支持的 AT 命令并没有完全统一,这直接提高了用户使用的复杂性。对于 AT 命令的发送和接收以及数据的解析没有统一的处理方式,并且在使用 AT 设备连接网络时,只能通过命令完成简单的设备连接和数据收发功能,很难做到对上层网络应用接口的适配,不利于产品设备的开发。
为了方便用户使用 AT 命令,简单的适配不同的 AT 模块, RT-Thread 提供了 AT 组件用于 AT 设备的连接和数据通讯。AT 组件的实现也包括客户端的和服务器两部分,完成 AT 命令的发送、命令格式及参数判断、命令的响应、响应数据的接收、响应数据的解析、URC 数据处理等整个 AT 命令数据交互流程。
通过 AT 组件,设备可以作为 AT Client 使用串口连接其他设备发送并接收解析数据,可以作为 AT Server 让其他设备甚至电脑端连接完成发送数据的响应,也可以在本地 shell 启动 CLI 模式使设备同时支持 AT Server 和 AT Client 功能,该模式多用于设备开发调试。对于嵌入式设备而言,更多的情况下设备使用AT组件作为客户端连接服务器设备。
支持AT命令集的设备一般内部都集成了TCP/IP网络协议栈,我们只需要通过串口连接AT模块与主控芯片,就可以使用AT命令集控制AT模块实现我们需要的网络服务功能。类比前一篇博客介绍的网络分层结构,AT组件的协议栈架构并没有网络协议层,AT通讯模块的驱动协议框架如下图所示:
APP层:开发者只需要使用标准的系统调用接口,比如BSD Socket API 开发应用即可,无需关心底层的实现,同时应用代码还拥有比较好的可移植性;
SAL组件层:对上层提供了BSD Socket API,对下层提供了协议簇注册接口;
AT组件层:对上层提供了基于AT的Socket接口,对下层提供了移植接口。AT device在初始化完成后会被作为一个AT Socket设备注册到SAL组件中,当上层应用调用BSD Socket API时,会通过注册的接口调用底层的AT device驱动,完成数据的传输;
AT device层:利用AT组件对AT device做的移植,主要是利用AT组件提供的接口完成对AT设备(比如ESP8266模块)的初始化工作。由于AT设备内部有MCU芯片运行射频芯片的驱动与协议栈代码(要想正常使用AT模块,需要确保里面烧录了正确的固件代码),我们在主控设备上只需要完成串口驱动的配置和AT命令集的发送解析既可以了。