当pppd处于活动状态时,将AT命令发送到SIM900

JSE*_*JSE 6 gsm at-command pppd raspberry-pi sim900

我有一个连接了SIM900 GSM附加板的Raspberry Pi.我已pppd按照本指南设法建立GPRS连接.(这是针对不同的GSM模块,但步骤相同)

我想定期向AT+CCLK?SIM900 发送一个AT命令()来检查时钟.我已经管理发送ad hoc AT命令使用screen但是什么时候pppd我不能screen用来连接到串行线.它只是立即退出说[screen is terminating].我猜这是因为pppd它正在使用它连接到互联网.

问:如何在不关闭pppd的情况下获得时钟时间?

查看用户手册的一部分,它说SIM900有一个符合GSM0710标准的多路复用器.这有用吗?如果是这样我将如何实现这一目标?

JSE*_*JSE 5

好吧,我几乎已经解决了这个问题,但最后一步遇到了障碍.以为我会展示我设法做的事情,因为它可以帮助别人.

我发现这篇关于堆栈溢出的帖子列出了3种实现此目的的可能方法.当PPP(在我有限的经验中)很好地处理这个问题时,我不想通过AT命令控制gprs.RPi只有一个串口,因此无法通过多个串行接口进行多路复用.

因此,我通过单个串行接口进行多路复用,希望SIM900支持这一点.我在这里找到了使用GSM07.10标准的SIM900多路复用器上的用户手册.

我找不到有关如何设置多路复用的大量信息,但最终在挖掘后我在linux内核的n_gsm模块上找到了这个文档.我可以跟随它所说的但不足以编写我自己的程序来设置一些虚拟串口.

值得庆幸的是,经过一些谷歌搜索后,我发现这位非凡的绅士已经创建了一个C程序,使用n_gsm模块为我们设置虚拟串口.

我按照说明下载,配置和构建了程序,并尝试加载n_gsm模块.不幸的是,RPi不包含n_gsm模块作为默认值,所以我不得不去构建一个新的内核,并添加n_gsm作为模块.我按照RPi网站上的指示非常好.

对于SIM900,我必须更改第322行以删除命令&w的结尾AT+IPR.它应该知道如下:

if (send_at_command(serial_fd, "AT+IPR=115200\r") == -1) errx(EXIT_FAILURE, "AT+IPR=115200: bad response");

sleep(1.5)在尝试读取响应之前,我还编辑了第128行,因为它有时会返回错误,因为它没有及时得到响应.

所以我运行cmux程序(使用sudo创建新的/ dev/ttyGSM*设备)并运行AT命令,设置线路规则并创建新的虚拟串行设备,但是当我尝试打开一个串行设备时screen /dev/ttyGSM1 115200屏幕终端返回[screen is terminating].

我做了sudo fuser /dev/ttyGSM1什么没有返回任何其他进程正在使用它.

然后我尝试echo AT > /dev/ttyGSM1了返回-bash: /dev/ttyGSM1: Level 2 halted.

我不确定这是指什么,也无法找到有关此消息的任何信息.它能谈论OSI模型的第2层,也就是数据链路层吗?

无论如何,这是我有多远.我已经决定暂时把它放在一边,只是使用NTP,但我希望这可以帮助其他人.如果您确实找到了解决方案,或者可以提出我可能错过的建议,请说明.谢谢


Tho*_*ker 4

我会回答这个问题,因为它也可能对其他人有帮助。但我想首先分享我在复用 UART 接口方面的经验。当我设置完一切后,似乎一切都运行良好。但当我尝试连接 VPN 或传输一些文件时,Raspbian 完全冻结了。我不确定到底是什么问题,但似乎与n_gsmcmux组件有关。不过,低带宽应用程序(如 ping、telnet 或 SSH)似乎运行良好。n_gsm模块被标记为实验性的,可能不应该在生产中使用。


n_gsm默认情况下,Raspbian 中不包含内核模块。要开始使用 CMUX 驱动程序,我们需要更新 Raspbian 并下载内核源文件,然后才能编译模块n_gsm

  1. 确保您的系统是最新的,安装依赖项并更新内核
sudo -i
apt update
apt dist-upgrade
apt install bc bison git build-essential flex libssl-dev
rpi-update
sync
reboot
Run Code Online (Sandbox Code Playgroud)
  1. 下载内核源代码,以便我们可以制作自己的内核模块
wget -O /usr/bin/rpi-source https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source
chmod +x /usr/bin/rpi-source
/usr/bin/rpi-source -q --tag-update
rpi-source
Run Code Online (Sandbox Code Playgroud)
  1. 构建用于实验性 GSM MUX 线路规则支持的内核模块
cd /root/linux/drivers/tty/
make -C /lib/modules/$(uname -r)/build M=$(pwd) -e CONFIG_N_GSM=m modules
cp /root/linux/drivers/tty/n_gsm.ko /lib/modules/`uname -r`/kernel/drivers/tty/
depmod
modprobe n_gsm
Run Code Online (Sandbox Code Playgroud)

如果您想在启动时自动加载该模块,您可能还想将该模块添加到 /etc/modules 中。

  1. 下载并编译 GSM MUX 驱动程序 (CMUX)
cd /usr/local/src/
git clone https://github.com/Rtone/cmux.git
cd cmux
Run Code Online (Sandbox Code Playgroud)

