「正点原子Linux连载」第七十一章Linux 4G通信实验
1)实验平台:正点原子Linux开发板
2)摘自《正点原子 I.MX6U嵌入式Linux驱动开发指南》 关注官方微信号公众号,获取更多资料:正点原子
第七十一章Linux 4G通信实验
前面我们学习了如何在Linux中使用有线网络或者WIFI,但是使用有线网络或者WIFI有很多限制,因为要布线,即使是WIFI你也得先布线,然后在接个路由器。有很多场合是不方便布线的,这个时候就是4G大显身手的时候,产品可以直接通过4G连接到网络,实现无人值守。本章我们就来学一下如何在I.MX6U-ALPHA开发板中使用4G来实现联网功能。
71.1 4G网络连接简介
提起4G网络连接,大家可能会觉得是个很难的东西,其实对于嵌入式Linux而言,4G网络连接恰恰相反,不难!大家可以看一下其他的嵌入式Linux或者Android开发板,4G模块都是MiniPCIE接口的,包括很多4G模块都是MiniPCIE接口的。但是大家稍微深入研究一下就会发现,这些4G模块虽然用了MiniPCIE接口,但是实际上的通信接口都是USB,所以4G模块的驱动就转换为了USB驱动。而这些4G模块厂商都提供了详细的文档讲解如何在Linux下使用4G模块,以及如何修改Linux内核加入4G模块驱动。正点原子的I.MX6U-ALPHA开发板也有一个MiniPCIE形式的4G模块接口,虽然外形是MiniPCIE的,但是内心却是USB的。I.MX6U-ALPHA开发板的4G模块原理图如图71.4.1所示:
图71.4.1 4G模块原理图
图71.4.1中的U8就是MiniPCIE接口,MiniPCIE接口连接到了GL850这个HUB芯片的DP2和DM2,也就是GL850的USB2接口上。U11就是Nano SIM接口,I.MX6U-ALPHA开发板使用Nano SIM卡,这样大家就可以直接拿自己的手机卡进行测试。I.MX6U-ALPHA开发板的4G接口位置如图71.1.2所示:
图71.1.2 ALPHA开发板4G接口
在使用之前需要将4G模块插入到图71.1.2所示的MiniPCIE接口上,然后上紧两边的螺丝,Nano SIM卡插入到图71.1.2中的Nano SIM座里面,注意Nano SIM卡的方向!
Nano SIM卡的金属触点朝下!
Nano SIM卡的金属触点朝下!
Nano SIM卡的金属触点朝下!
理论上所有的MiniPCIE接口的4G模块都可以连接到正点原子的I.MX6U-ALPHA开发板上,因为这些4G模块都遵循同样的接口标准,但是大家在使用的时候还是要详细的看一下4G模块的接口引脚描述。不同的4G模块其驱动形式也不同,本章我们讲解两款4G模块在I.MX6U-ALPHA开发板上的使用,一个是上海移远公司的EC20,另外一个是高新兴物联的ME3630,这两款4G模块都有MiniPCIE接口的,这两个4G模块如图71.4.2所示:
图71.4.2 4G模块
图71.4.2中左侧的是高新兴物联的ME3630-W 4G模块,右侧的是上海移远的EC20 4G模块。本章我们就分别来讲解一下如何在I.MX6U-ALPHA开发板上使用EC20和ME3630这两个4G模块。
4G模块工作是需要天线的,因此在选购4G模块的时候一定要记得购买天线,否则无法进行测试。一般MiniPCIE接口的4G模块留出来的天线接口为IPEX座,因此购买天线的时候也要选择IPEX接口的,或者使用IPEX转SMA线来转接。推荐大家到正电原子官方店铺购买4G模块和相应的天线。
71.2高新兴ME3630 4G模块实验
71.2.1 ME3630 4G模块简介
ME36304G模块是正点原子官方推荐的4G通信模块,ME3630 4G模块是深圳高新兴物联出品的4G LTE模块,前身是中兴物联,正点原子是高新兴物联官方代理商,因此在模块质量以及售后服务这一块是有保证的。
ME3630是一款LTE Cat.4七模全网通4G模块,在LTE模式下可以提供50Mbps上行速率以及150Mbps的下行速率,并支持回退到3G或2G网络。此模组支持分集接收、分集接收是终端产品支持双天线以提高通信质量和通信可靠性的无线连接技术。ME3630支持多种网络协议,比如PAP、CHAP、PPP等,拥有多种功能,比如GNSS、Remotewakeup、SMS、支持FoTA空中升级等。ME3630 4G模块广泛应用于智能抄表、安防信息采集、工业路由器、车载通信以及监控等等M2M领域。ME3630 4G模组特性如下:
①、一路USB2.0接口。
②、一路UART接口。
③、SIM卡接口支持1.8/3.0V。
④、内置TCP、UDP、FTP和HTTP等协议。
⑤、支持RAS/ECM/NDIS。
⑥、支持AT指令。
ME3630 4G模块有多种配置,比如纯数据版本、集成GNSS版本、全网通版本等等,本节教程我们主要使用到ME3630的数据通信功能,因此推荐大家购买全网通数据版,如果想要定位功能的话就购买全网通数据+GNSS版本,至于其他的版本大家根据自己的实际需求选择即可。在正式使用ME3630 4G模块之前,请先将其插入到开发板的MiniPCIE座上、上紧螺、插入Nano SIM卡、接上天线,如图71.2.1.1所示:
图71.2.1.1 ALPHA开发板连接ME3630模块
一切准备就绪以后就可以开始驱动ME3630 4G模块了。
71.2.2 ME3630 4G模块驱动修改
1、添加USB设备信息
我们需要先在Linux内核中添加ME3630的USB设备信息,因为我们前面说了,ME3630 4G模块用的USB接口。打开Linux源码的drivers/usb/serial/option.c文件,找到options_ids数组,然后在里面添加ME3630的PID和VID,要添加的内容如下:
示例代码71.2.2.1 ME3630 PID和VID信息
1{ USB_DEVICE( 0x19d2, 0x0117)}, /* ME3630*/
2{ USB_DEVICE( 0x19d2, 0x0199)},
3{ USB_DEVICE( 0x19d2, 0x1476)},
完成以后的options_ids数组如图71.2.2.1所示:
图71.2.2.1 添加PID和VID后的option_ids数组
2、添加ECM支持程序
ME3630支持ECM接口,可以通过ECM接口轻松联网,如果要使用ECM接口的话需要修改drivers/usb/serial/option.c文件里面的option_probe函数。找到此函数,然后在里面输入如下内容:
示例代码71.2.2.2 option_probe函数需要添加的内容
1/* EM3630 */
2if( serial-> dev-> descriptor. idVendor == 0x19d2&&
3 serial-> dev-> descriptor. idProduct == 0x1476&&
4 serial-> interface-> cur_altsetting-> desc. bInterfaceNumber == 3)
5 return- ENODEV;
6
7if( serial-> dev-> descriptor. idVendor == 0x19d2&&
8 serial-> dev-> descriptor. idProduct == 0x1476&&
9 serial-> interface-> cur_altsetting-> desc. bInterfaceNumber == 4)
10 return- ENODEV;
11
12if( serial-> dev-> descriptor. idVendor == 0x19d2&&
13 serial-> dev-> descriptor. idProduct == 0x1509&&
14 serial-> interface-> cur_altsetting-> desc. bInterfaceNumber == 4)
15 return- ENODEV;
16
17if( serial-> dev-> descriptor. idVendor == 0x19d2&&
18 serial-> dev-> descriptor. idProduct == 0x1509&&
19 serial-> interface-> cur_altsetting-> desc. bInterfaceNumber == 5)
20 return- ENODEV;
添加完成以后的option_probe函数如图71.2.2.2所示:
图71.2.2.2 向option_probe添加的内容
3、配置Linux内核
我们需要配置Linux内核,首先使能USBNET功能,路径如下:
-> Device Drivers
->-*- Network device support
-> USB Network Adapters
-> -*- Multi-purpose USB Networking Framework
配置如图71.2.2.3所示:
图71.2.2.3 使能USB网络
接下来我们还需要使能USB串口GSM、CDMA驱动,配置路径如下:
-> Device Drivers
-> [*] USB support
-><*>USB Serial Converter support
-><*> USB driver for GSM and CDMA modems
配置如图71.2.2.4所示:
图71.2.2.4 USB GSM和CDMA
继续配置Linux内核,使能USB的CDC ACM模式,配置路径如下:
-> Device Drivers
->[*] USB support
-><*>Support for Host-side USB
-><*> USB Modem (CDC ACM) support
配置如图71.2.2.5所示:
图71.2.2.5 使能USB的CDC ACM功能
关于Linux内核的配置就到此为止,编译一下Linux内核,然后使用新的zImage启动开发板。如果ME3630已经插上的话,系统启动以后就会输出如图71.2.2.6所示的信息:
图71.2.2.6 ME3630虚拟USB信息
从图71.2.2.6可以看出,ME3630虚拟出了3个USB设备,分别为ttyUSB0~ttyUSB2。对于支持ECM接口的4G模块来讲,比如ZM5330/ZM8620/ME3620/ME3630。如果模块工作在ECM模式下,可以通过运行"ifconfig -a"命令查看对应的网卡,网卡的名字可能为usbX/ecmX/ethX等,X是具体的数字,如果存在的话就说明ECM接口驱动加载成功。输入"ifconfig -a"命令,会发现多了一个名为"usb0"的网卡,图71.2.2.7所示:
图71.2.2.7 ME3630对应的usb0网卡
71.2.3 ME3630 4G模块ppp联网测试
1、使能Linux内核ppp功能
ME3630支持通过ppp拨号上网,也是支持使用ECM接口上网,我们先来学习一下如何通过ppp拨号上网。首先我们需要配置Linux内核,打开Linux内核的ppp功能,配置路径如下:
-> Device Drivers
-> [*] Network device support
-><*>PPP (point-to-point protocol) support
-><*> PPP BSD-Compress compression
-><*> PPP Deflate compression
-> [*] PPP filtering
-><*> PPP MPPE compression (encryption)
-> [*] PPP multilink support
-><*> PPP over Ethernet
-><*> PPP support for async serial ports
-><*> PPP support for sync tty ports
配置完成以后如图71.2.3.1所示:
图71.2.3.1 Linux内核PPP使能
配置完成以后重新编译一下Linux内核,得到新的zImage镜像文件,然后使用新的zImage镜像文件启动开发板。
2、移植pppd软件
我们需要通过pppd这个软件来实现ppp拨号上网,这个软件需要我们移植。
在移植之前先删除掉/usr/sbin/chat这个软件!
在移植之前先删除掉/usr/sbin/chat这个软件!
在移植之前先删除掉/usr/sbin/chat这个软件!
我们使用Busybox制作根文件系统的时候会生成/usr/sbin/chat这个软件,我们一会移植pppd的时候也会编译出chat软件。因此需要将根文件系统中原来的/usr/sbin/chat软件删除掉,否则的话我们移植的chat软件工作将会出问题!
pppd源码已经放到了开发板光盘中,路径为:1、例程源码->7、第三方库源码-> ppp-2.4.7.tar.gz,将ppp-2.4.7.tar.gz拷贝到Ubuntu下并解压,解压以后会生成一个名为ppp-2.4.7的文件夹。进入到ppp-2.4.7目录中,然后编译pppd源码,命令如下:
cd ppp-2.4.7/
make CC=arm-linux-gnueabihf-gcc //编译
编译完成以后就会在当前目录下生成chat/chat、pppd/pppd、pppdump/pppdump和pppstats/pppstats这四个文件,将这个四个文件拷贝到开发板根文件系统中的/sur/bin目录下,命令如下:
sudo cp chat/chat /home/zuozhongkai/linux/nfs/rootfs/usr/bin/ -f
sudo cp pppd/pppd /home/zuozhongkai/linux/nfs/rootfs/usr/bin/ -f
sudo cp pppdump/pppdump /home/zuozhongkai/linux/nfs/rootfs/usr/bin/ -f
sudo cp pppstats/pppstats /home/zuozhongkai/linux/nfs/rootfs/usr/bin/ -f
完成以后输入"pppd-v"查看一下pppd的版本号,如果pppd版本号显示正常的话就说明pppd移植成功,如图71.2.3.2所示:
图71.2.3.2 pppd版本号信息
3、ppp上网测试
在使用pppd进行拨号上网之前需要先创建4个文件,这个4个文件必须放到同一个目录下。在开发板根文件系统下创建/etc/gosuncn目录,进入到刚刚创建的/etc/gosuncn目录下,然后新建一个名为"ppp-on"的shell脚本文件,在ppp-on文件里面输入如下所示内容:
示例代码71.2.3.1 ppp-on文件内容
1 #!/bin/sh
2 clear
3 OPTION_FILE= "gosuncn_options"
4 DIALER_SCRIPT= $( pwd)/ gosuncn_ppp_dialer
5 exec pppd file $OPTION_FILE connect "chat -v -f ${DIALER_SCRIPT}"
再新建一个名为"gosuncn_option"的文件,在文件里面输入如下所示内容:
示例代码71.2.3.2 gosuncn_option文件内容
1/dev/ttyUSB2
2115200
3 crtscts
4 modem
5 persist
6 lock
7 noauth
8 noipdefault
9 debug
10 nodetach
11 user Anyname
12 password Anypassword
13 ipcp- accept- local
14 ipcp- accept- remote
15 defaultroute
16 usepeerdns
17 noccp
18 nobsdcomp
19 novj
20 dump
第1行,如果是联通或移动的卡就是用ttyUSB2,如果是电信的卡就是用ttyUSB0。
第11~12行,这两行内容和所使用的卡有关,如果是联通或者移动的卡就按照上面的写,如果是电信的卡,要改为如下所示内容:
usercard
passwordcard
再新建一个名为"gosuncn_ppp_dialer"的文件,输入如下所示内容:
示例代码71.2.3.3 gosuncn_ppp_dialer文件内容
1 ABORT "NO CARRIER"
2 ABORT "ERROR"
3 TIMEOUT 120
4"" ATE
5 SAY "ATE"
6 ECHO ON
7 OK ATH
8 OK ATP
9 OK AT+CGDCONT=1,\"IP\",\"3GNET\"
10 OK ATD*99#
11 CONNECT
第9行,后面的3GNET是网络的APN码,这个要根据自己所使用的手机卡来确定,联通卡的APN为3GNET,移动卡的APN为CMNET。因为我使用的是联通卡进行测试的,所有这里设置APN为3GNET,如果使用的移动卡,那么要将APN设置为CMNET。如果是电信的卡,那么第9行要改为:
OK "AT+ZCAPN=card,card"
第10行,如果是联通或移动的卡,那么第10行就不变。如果是电信的卡,那么第10行要改为:
OK ATD#777
最后新建一个名为"disconnect"的shell脚本,输入如下所示内容:
示例代码71.2.3.4 disconnect文件内容
1 #!/bin/sh
2 killall pppd
这四个文件编写完成以后要给予ppp-on和disconnect这两个文件可执行权限,命令如下:
chmod 777 ppp-on disconnect
完成以后输入如下命令连接4G网络:
./ppp-on &
在ME3630连接4G网络的过程中,可能会出现如图71.2.3.3所示的错误提示:
图71.2.3.3ppp拨号上网错误提示
从图71.2.3.3可以看出,提示不能创建"Can't create lock file /var/lock/LCK..ttyUSB2",检查根文件系统是否存在/var/run和/var/lock这两个目录,如果没有的话就手动创建这两个文件夹,命令如下:
mkdir /var/run //创建/var/run文件夹
mkdir /var/lock //创建/var/lock文件夹
完成以后重新输入"./pppd-on &"命令连接4G网络,连接成功以后会输入如图71.2.3.4所示信息:
图71.2.3.4 4G网络连接信息
从图71.2.3.4可以看出,在ME3630 4G模块联网过程中,需要用到/etc/ppp/resolv.conf文件,但是我们当前根文件系统没有此文件,所以需要手动创建此文件。创建完成以后重启开发板!开发板重启以后进入到/etc/gosuncn目录,然后输入如下命令完成拨号上网:
./ppp-on &
ppp拨号成功以后就会生成一个名为"ppp0"的网卡,如图71.2.3.5所示:
图71.2.3.5 ppp0网卡信息
4G网络测试需要关闭其他网卡,否则的话网络测试可能有问题,但是我们现在是通过网络启动的系统,并且通过NFS挂载的根文件系统,因此我们没法关闭其他的网卡,比如eth0。为了解决这个问题,我们只能将uboot、Linuxkernel、.dtb设备树和根文件系统都烧写到板子的EMMC或NAND上,然后直接启动EMMC或NAND上的系统即可,这样就不需要其他网卡工作了。烧写方法请参考我们的《第二十九章系统烧写》,这里就不详细的讲解了。系统烧写完成以后设置开发板从EMMC或NAND启动,因为我使用的是EMMC核心板,因此设置从EMMC启动,启动以后按照前面的步骤先让ME3630 4G模块连接上网络。确保当前开发板只有一个ME3630对应的ppp0网卡,最后直接ping百度官网即可,结果如图71.2.3.6所示:
图71.2.3.6 ME3630 4G模块ping百度官网
71.2.4 ME3630 4G模块ECM联网测试
对于支持ECM接口的模块可以直接通过ECM上网,ME3630模块支持ECM接口,重启开发板,输入"ifconfig-a"命令可以看到有一个名为"usb0"的网卡,如图71.2.4.1所示:
图71.2.4.1 usb0网卡
这个usb0网卡就是ECM接口对应的网卡,我们需要使用minicom输入一些AT指令,所以要先用minicom打开ttyUSB1,ttyUSB1就是ME3630的AT指令串口,波特率设置为115200。打开以后依次输入如下指令:
①、输入AT指令:
AT+ZSWITCH=L
然后重启开发板。如果模块已经设置为ECM模式的话此步骤就不需要了。
②、使用AT指令+CGDCONT来设置数据参数。联通卡的APN为3gnet,电信卡的APN为ctnet,移动卡的APN为cmnet。比如我现在用的联通卡,所以设置APN为3gnet,命令如下:
AT+CGDCONT=1,"IP","CMNET"
③、发送连接AT命令:
AT+ZECMCALL=1
等待连接成功,连接成功以后会输出如图71.2.4.2所示信息:
图71.2.4.2 ME3630 ECM接口网路连接成
功
连接成功以后打开usb0网卡,命令如下:
ifconfigusb0 up //打开usb0网卡
usb0网卡打开以后输入如下命令获取IP地址:
udhcpc -i usb0
IP地址获取过程如图71.2.4.3所示:
图71.2.4.3 usb0网卡获取IP地址过程
从图71.2.4.3可以看出,usb0网卡获取到的IP地址为10.164.232.36,然后ping一下百度官网,如果能ping通就说明ME3630的ECM接口联网成功。如果提示"bad address 'www.baidu.com'",那么请检查一下DNS服务器地址设置是否正确,打开/etc/resolv.conf文件,然后加入"nameserver 114.114.114.114"即可。
至此ME3630 4G模块的网络连接就已经全部测试完成,大家既可以在正点原子的I.MX6U-ALPHA开发板上使用4G上网了。
71.3 EC20 4G模块实验
71.3.1 EC20 4G模块简介
关于EC20 4G模块的详细资料请找卖家索要!
EC20有多种不同的配置,比如全网通纯数据版本、语音版、带GNSS版等等,建议大家购买的时候至少要选择全网通数据版,因为我们使用4G模块主要还是用于数据通信的。移远的EC20 4G模块采用LTE 3GPP Rel.11技术,支持最大下行速率150Mbps,最大上行速率50Mbps。EC20 4G模块特性如下:
1、一路USB2.0高速接口,最高可达480Mbps。
2、一组模拟语音接口(可选)。
3、1.8V/3.0V SIM接口。
4、1个UART接口。
5、W_DISABLE#(飞行模式控制)。
6、LED_WWAN#(网络状态指示)。
EC20也支持AT指令,本教程不讲AT指令,关于AT指令的使用请参考EC20的相关文档。在正式使用EC20 4G模块之前,请先将其插入到开发板的MiniPCIE座上、上紧螺、插入Nano SIM卡、接上天线,如图71.3.1.1所示:
一切准备就绪以后就可以开始驱动EC20 4G模块了。
71.3.2 EC20 4G模块驱动修改
1、添加USB设备信息
我们需要先在Linux内核中添加EC20的USB设备信息,因为我们前面说了,EC20 4G模块用的USB接口。打开Linux源码的drivers/usb/serial/option.c文件,首先定义EC20的ID宏,内容如下:
示例代码71.3.2.1 EC20 4G模块ID
1/* EC20 4G */
2 #define QUECTEL_VENDOR_ID 0X2C7C
3 #define QUECTEL_PRODUCT_EC20 0X0125
完成以后如图71.3.2.1所示:
继续在drivers/usb/serial/option.c文件里面找到option_ids数组,在此数组里面加入如下内容:
示例代码71.3.2.2 option_ids数组添加EC20 ID信息
{ USB_DEVICE( QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC20)}, /* EC20 4G */
完成以后option_ids数组如图71.2.2.2所示:
继续在drivers/usb/serial/option.c文件里面找到option_probe函数,在此函数里面添加如下内容:
示例代码71.3.2.3 option_probe函数添加的代码
1 /* EC20 */
2if( dev_desc-> idVendor == cpu_to_le16( 0x05c6)&&
3 dev_desc-> idProduct == cpu_to_le16( 0x9003)&&
4 iface_desc-> bInterfaceNumber >= 4)
5 return- ENODEV;
6
7if( dev_desc-> idVendor == cpu_to_le16( 0x05c6)&&
8 dev_desc-> idProduct == cpu_to_le16( 0x9215)&&
9 iface_desc-> bInterfaceNumber >= 4)
10 return- ENODEV;
11
12if( dev_desc-> idVendor == cpu_to_le16( 0x2c7c)&&
13 iface_desc-> bInterfaceNumber >= 4)
14 return- ENODEV;
添加完成以后的option_probe函数如图71.3.2.3所示:
图71.3.2.3修改后的option_probe函数
继续在drivers/usb/serial/option.c文件里面找到option_1port_device结构体变量,在里面加入休眠后唤醒接口,如图71.3.2.4所示:
图71.3.2.4添加的休眠唤醒接口
打开drivers/usb/serial/usb_wwan.c文件,在usb_wwan_setup_urb函数中添加零包处理代码,完成后的usb_wwan_setup_urb函数如下所示:
示例代码71.3.2.4 修改后的usb_wwan_setup_urb函数
1staticstruct urb * usb_wwan_setup_urb( struct usb_serial_port * port,
2int endpoint,
3int dir, void* ctx, char* buf, int len,
4void(* callback)( struct urb *))
5{
6 struct usb_serial * serial = port-> serial;
7 struct urb * urb;
8
9 urb = usb_alloc_urb( 0, GFP_KERNEL); /* No ISO */
10 if(! urb)
11 returnNULL;
12
13 usb_fill_bulk_urb( urb, serial-> dev,
14 usb_sndbulkpipe( serial-> dev, endpoint)| dir,
15 buf, len, callback, ctx);
16
17 /* EC20 */
18 if(dir == USB_DIR_OUT){
19 struct usb_device_descriptor *desc =
&serial->dev->descriptor;
20 if(desc->idVendor == cpu_to_le16(0x05c6)&&
21 desc->iProduct == cpu_to_le16(0x9090))
22 urb->transfer_flags |= URB_ZERO_PACKET;
23
24 if(desc->idVendor == cpu_to_le16(0x05c6)&&
25 desc->iProduct == cpu_to_le16(0x9003))
26 urb->transfer_flags |= URB_ZERO_PACKET;
27
28 if(desc->idVendor == cpu_to_le16(0x05c6)&&
29 desc->iProduct == cpu_to_le16(0x9215))
30 urb->transfer_flags |= URB_ZERO_PACKET;
31
32 if(desc->idVendor == cpu_to_le16(0x2c7c))
33 urb->transfer_flags |= URB_ZERO_PACKET;
34 }
35
36 return urb;
37}
第18~34行就是要添加到usb_wwan_setup_urb函数里面的零包处理代码。至此,Linux内核需要修改的地方就完了。编译一下Linux内核,检查一下代码修改有没有问题,如果修改正确的话就是没有任何问题的。
2、配置Linux内核
我们需要配置Linux内核,使能USB NET、GSM、CDMA驱动等,配置方法和我们在71.2.2小节讲解的ME3630 4G模块的配置方法一样,大家参考71.2.2小节即可。配置完成以后编译一下Linux内核,然后使用新的zImage启动开发板。如果EC20已经插上的话,系统启动以后就会输出如图71.3.2.5所示的信息:
图71.3.2.5 EC20虚拟出的USB接口
从图71.3.2.5可以看出,多了ttyUSB0~ttyUSB3,这4个tty接口就是EC20虚拟出来的,可以查看一下/dev/ttyUSB0~ttyUSB3是否存在,结果如图71.3.2.6所示:
图71.3.2.6 EC20虚拟出来的tty接口
图71.3.2.6中的这4路ttyUSB的含义见表71.3.2.1:
表71.3.2.1四路ttyUSB函数
我们用到最多的就是ttyUSB1和ttyUSB2,如果你购买的EC20模块带有GPS功能,那么就可以通过ttyUSB1接口读取GPS数据。如果你想使用EC20的AT指令功能,那么就使用ttyUSB2接口即可。
3、添加移远官方的GobiNet驱动
移远为EC20提供了GobiNet驱动,驱动源码我们已经放到了开发板光盘中,路径为:1、例程源码->5、模块驱动源码->3、4G模块->移远EC20\EC20_R2.1_Mini_PCIe-C->05 Driver->Linux->GobiNet-> Quectel_WCDMA<E_Linux&Android_GobiNet_Driver_V1.3.0.zip。将Quectel_WCDMA<E_Linux&Android_GobiNet_Driver_V1.3.0/src下的所有.c和.h文件都拷贝到Linux内核中的/driver/net/usb目录下,也就是图71.3.2.7中所示的文件:
图71.3.2.7 需要拷贝的文件
拷贝完成以后打开Linux内核的drivers/net/usb/Makefile文件,在此文件末尾加入如下内容:
示例代码71.3.2.5 修改后的drivers/net/usb/Makefile文件
1 obj- $(CONFIG_USB_GOBI_NET) += GobiNet. o
2 GobiNet- objs := GobiUSBNet. o QMIDevice. o QMI. o
最后在drivers/net/usb/Kconfig文件中加入下所示内容:
示例代码71.3.2.6 drivers/net/usb/Kconfig要添加的内容
1 config USB_GOBI_NET
2 tristate"Gobi USB Net driver for Quectel module"
3 help
4 Support Quectelmodule.
5
6 A modemmanager with support for GobiNet is recommended.
7 Tocompile this driver as a module, choose M here: the module will be calledGobiNet.1
上述内容在drivers/net/usb/Kconfig文件中的位置如图71.3.2.8所示:
图71.3.2.8 内容要添加的位置
完成以后打开Linux内核配置界面,使能前面添加的Gobi驱动,配置路径如下:
-> Device Drivers
->[*] Network device support
->-*- USB Network Adapters
-><*> Gobi USB Net driver for Quectel module
配置如图71.3.2.9所示:
图71.3.2.9 使能Gobi驱动
配置完成以后就重新编译一下Linux内核,然后使用新的zImage启动开发板。启动以后检查一下"/dev/qcqmi2"这个文件是否存在,如果存在的话就说明Gobi驱动工作成功。至此,EC20的驱动就已经修改完成了,接下来就是使用EC20来实现联网。
71.3.3 quectel-CM移植
要使用EC20,我们需要用到移远提供的quectel-CM这个软件,这个软件是移远提供的网络管理工具,软件源码已经放到了开发板光盘中,路径为:1、例程源码->5、模块驱动源码->3、4G模块->移远EC20->EC20_R2.1_Mini_PCIe-C->05 Driver->Linux->GobiNet->WCDMA<E_QConnectManager_Linux&Android_V1.1.34.zip。将WCDMA<E_QConnectManager_Linux&Android_V1.1.34.zip这个压缩包进行解压,得到quectel-CM这个文件夹,然后将quectel-CM文件夹拷贝到Ubuntu中。拷贝完成以后进入到Ubuntu中的quectel-CM文件夹,使用如下命令进行交叉编译:
make CROSS_COMPILE=arm-linux-gnueabihf-
编译完成以后得到一个名为"quectel-CM"软件,如图71.3.3.1所示:
图71.3.3.1 编译出来的quectel-CM软件
将图71.3.3.1中编译出来的quectel-CM软件拷贝到开发板根文件系统的/usr/bin目录下,命令如下:
sudo cp quectel-CM /home/zuozhongkai/linux/nfs/rootfs/usr/bin/ -f
拷贝完成以后就可以使用quectel-CM软件来实现EC20联网测试了。
71.3.4 EC20上网测试
在开发板上输入如下命令完成EC20的4G网络连接:
quectel-CM -s cenet &
注意,quectel-CM软件会使用到udhcpc来获取IP地址,所以一定要确保当前根文件系统下存在udhcpc。当4G网络连接成功以后就会获取到IP地址,如图71.3.4.1所示:
图71.3.4.1 EC20 4G网络连接成功并获取到IP地址
从图71.3.4.1可以看出,EC20对应的网卡名字为"eth2",输入"ifconfigeth2"即可查看eth2网卡的详细信息,如图71.3.4.2所示:
图71.3.4.2 eth2网卡详细信息
4G网络测试需要关闭其他网卡,否则的话网络测试可能有问题,但是我们现在是通过网络启动的系统,并且通过NFS挂载的根文件系统,因此我们没法关闭其他的网卡,比如eth0。为了解决这个问题,我们只能将uboot、Linuxkernel、.dtb设备树和根文件系统都烧写到板子的EMMC或NAND上,然后直接启动EMMC或NAND上的系统即可,这样就不需要其他网卡工作了。烧写方法请参考我们的《第二十九章系统烧写》,这里就不详细的讲解了。系统烧写完成以后设置开发板从EMMC或NAND启动,因为我使用的是EMMC核心板,因此设置从EMMC启动,启动以后按照前面的步骤先让EC20连接上网络。确保当前开发板只有一个EC20对应的eth2网卡,然后直接直接ping百度官网即可,结果如图71.3.4.3所示:
图71.3.4.3 ping百度官网成功
如果ping百度官网没有问题,那么就表示EC20 4G模块在我们的I.MX6U-ALPHA开发板上工作
嵌入式基础知识归纳、笔面试预备
由于字数有限,可关注公众号获取完整原文:xfxuezhang
堆和栈的区别
数据结构中的堆和栈
栈 :是一种可以实现“先进后出 ”的存储结构。操作仅限于栈的顶部。常应用于实现递归功能方面的场景
堆 :是一种经过排序的完全二叉树 。其中,节点是从左到右 填满的,并且最后一层的树叶都在最左边;每个节点的值都小于(或者都大于)其子节点的值。因为堆有序的特点,一般用来做数组中的排序,称为堆排序。
内存分配中的堆和栈
分配方式
栈 :由编译器自动分配和释放的,处于相对较高的地址,其栈地址是向下增长的。
堆 :由程序员手动完成申请和释放,地址是向上增长的。
存储内容
栈 :主要用于存放函数的参数与局部变量等
堆 :具体存储内容由程序员根据需要决定存储数据
生存周期
栈 :其生存周期也只在函数的运行过程中,在运行后就释放,并不可以再次访问
堆 :动态内存的整个生存期是由程序员自己决定的,使用非常灵活。但必须及时释放它,否则将会导致运行的程序出现内存泄漏等错误。
分配效率
栈 :栈内存分配运算内置于处理器的指令集中,它的效率一般很高
堆 :由函数库提供,机制复杂(由链表记录空闲内存区域),分配效率比栈要低得多
内存碎片
栈 :不会存在这个问题
堆 :频繁分配和释放不同大小的堆空间会造成内存空间的不连续,从而造成大量碎片,导致程序效率降低
数据结构
满二叉树 :二叉树中除了叶子结点,每个结点的度都为 2。完全二叉树 :二叉树中除去最后一层节点为满二叉树,且最后一层的结点依次从左到右分布。一颗完全二叉树上有个结点,求叶子节点个数: 除以2向上取整 二叉树性质因为所以由于该等式右边为奇数,左边的只能是偶数又因为完全二叉树中度为结点个数要么是要么是,所以只能是因此所以二叉树的性质
二叉树中,第 层最多 有 个结点。如果二叉树的深度为 ,那么此二叉树最多 有 个结点。二叉树中,终端结点数(叶子结点数)为 ,度(子树数量)为 的结点为 ,度为 的结点数为 ,则 。总结点。包含个结点的二叉树 的高度至少 为。个结点的完全二叉树 的深度为 。 表示取小于 的最大 整数。当 时,父亲结点为结点 。( 时,表示的是根结点,无父亲结点)如果 (总结点的个数) ,则结点 肯定没有左孩子(为叶子结点);否则其左孩子是结点 。如果 ,则结点肯定没有右孩子;否则右孩子是结点 。判断合法的出栈序列
按顺序入栈的序列,任意元素 e ,比 e 先入栈的元素,并且比 e 后出栈的元素,一定是逆序的。
例: 设栈的入栈序列是 1 2 3 4,则下列不可能是其出栈序列的是( )。A. 1 2 4 3B. 2 1 3 4C. 1 4 3 2D. 4 3 1 2E. 3 1 2 4
解法: 以E选项讲解
选择任意元素e ,这里选择3比3后出栈的有三个元素 1 2 4其中比3先入栈的有两个元素 1 2但是1 2是正序的,而不是逆序的所以这个序列不是合法出栈序列算法相关
排序算法的时间复杂度和空间复杂度
this指针
this指针指向被调用的成员函数所属的对象 。本质是一个指针常量 ,储存了调用他的对象的地址 。
用途:
当形参和成员变量同名时,可用this指针来区分在类的非静态成员函数中返回对象本身 ,可使用return *this特点:
只能在成员函数 中使用,在全局函数、静态成员函数中都不能使用 this 。this始终指向当前对象,静态成员函数属于类。this 指针是在成员函数的开始前构造 ,并在成员函数的结束后清除 。和函数的其他参数生命周期一样。this 指针会因编译器不同而有不同的存储位置,可能是栈、寄存器或全局变量 。编译器在生成程序时加入了获取对象首地址的相关代码并把获取的首地址存放在了寄存器中。大多数编译器是在创建对象 的时候,向ecx寄存器传递this指针。计算机网络
计算机网络笔记
TCP/IP五层模型
第一个字段第二个字段网络号,标志主机或路由器所连接到的网络。主机号,标志该主机或路由器
类别网络号主机号范围A类(0)8位24位1.0.0.1 - 126.255.255.254B类(10)16位16位128.1.0.1 - 191.254.255.254C类(110)24位8位192.0.1.1 - 223.255.254.254
类别最大网络数第一个网络号最后一个网络号最大主机数A类126(2^7 - 2)1.0.0.0126.0.0.02^24 - 2B类16383(2^14 - 1)128.1.0.0191.255.0.02^16 - 2C类2097151(2^21 - 1192.0.1.0223.255.255.02^8 - 2
注:
A类网络号减2:1、IP全0表示 本网络; 2、IP 127(01111111)表示 环回 测试地址 A类主机号减2:1、全0表示所连接到的单个网络地址; 2、全1表示所有主机 B类网络号减1:1、前面两位(1 0)已经固定,不会出现全0或全1; 2、128.0.0.0不指派 B类主机号减2:扣除全0和全1的情况 C类网络号减1:1、前面两位(1 1 0)已经固定,不会出现全0或全1; 2、192.0.0.0不指派 C类主机号减2:扣除全0和全1的情况 其他 控制消息 是指网络通不通、主机是否可达、路由是否可用 等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递 起着重要的作用。IP地址放在IP数据报的首部,而硬件地址放在MAC帧的首部。在网络层和网络层以上使用的是IP地址,而数据链路层及以下使用的是硬件地址使用抽象的IP地址,而不直接使用硬件地址通信的原因:全世界存在不同的网络使用不同的硬件地址,要使这些异构网络能够互相通信就必须进行非常复杂的硬件地址转换工作,但IP编址把这个复杂问题解决了 IP首部的固定长度是 20字节 IP数据报的数据部分在 4字节的整数倍 时开始数据报能在互联网中经过的路由器的最大数值是 255 , 若把TTL初始值设置为“1”,表示 这个数据报只在本局域网中传送 划分子网的方法:从网络的主机号借用若干位作为子网号 IP地址 = {<网络号>,<子网号>,<主机号>}子网掩码:将三级IP地址的子网掩码与收到的数据报的目的IP地址逐位相与,得出所要找的子网的网络地址 无分类编制CIDR的特点:1、消除了传统的A、B、C类地址以及划分子网的概念;2、把网络前缀相同的连续的IP地址组成一个“CIDR地址块” IP = {<网络前缀>,<主机号>}CIDR斜线记法:IP地址后面加上斜线“/”,然后写上网络前缀所占的位数 网络号 的位数直接决定了可以分配的网络数 ;主机号 的位数则决定了网络中最大的主机数 。Linux相关
文件权限符号
第一个字符表示文件类型 :普通文件:-目录文件:d字符设备文件:c块设备文件:b符号链接文件:l命名管道文件:psocket文件:sr:读权限。w:写权限。x:可执行权限。-:没有权限。s:SET位可执行权限。SUID:只对二进制文件有效SGID:对普通文件和目录有效t:粘滞位权限。Sticky。在该目录创建的文件或目录只有创建者才有权限删除。-rwxr-xr-x:文件类型(普通文件-),所有者权限(r读/w写/x可执行),所属组的权限(r读/x可执行),其它用户权限(x可执行)权限属性后面有点 (.),表示该文件带有"SELinux的安全上下文";权限属性后面标记为加号 (+),表示使用了ACL(Access Control List)权限。如果文件权限后面附加一个空格 ,则表示系统没有可替换的访问控制措施。修改文件权限
chgrp(change group):改变文件所属用户组chown(change owner):改变文件所有者chmod(change mod):修改文件的权限 # 设置一个可执行文件,不让其他人修改 chmod 755 filename # -rwxr-xr-x # 让文件拥有执行权限,但不知道原权限 chmod a+x filename命令身份操作文件参数chmodu g o a+(加入) -(除去) =(设置)r w x文件或目录u = user, g = group,o = other, a = all目录结构
/ :根目录只有root用户具有该目录下的写权限/bin :用户二进制文件包含二进制可执行文件,包含常见的Linux命令。/sbin :系统二进制文件包含二进制可执行文件,但该目录下的Linux命令通常由系统管理员使用,对系统进行维护/etc :配置文件包含所有程序所需的配置文件,也包含了用于启动/停止单个程序的启动/关闭shell脚本/dev :设备文件包括终端设备、USB或连接到系统的任何设备/proc :进程信息这是一个虚拟的文件系统,包含正在运行的进程的信息。/var :变量文件可以找到内容可能增长的文件。包括:/var/log:系统日志文件/var/lib:包和数据库文件/var/mail:电子邮件/var/spool:打印队列/var/lock:锁文件/tmp :临时文件包含系统和用户创建的临时文件,系统重启后,文件都将删除/usr :用户程序包含二进制文件、库文件、文档和二级程序的源代码。包括:/usr/bin:包含用户程序的二进制文件/usr/sbin:包含系统管理员的二进制文件/usr/lib:包含/usr/bin和/usr/sbin用到的库/usr/local:包含从源安装的用户程序/home :HOME目录所有用户用home目录来存储他们的个人档案/lib :系统库包含支持位于/bin和/sbin下的二进制文件的库文件/boot :引导加载程序文件把汗引导加载程序相关的文件/opt :可选的附加应用程序包含从个别厂商的附加应用程序。附加应用程序应该安装在/opt或/opt的子目录下/mnt :挂载目录临时安装目录,系统管理员可以挂载文件系统/media :可移动媒体设备用于挂载可移动设备的临时目录常用命令
新手必须掌握的Linux命令
常见执行Linux命令的格式:命令名称 [命令参数] [命令对象]
arch:显示机器的处理器架构
uname -a:完整地查看当前系统的内核名称、主机名、内核发行版本、处理器类型等信息
uname -r:显示内核版本
文件系统
文件系统是针对于存储器分区 而言的,而非存储芯片。
基于FLASH的文件系统 (基于MTD驱动层)jffs2(Journalling Flash FileSystem v2)日志闪存文件系统主要用于NOR 型闪存,不适合容量较大的NAND。特点 :可读写的、支持数据压缩的、基于哈希表的日志型文件系统,并提供了崩溃/掉电安全保护,提供“写平衡”支持等。缺点 :当文件系统已满或接近满时,因为垃圾收集的关系而使jffs2的运行速度大大放慢。存储设备
Flash
结合ROM和RAM的长处,具备可擦除可编程的性能,不会断电丢失数据,可以快速读取数据。
NOR Flash
接口时序同SRAM,易使用读取速度较快擦除速度慢写入速度慢(需要先擦除)随机存取速度较快,支持XIP,适用于代码存储。常用于存放引导程序、根文件系统等单片容量较小NAND Flash
地址/数据线复用,数据位较窄读取速度较慢擦除速度快写入速度快顺序读取较快,随机存取速度慢,适用于数据存储。常用于存放用户文件系统等。单片容量较大嵌入式平台启动流程
系统从装有启动代码的Nor Flash启动后,初始化对应的硬件,包括SDRAM等,然后将Nand Flash上的Linux 内核读取到内存中,做好该做的事情后,就跳转到SDRAM中去执行内核了,然后内核解压(如果是压缩内核的话,否则就直接运行了)后,开始运行,在Linux内核启动最后,去Nand Flash上,挂载根文件,比如jffs2,yaffs2等,挂载完成,运行初始化脚本,启动consle交互,才允许你通过console和内核交互。至此完成整个系统启动过程。
RAM(Random Access Memory)
随机访问存储器,直接与CPU交换数据,也叫内存。可以随机读写,速度很快。断电后数据丢失。
SRAM (Static RAM)
静态RAM,速度非常快,不需要刷新电路即可保存数据。集成度较低,非常昂贵,多用于CPU的一二级缓存L1/L2 Cache。DRAM (Dynamic RAM)
动态RAM,速度比SRAM慢,需要定时刷新充电才能保存数据。比SRAM便宜很多,多用于计算机内存。DDR RAM (Double-Data-Rate RAM)
可以在一个时钟读写两次数据,使得数据传输速度加倍了相关问答
android系统盘根目录中的(文件)谁给讲一下是干什么的?-ZOL问答sdcard:是SD卡中的FAT32文件系统挂载的目录etc:指向/system/etc,众所周知的配置文件存放目录system:是一个很重要的目录,系统中的大部分东西都在这里了...
makefile中的@$是什么意思?OBJS_BOOTPACK=bootpack.objnaskfu...[回答]$@:代表规则中的目标文件名.如果目标是一个文档(Linux中,一般称.a文件为文档),那么它代表这个文档的文件名.在多目标的模式规则中,它代表的是哪个触...
RRAM最近怎么没消息了?资讯电路方案开发板数据手册部件采购...1首页设计技巧新品发布博客原创一文读懂RRAM,为啥说它最有希望取代DRAM?2017-12-1211:02:06...存储器.....
安装了SSD,需要再安装傲腾内存吗?欢迎在点击右上角关注:「太平洋电脑网」,更多有趣资讯等着您哦。没啥必要了。我们做过一个测试,结果是还是120G的SSD好一点。来看看实验过程:测试平台...通过...
PS5与XSX如何选择?巧了,今天正好在头条发布了一篇文章,聊PS5和XboxSeriesX,干脆就直接全文搬运了算了!开篇就不多说了,直接上正文关键部分!功能:两款主机难分高下AMD为X...硬...
为什么nfs一直 挂载 失败-ZOL问答/要挂载的目录/挂载点。刚刚在希赛上看见这个资料了,希望可以帮助到你!有用(0)回复和你的使用目的有关:1、开发板linux系统和PC机交换数据(文件)2、在开...
金士顿新推出的KC600系列SATA SSD的性价比如何?接口:支持SATSARev.3.0(6Gb/s),并且兼容STA2.0(3Gb/s);容量:256GB、512GB、1024GB、2048GB;主控:慧荣(SMI)SM2259;...
256G的固态要不要分区?首先呢,硬盘不分区是不能用的,这个不管机械硬盘还是固态硬盘都一样的,其次呢,你在SSD上装系统的时候,即使你只设置分一个区的时候其实分区也不止一个,使用M...假...
手机系统闪存(Flash Memory)包含哪些。。-ZOL问答norflash主要是用在低端机上面,nand和nor的作用是一样的都是用来存储数据的,只不过nor可以直接在上面跑代码,而nand不能,nor里面的数据不必加载到ram上面去...
固态硬盘该如何挑选?金泰克S300120GBSSD参考价:299元质保期:三年质保推荐理由:价格便宜、国产老牌子金泰克S300120GBSSD采用业界流行的全金属设计,通体金属,能够较大...除.....