☰
域格移芯平台模块之open二次开发(二):AT指令
2026/10/28 2:55:57 网站建设 项目流程

适用模块:YM310 X09、YM310 X19、YM310 X08、YM310 W09、YM310 W19

  • AT指令概述
  • 模块自带AT指令(RIL接口)
    • RIL接口说明
    • 使用流程
    • 注意事项
  • 客户自定义AT指令(参考 demo_gpio.c)
    • demo_gpio.c 的指令格式
    • 实现步骤
    • 注意事项
  • 实测验证
  • 踩坑记录
    • 自定义 AT 在 USB 口不响应
    • RIL 回调拿不到 +CESQ 响应
  • 两类指令的快速对照

本篇示例基于 demo 工程,编译命令为build YM310_X09C.S61 demo。

AT指令概述

在 OpenCPU开发里,AT 指令有两类实现方法:

  • 模块自带 AT 指令:协议栈/基带原生支持,比如AT+CPIN?(查 SIM)、AT+CEREG?(查注册)、AT+CESQ(查信号)。应用不用实现,只管发给协议栈、收响应。
  • 客户自定义 AT 指令:协议栈不认识,比如AT+GPIO=2,0,1、AT+MYRSRP。全部由应用层代码解析、执行、回复,常用于让外部 MCU / 上位机控制模组上的应用行为。

本篇分别讲这两类在 YOpen SDK 下怎么调、怎么配、怎么发,并给出一个能同时跑通两类指令的实测 demo。

模块自带AT指令(RIL接口)

RIL接口说明

SDK 在api/yopen_ril.h里封装了 RIL 接口,应用通过它把 AT 发给协议栈:

// RIL 初始化,注册 URC 主动上报回调yopen_errcode_ril_eyopen_ril_init(yopen_ril_urc_callback callback);// 发送 AT 指令typedefint32_t(*yopen_ril_callback)(char*line,uint32_tline_len,void*user_data);yopen_errcode_ril_eyopen_ril_send_atcmd(char*cmd,uint32_tcmd_len,yopen_ril_callback callback,void*param);

使用流程

  1. 初始化 RIL:应用启动时yopen_ril_init(),注册一个 URC 回调,用来接收网络主动上报(来电、短信、注册状态变化)。
  2. 构造命令字符串:按 3GPP / 厂商规范拼写,末尾带\r\n。比如查卡状态必须写成AT+CPIN?\r\n。
  3. 下发指令:yopen_ril_send_atcmd()传命令、长度、响应回调、自定义参数。
  4. 解析响应:回调里逐行收到协议栈返回,常见有OK、ERROR、厂商扩展错误(如+CME ERROR: 140),以及查询类信息行。

下面以查询 RSRP 为例(AT+CESQ):

#include"yopen_ril.h"#include"yopen_nw.h"staticintg_rsrp=255;/* 255 表示无效 *//* RIL 响应回调:协议栈返回内容逐行传入 */staticint32_tcesq_rsp_cb(char*line,uint32_tline_len,void*user_data){if(line&&strstr(line,"+CESQ:")){/* +CESQ: <rxlev>,<ber>,<rscp>,<ecno>,<rsrq>,<rsrp> */char*p=strchr(line,':')+1;intfield=0;char*comma;while((comma=strchr(p,','))!=NULL){*comma=0;if(++field==6){g_rsrp=atoi(p);break;}/* 第 6 字段 = RSRP */p=comma+1;}DEMO_AT_TRACE("parse +CESQ rsrp=%d\n",g_rsrp);}return0;}voidquery_rsrp_by_at(void){yopen_ril_init(NULL);yopen_ril_send_atcmd("AT+CESQ\r\n",strlen("AT+CESQ\r\n"),cesq_rsp_cb,NULL);}

注意事项

  • 超时与重试:yopen_ril_send_atcmd()自身不直接暴露超时参数,超时由 RIL 内部管,默认约 5 秒。涉及网络交互的命令(短信、PDP 激活)建议上层用状态机 + 超时计数器保护,别在主线程死等。
  • 命令格式:严格按规范。ATD拨号必须带;;AT+CMGS发短信先等>提示再发内容、以Ctrl+Z(0x1A) 结尾。
  • 错误码解析:+CME ERROR: <code>优先查厂商扩展定义。比如该平台140在bsp/EC7XX/kernel/PLAT/prebuild/PS/inc/cmicomm.h里是CME_FEATURE_NOT_SUPPORTED,常见于没开 VoLTE/IMS 却去拨语音电话的场景(详见文末踩坑记录)。

客户自定义AT指令(参考 demo_gpio.c)

demo_gpio.c 的指令格式

YOpen SDK 里自定义 AT 的典型参考是demo/demo_gpio.c,它实现了:

AT+GPIO=<yopen_GpioNum>,<dir>[,level]

例如AT+GPIO=2,0,1把 GPIO2 配成输出并拉高。命令从 USB / 指定 UART 收进来,应用解析后执行 GPIO 动作,并通过同一串口回结果。

实现步骤

  1. 初始化 UART:yopen_uart_set_dcbconfig()配波特率,yopen_uart_open()打开口,yopen_uart_register_cb()注册接收回调。
  2. 接收回调通知任务:回调里收到YOPEN_UART_RX_RECV_DATA_IND事件后,用消息队列通知业务任务去读数据。
  3. 读取并解析:业务任务yopen_uart_read()读串口,再parse_at_command()解析——strchr(input,'=')定位命令名与参数分隔,strchr(params_start,',')依次切分多参数,atoi()转整型。
  4. 执行并回复:按解析结果设 GPIO 方向/电平,然后demo_uart_write()回\r\nOK\r\n;失败回\r\nERROR\r\n。要上报状态则按<CR><LF>+GPIO LVL <level><CR><LF>回送,最后也要有OK/ERROR收尾。

