1. 驱动移植
需要综合参考《Neoway_N720_N720V5_USB驱动应用指南_V1.0.pdf》,《Neoway_N720V5_Linux集成用户手册V1.0.pdf》。
(1)修改驱动代码
1.1)添加 VID PID
打开内核源码文件 cdc -acm.c (路径一般为 kernel/drivers/usb/class/cdc/kernel/drivers/usb/class/cdc)找到数组 acm_ids[],添加模块 VID 、PID 信息,代码添加如下:
static const struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x2949, 0x8700)}, //N720V5
}
1.2)过滤端口
ACM 驱动可能 被加载 成网卡端口( RNDIS/RMNET/ECMRNDIS/RMNET/ECM 端口),使得主设备将网卡枚举成 tty ACM 设备,加载 RMNET RMNET 等网卡驱动后无法正确枚举出设备,导致不能拨号。因此需要 在 ACM 驱动中过滤网卡端口, 修改方式如下 :
在kernel/drivers/usb/class/cdc-acm.c 文件里添加如下内容:
static void acm_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old);
/*
* Functions for ACM control messages.
*/
#if 1 /*Added by Neoway*/
#define true 1
#define false 0
#define NEOWAY_VENDOR_ID 0x2949
#define NEOWAY_PRODUCT_N720V5 0x8700
bool detected_neoway_product(struct usb_device *dev)
{
if (NULL == dev)
return false;
if (le16_to_cpu(dev->descriptor.idVendor) == NEOWAY_VENDOR_ID &&
le16_to_cpu(dev->descriptor.idProduct) == NEOWAY_PRODUCT_N720V5 )
return true;
return false;
}
#endif
……
static int acm_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_cdc_union_desc *union_header = NULL;
……
int rv = -ENOMEM;
#if 1 /*Added by Neoway*/
struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc;
if (detected_neoway_product(usb_dev) && (desc->bInterfaceNumber == 0 || desc->bInterfaceNumber == 1)) {
dev_err(&intf->dev, "Neoway quirk, skipping interface 0x%x\n", desc->bInterfaceNumber);
return -ENODEV;
}
#endif
(2)修改内核配置
2.1)进入内核目录
cd XXX/kernel/linux-4.9.y/
2.2)执行make menuconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-himix100-linux- menuconfig
2.3)配置内核
Device Drivers --->
[*]USB Support --->
*** USB Device Class drivers ***
2.4)选择“Save”,保存配置,然后选择“Exit”,退出
2.5)重新编译内核
2.6)重新烧录内核
按照官方手册中的方法,执行以上步骤之后就可以了,在/dev/下能够生成ttyyACM0、/dev/ttyACM1、/dev/ttyACM2设备。但实际上并没有生成。问题出在哪里?
1)怀疑是没有插入模块的缘故,只有插入模块,才能调用probe函数,从而建立/dev/ttyACM0-2设备
将模块插入,问题依旧;
2)怀疑上边的指导说明有误
之前就对这一项存在疑问,因为menuconfig中实际上并没有这一项,而只有USB Modem (CDC ACM) support这一项,在《Neoway_N720V5_Linux集成用户手册V1.0.pdf》的步骤图示中也确实是只有
3)还有一个小问题需要弄清楚:是插入模块后才会正确枚举出设备,还是即使不插4G模块,也能枚举出设备?
将模块拔掉,这一次没有/dev/ttyACM0-2设备了。由此看来,必须插入4G模块,走probe函数后设备节点才会产生。
至此,驱动移植全部完成了!
2. 应用开发
驱动移植成功只是一个很小的阶段性的胜利,真正的考验才刚刚开始。接下来,开始在Hi3559AV100上进行友方4G模块N720V5的应用开发。
饭要一口一口地吃,事要一步一步地做。
在开发应用之前,先要把操作4G模块的AT指令集先过一遍,把基础工作做好。
(1)通用AT指令
1.1)获取模块厂商信息
终端下发送(以下简写为发送):
~ # echo -e "ATI\r\n" > /dev/ttyACM1
4G模块回应(以下简称回应)(插入/不插入SIM卡一致):
~ #
NEOWAY
N720V5
REVISION V004
OK
1.2)获取模块软件版本
发送:
~ # echo -e "AT+GMR\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+GMR: N720V5_BZ_CM570_V004
OK
1.3)获取信号强度
发送:
~ # echo -e "AT+CSQ\r\n" > /dev/ttyACM1
回应(未插天线)(插入/不插入SIM卡一致):
~ #
+CSQ: 15,99
OK
1.4)获取当前网络注册状态
发送:
~ # echo -e "AT+CREG?\r\n" > /dev/ttyACM1
回应(未插SIM卡时):
~ #
+CREG: 0,0
OK
回应(插入SIM卡时):
~ #
+CREG: 0,1
OK
发送:
~ # echo -e "AT+CREG=?\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+CREG: (0-2)
OK
发送:
~ # echo -e "AT+CREG=1\r\n" > /dev/ttyACM1
回应:
~ #
OK
再发送:
~ # echo -e "AT+CREG?\r\n" > /dev/ttyACM1
回应:
~ #
+CREG: 1,1
OK
1.5)获取EPS网络注册状态
发送:
~ # echo -e "AT+CEREG?\r\n" > /dev/ttyACM1
回应(未插SIM卡时):
~ #
+CEREG: 0,0
OK
回应(插入SIM卡时):
~ #
+CEREG: 0,1
OK
发送:
~ # echo -e "AT+CEREG=1\r\n" > /dev/ttyACM1
回应:
~ #
OK
再发送:
~ # echo -e "AT+CEREG?\r\n" > /dev/ttyACM1
回应(插入SIM卡时):
~ #
+CEREG: 1,1
OK
发送:
~ # echo -e "AT+CEREG=?\r\n" > /dev/ttyACM1
回应:
~ #
+CEREG: (0-2)
OK
1.6)网络选择
以下均在未插SIM卡的状态下测试。
发送:
~ # echo -e "AT+COPS?\r\n" > /dev/ttyACM1
回应(未插SIM卡时):
~ #
+COPS: 0
OK
回应(插入SIM卡时):
~ #
+COPS: 0,0,"CHINA MOBILE",7
OK
发送:
~ # echo -e "AT+COPS=0,0\r\n" > /dev/ttyACM1
回应(未插SIM卡时):
~ #
OK
长时间后终端会出现:
+CREG: 2
+CEREG: 2
回应(插入SIM卡时):
~ #
OK
发送:
~ # echo -e "AT+COPS=0,2\r\n" > /dev/ttyACM1
回应(插入SIM卡时):
~ #
OK
再次发送:
echo -e "AT+COPS?\r\n" > /dev/ttyACM1
回应:
~ #
+COPS: 0,2,"46000",7
OK
1.7)查询国际移动用户识别码
以下均在未插SIM卡的状态下测试。
发送:
~ # echo -e "AT+CIMI\r\n" > /dev/ttyACM1
回应(未插SIM卡时):
~ #
ERROR
回应(插入SIM卡时) :
~ #
460001271966189
OK
1.8)获取通信模块IMEI号
发送:
~ # echo -e "AT+CGSN\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+CGSN: "865192041776138"
OK
1.9)获取SIM卡标识
发送:
~ # echo -e "AT+CCID\r\n" > /dev/ttyACM1
回应(未插SIM卡时):
~ #
ERROR
回应(插入SIM卡时):
~ #
+CCID: 898600690119F0215276
OK
1.10)查询模块型号
发送:
~ # echo -e "AT+CGMM\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+CGMM: N720V5
OK
1.11)查询模块型号
发送:
~ # echo -e "AT+GMM\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+GMM: N720V5
OK
1.12)设置模块波特率
发送:
~ # echo -e "AT+IPR=115200\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
OK
发送:
~ # echo -e "AT+IPR=100\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
ERROR
输入以上错误比特率后,再发送:
echo -e "AT+IPR?\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+IPR: 0
OK
发送:
~ # echo -e "AT+IPR=?\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+IPR: 0, 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
OK
1.13)模块功能选择
发送:
~ # echo -e "AT+CFUN=?\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+CFUN: (0-1,4),(0-1)
OK
发送:
~ # echo -e "AT+CFUN?\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+CFUN: 1
OK
发送:
~ # echo -e "AT+CFUN=0,0\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
OK
发送:
~ # echo -e "AT+CFUN=4,0\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
OK
发送:
~ # echo -e "AT+CFUN=0,1\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
OK
usb 3-1: USB disconnect, device number 2
cdc_acm 3-1:1.4: failed to set dtr/rts[1]+ Done cat /dev/ttyACM1
~ # usb 3-1: new high-speed USB device number 3 using xhci-hcd
cdc_acm 3-1:1.0: Neoway quirk, skipping interface 0x0
cdc_acm 3-1:1.1: Neoway quirk, skipping interface 0x1
cdc_acm 3-1:1.2: ttyACM0: USB ACM device
cdc_acm 3-1:1.4: ttyACM1: USB ACM device
cdc_acm 3-1:1.6: ttyACM2: USB ACM device
发送:
~ # echo -e "AT+CFUN=1,1\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+CREG: 0
+CEREG: 0
OK
usb 3-1: USB disconnect, device number 2
cdc_acm 3-1:1.4: failed to set dtr/rts[1]+ Done cat /dev/ttyACM1
~ # usb 3-1: new high-speed USB device number 3 using xhci-hcd
cdc_acm 3-1:1.0: Neoway quirk, skipping interface 0x0
cdc_acm 3-1:1.1: Neoway quirk, skipping interface 0x1
cdc_acm 3-1:1.2: ttyACM0: USB ACM device
cdc_acm 3-1:1.4: ttyACM1: USB ACM device
cdc_acm 3-1:1.6: ttyACM2: USB ACM device
1.14)串口多路复用
发送:
~ # echo -e "AT+CMUX=0\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
OK
发送:
~ # echo -e "AT+CMUX=?\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+CMUX: (0-1),(0-2),(1-8),(1-32768),(1-255),(0-100),(2-255),(1-255),(1-7)
OK
1.15)时钟
发送:
~ # echo -e "AT+CCLK?\r\n" > /dev/ttyACM1
回应(未插SIM卡时):
~ #
+CCLK: "14/01/01,00:00:40"
OK
回应(插入SIM卡时):
~ #
+CCLK: "20/02/11,16:31:02"
OK
1.16)输入PIN码
发送:
~ # echo -e "AT+CPIN?\r\n" > /dev/ttyACM1
回应(未插SIM卡时):
~ #
ERROR
回应(插入SIM卡时):
~ #
+CPIN: READY
OK
发送:
~ # echo -e "AT+CPIN=\"0000\"\r\n" > /dev/ttyACM1
回应(插入SIM卡时):
~ #
+CME ERROR: 4
ERROR
1.17)PIN使能与查询功能指令
发送:
~ # echo -e "AT+CLCK=?\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+CLCK: ("CS","PS","PF","SC","AO","OI","OX","AI","IR","NT","NM","NS","NA","AB","AG","AC","FD","PN","PU","PP","PC")
OK
发送:
~ # echo -e "AT+CLCK=\"SC\",2\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+CLCK: 0
OK
1.18)修改密码指令
发送:
~ # echo -e "AT+CPWD=?\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+CPWD: ("CS",16),("PS",16),("PF",16),("SC",16),("AO",16),("OI",16),("OX",16),("AI",16),("IR",16),("AB",16),("AG",16),("AC",16),("FD",16),("NT",16),("NM",16),("NS",16),("NA",16),("PN",16),("PU",16),("PP",16),("PC",16),("P2",16)
OK
~ #
发送:
~ # echo -e "AT+CPWD=\"SC\",\"1234\",\"0000\"\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+CME ERROR: 10
~ #
1.19)设置PDP格式
发送:
~ # echo -e "AT+CGDCONT=1,\"IP\",\"CMNET\"\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
OK
发送:
~ # echo -e "AT+CGDCONT?\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+CGDCONT: 1,"IP","CMNET","",,,
OK
1.20)用户认证
发送:
~ # echo -e "AT+XGAUTH=?\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
+XGAUTH: (1),(0-2),32,32
OK
1.21)设置GPRS附着和分离
发送:
echo -e "AT+CGATT=?\r\n" > /dev/ttyACM1 或 echo -e "AT+CGATT?\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
OK
OK
......
发送:
echo -e "AT+CGATT=1\r\n" > /dev/ttyACM1
回应(未插SIM卡时):
~ #
ERROR
回应(插入SIM卡时):
~ #
OK
1.22)GPRS拨号
发送:
~ # echo -e "ATD*99#\r\n" > /dev/ttyACM1
回应(未插SIM卡时):
~ #
+CME ERROR: 100
回应(插入SIM卡时):
~ #
CONNECT
1.23)模块休眠模式使能
发送:
~ # echo -e "AT+ENPWRSAVE?\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+ENPWRSAVE: 0
OK
发送:
~ # echo -e "AT+ENPWRSAVE=1\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
OK
再次发送:
echo -e "AT+ENPWRSAVE?\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
+ENPWRSAVE: 1
OK
1.24)打开&关闭回显
发送:
~ # echo -e "ATE0\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
OK
发送:
~ # echo -e "AT\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
OK
发送:
~ # echo -e "ATE1\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
~ #
OK
再次发送:
~ # echo -e "AT\r\n" > /dev/ttyACM1
回应(插入/不插入SIM卡一致):
ATATATATAT
ERRORATATATATATAT
ERRORATATATATAT
ERRORATATATATATAT
ERRORATATATATAT
ERROR……
1.25)读写本机号码
发送:
~ # echo -e "AT+CNUM\r\n" > /dev/ttyACM1
回应(插入SIM卡时):
~ #
+CNUM: "","13691005742",129
OK