通常你需要cmux.c在编译之前进行编辑。这是我用于设置的差异。

diff --git a/cmux.c b/cmux.c
index 1af0f50..f13edfe 100644
--- a/cmux.c
+++ b/cmux.c
@@ -29,6 +29,7 @@
 #include <linux/types.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/sysmacros.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <err.h>
@@ -50,13 +51,13 @@
 #endif

 /* serial port of the modem */
-#define SERIAL_PORT    "/dev/ttyS1"
+#define SERIAL_PORT    "/dev/ttyAMA0"

 /* line speed */
 #define LINE_SPEED     B115200

 /* maximum transfert unit (MTU), value in bytes */
-#define MTU    512
+#define MTU    1400

 /**
 * whether or not to create virtual TTYs for the multiplex
@@ -66,7 +67,7 @@
 #define CREATE_NODES   1

 /* number of virtual TTYs to create (most modems can handle up to 4) */
-#define NUM_NODES      4
+#define NUM_NODES      2

 /* name of the virtual TTYs to create */
 #define BASENAME_NODES "/dev/ttyGSM"
@@ -313,15 +314,9 @@ int main(void) {
        *       to fit your modem needs.
        *       The following matches Quectel M95.
        */
-       if (send_at_command(serial_fd, "AT+IFC=2,2\r") == -1)
-               errx(EXIT_FAILURE, "AT+IFC=2,2: bad response"); 
-       if (send_at_command(serial_fd, "AT+GMM\r") == -1)
-               warnx("AT+GMM: bad response");
        if (send_at_command(serial_fd, "AT\r") == -1)
                warnx("AT: bad response");
-       if (send_at_command(serial_fd, "AT+IPR=115200&w\r") == -1)
-               errx(EXIT_FAILURE, "AT+IPR=115200&w: bad response");
-       sprintf(atcommand, "AT+CMUX=0,0,5,%d,10,3,30,10,2\r", MTU);
+       sprintf(atcommand, "AT+CMUX=0,0,0,%d,253,3,254,0,0\r", MTU);
        if (send_at_command(serial_fd, atcommand) == -1)
                errx(EXIT_FAILURE, "Cannot enable modem CMUX");
Run Code Online (Sandbox Code Playgroud)

进行更改后,我们应该准备好编译、安装和运行多路复用器。

diff --git a/cmux.c b/cmux.c
index 1af0f50..f13edfe 100644
--- a/cmux.c
+++ b/cmux.c
@@ -29,6 +29,7 @@
 #include <linux/types.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/sysmacros.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <err.h>
@@ -50,13 +51,13 @@
 #endif

 /* serial port of the modem */
-#define SERIAL_PORT    "/dev/ttyS1"
+#define SERIAL_PORT    "/dev/ttyAMA0"

 /* line speed */
 #define LINE_SPEED     B115200

 /* maximum transfert unit (MTU), value in bytes */
-#define MTU    512
+#define MTU    1400

 /**
 * whether or not to create virtual TTYs for the multiplex
@@ -66,7 +67,7 @@
 #define CREATE_NODES   1

 /* number of virtual TTYs to create (most modems can handle up to 4) */
-#define NUM_NODES      4
+#define NUM_NODES      2

 /* name of the virtual TTYs to create */
 #define BASENAME_NODES "/dev/ttyGSM"
@@ -313,15 +314,9 @@ int main(void) {
        *       to fit your modem needs.
        *       The following matches Quectel M95.
        */
-       if (send_at_command(serial_fd, "AT+IFC=2,2\r") == -1)
-               errx(EXIT_FAILURE, "AT+IFC=2,2: bad response"); 
-       if (send_at_command(serial_fd, "AT+GMM\r") == -1)
-               warnx("AT+GMM: bad response");
        if (send_at_command(serial_fd, "AT\r") == -1)
                warnx("AT: bad response");
-       if (send_at_command(serial_fd, "AT+IPR=115200&w\r") == -1)
-               errx(EXIT_FAILURE, "AT+IPR=115200&w: bad response");
-       sprintf(atcommand, "AT+CMUX=0,0,5,%d,10,3,30,10,2\r", MTU);
+       sprintf(atcommand, "AT+CMUX=0,0,0,%d,253,3,254,0,0\r", MTU);
        if (send_at_command(serial_fd, atcommand) == -1)
                errx(EXIT_FAILURE, "Cannot enable modem CMUX");
Run Code Online (Sandbox Code Playgroud)
  1. 使用新的串行接口

我们现在应该能够使用新界面了。/dev/ttyAMA0我们现在可以使用/dev/ttyGSM1和来代替使用/dev/ttyGSM2。我使用第一个与 pppd 和第二个同时发送 AT 命令。由于某种原因我无法继续使用wvdial,所以我完全放弃了它并开始pppd直接使用。我为两者cmux创建pppd了一个 systemd 服务,该服务在启动时依次运行,因此在启动时,Raspbian 正在设置多路复用器并通过 PPP 与互联网连接。当连接有效时,我将发送一条 SMS 消息(通过辅助多路复用器)来报告终端现已在线。


我也在Seeed 论坛上写了这篇文章来回答类似的问题。我很好奇是否有人分享我的稳定性经验,或者是否有人能够分享一些改进。