最近发生了一个问题,由于之前ppp拨号的断线检测与自动重连是使用的网上流传的ping114方案,如果ping114不通,再去kill掉拨号进程再去重新拨号,和由于ppp拨号的modem使用了,cmux协议映射出来的虚拟串口,和由于gprs模块的电源上电的操作和断电的操作都是一样的,所以引发了许多问题。
应用程序使用的是cmux协议映射出来的虚拟串口,ppp拨号使用的modem也是cmux映射出来的虚拟串口,所以这就引发了一个问题,那就是cmux协议一定要在应用程序中使用虚拟串口之前,cmux协议就要开始运行,但是cmux协议运行出来的虚拟串口要想使用,必须gprs模块(支持0710gprs协议,也就是cmux)要上电,gprs模块是带电的状态,然后运行cmux,虚拟串口出来,然后ppp拨号使用一个虚拟串口,应用程序使用另一个虚拟串口,如果cmux还没有映射出来串口,应用程序就去使用了个那个不存在的串口文件,那是肯定不行的。
首先gprs模块带电,然后运行cmux,然后ppp拨号,然后应用程序,能想到的就是这个执行顺序。
但过程中由于使用的flash是spi flash,文件系统使用的是jffs2文件系统,使得系统的挂载后到应用程序,这个过程的时间很长,那是因为spi flash的读写速度很慢,而且由于jffs2这个文件系统再每次挂载时,都要去扫描一遍自身,同时要跟物理内存建立好关系,所以很慢,即使我已经将内核配置成了支持jffs2的按节点的信息去进行扫描,也将jffs2文件系统制作成了可以按节点去扫描的特性,虽然挂载到flash上的速度变快了,但是应用程序想要在文件系统刚挂载到flash上时,就要完全运行起来是不行的,因为在文件系统和内存建立映射的这一过程还是很慢的,应用程序会在全局变量那里等待着,因为内存还没有加载好,所以导致很慢。
ppp拨号的断线自动重拨机制,并不是向网上流传的那种千篇一律的自己写一个脚步,不断的去ping114等来监测是否ping通,ping不通则pkill掉pppd进程然后重新拨号这种机制。这种机制在gprs模块的断电操作和上电操作不一样时,使用是可以的,效果会好,同时也要保证114等要稳定。
我的情况,我的gprs模块上电断电操作是一样的,我使用了cmux协议,当ping114不行时,如果我去kill掉pppd,然后重新拨号,这种是不行的,应该在kill掉pppd后要将gprs模块电源重启后,在去重新pppd,然而我不知道gprs模块的电源状态,即使我知道了gprs模块的电源状态,但由于我还使用了cmux协议,如果gprs模块重启了,那么cmux协议映射出来的串口就是不能用的了,因为这是两者间的协议,gprs模块重启,已经认为,自己不是在mux模式下了,这个时候你的应用程序还在使用着不能使用的虚拟串口。你要是将cmux协议干掉了,然后重新在运行一遍cmux协议,我想这种逻辑并不是好的。
后来我研究了一下ppp的option脚步,发现这个脚步中有很还多参数,
lcp-echo-interval n
lcp-echo-failure n
lcp-restart n
maxfail n
persist
这五个参数就很有用,第一个参数,n秒间隔向lcp发送请求包。第二个参数,如果发送向lcp的请求包,你没有收到n个,pppd断线。第三个参数,lcp重传的超时时间。第四个参数,ppp断线时,自动重拨的次数。第五个参数,表示pppd一直在线,断线自动重拨,如果重拨都不成功,pppd进程死亡。
这样pppd就可以自动检测在线情况,然后进行重拨。
后来我将逻辑改了,不在去手动ping了,而是检测到pppd进程不存在了,就去重启系统。每次系统上电时,改变一次gprs电源状态,单独写了一个应程序去给gprs发送AT命令,如果回复OK,表示模块带电,后面就执行cmux,然后拨号,然后运行另一个进程。如果不回复OK。表示模块不带电,然后切换模块电源状态,然后继续cmux,拨号,另一个进程。gprs模块如果第一发现sim卡不存在时,模块只要一直在带电状态,没有重启,它会一直认为sim卡不存在。