下面以AT+MYRSRP(查询 RSRP 的自定义指令)为例,展示 UART 接收侧代码:

#include"yopen_uart.h"#include"yopen_nw.h"#defineMY_AT_PORTYOPEN_UART_PORT_1/* 自定义 AT 走独立 UART,避开 USB 口 *//* 业务任务里读串口、解析、回复 */staticvoidat_uart_task(void){chardata[128];intlen=yopen_uart_read(MY_AT_PORT,(uint8_t*)data,sizeof(data)-1);if(len<=0)return;data[len]=0;/* 归一化:去前导空白、转大写,兼容 AT+MYRSRP / AT+MYRSRP? / AT+MYRSRP; 等变体 *//* 归一化实现可参考 demo_gpio.c 的 parse_at_command() */if(strncmp(data,"AT+MYRSRP",9)==0){yopen_nw_signal_strength_info_s sig;charresp[64];if(yopen_nw_get_signal_strength(0,&sig)==YOPEN_NW_SUCCESS)snprintf(resp,sizeof(resp),"\r\n+MYRSRP: %d\r\n\r\nOK\r\n",sig.rsrp);elsesnprintf(resp,sizeof(resp),"\r\n+MYRSRP: NA\r\n\r\nERROR\r\n");yopen_uart_write(MY_AT_PORT,(uint8_t*)resp,strlen(resp));}else{yopen_uart_write(MY_AT_PORT,(uint8_t*)"\r\nERROR\r\n",9);}}

注意事项

  • 自定义 AT 处理任务别做长耗时操作,否则阻塞串口读取,影响后续命令和 URC。
  • 多任务共享 GPIO / 传感器等资源时,解析执行要加锁。
  • 回复尽量简短,避免占串口太久。
  • 命令命名:建议加私有前缀(如AT+MYGPIO、AT+MYRSRP),别和模块自带AT+标准指令撞车。
  • 端口选择:见下方「踩坑记录」——S61 这类平台 USB AT 口被原厂引擎占着,自定义 AT 建议直接接硬件 UART(如 UART1)。

实测验证

下面这张图来自 YOpen SDK(EC716S / YM310_X09C.S61 平台)上的真实测试,两类 AT 同时跑、互不干扰。

左侧 EPAT Trace 窗口(模块自带 AT 路径)

  • ATCMD , decode AT : AT+CESQ:应用层通过yopen_ril_send_atcmd()把AT+CESQ下发给协议栈。
  • AT CMD , RESP : +CESQ: 99,99,255,255,34,48:协议栈返回小区信号质量,最后一个字段48就是 RSRP 报告值。
  • [AT_RSRP]auto AT+CESQ rsrp=48:应用在 RIL 回调里解析出 RSRP 并打印到 trace。

右侧串口助手窗口(客户自定义 AT 路径)

  • 通过硬件 UART1 向模组发AT+MYRSRP。
  • 模组应用层收到后调yopen_nw_get_signal_strength()读信号强度,回送结果,最终返回OK。

踩坑记录

自定义 AT 在 USB 口不响应

现象:应用层yopen_uart_open(YOPEN_USB_PORT_COM)后,从外部串口助手发AT+MYRSRP回ERROR,而AT+CESQ等原厂指令却正常。

原因:
YM310_X09C.S61(EC716s)平台上,YOPEN_USB_PORT_COM被协议栈 AT 引擎独占,应用层无法通过yopen_uart_open()接管这个口。外部指令实际走的是原厂 AT 引擎,所以不认识自定义指令。

处理方法:
把自定义 AT 改走硬件 UART:

staticints_uart_port=YOPEN_UART_PORT_1;/* 原来是 YOPEN_USB_PORT_COM */

重新编译烧录,从 UART1(TX/RX/GND 接电脑串口工具,波特率 115200)发AT+MYRSRP即可。USB AT 口继续正常用原厂指令,互不干扰。

RIL 回调拿不到 +CESQ 响应

现象:S61 平台调用yopen_ril_send_atcmd("AT+CESQ\r\n", ...)后,等信号量 5 秒超时,g_rsrp一直是 255。

原因:
该平台yopen_ril_send_atcmd()的响应回调不一定会把+CESQ:/OK逐行回传给应用层回调(外部 USB 口发AT+CESQ能回值,是因为那条路走的是原厂 AT 引擎)。

处理方法:
保留yopen_ril_send_atcmd("AT+CESQ\r\n", ...)作为「模块自带 AT 下发」的演示动作,但实际取值改用已验证可用的 API:

yopen_nw_signal_strength_info_s sig;if(yopen_nw_get_signal_strength(0,&sig)==YOPEN_NW_SUCCESS)g_rsrp=sig.rsrp;/* 直接读,稳 */

两类指令的快速对照

维度模块自带 AT 指令客户自定义 AT 指令
实现位置协议栈/基带固件应用层代码(如demo_gpio.c)
调用/入口yopen_ril_send_atcmd()yopen_uart_read()+ 自行解析
结果返回RIL 回调逐行接收yopen_uart_write()主动回复
典型示例AT+CPIN?、ATD...AT+GPIO=2,0,1
出错排查查 CME 错误码/网络状态查解析逻辑和 GPIO 配置

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询