【问题标题】:Sending AT commands to SIM900 whilst pppd is active在 pppd 处于活动状态时向 SIM900 发送 AT 命令
【发布时间】:2020-01-14 17:24:53
【问题描述】:

我有一个连接了 SIM900 GSM 附加板的 Raspberry Pi。通过关注this guide,我设法与pppd 建立了GPRS 连接。 (GSM模块不同,但步骤相同)

我想定期向 SIM900 发送 AT 命令 (AT+CCLK?) 以检查时钟。我已经使用screen 管理发送临时AT 命令,但是当pppd 启动时,我无法使用screen 连接到串行线路。它会立即退出并说[screen is terminating]。我猜这是因为pppd 正在使用它连接到互联网。

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

查看user manual 的一部分,它说SIM900 有一个为GSM0710 标准设计的多路复用器。这会有用吗?如果是这样,我将如何实现这一目标?

【问题讨论】:

    标签: raspberry-pi gsm at-command pppd sim900


    【解决方案1】:

    好的,我几乎解决了这个问题,但卡在了最后一个障碍。我想我会展示我所做的事情,因为它可能会帮助其他人。

    我在堆栈溢出中找到了this other post,它列出了实现此目的的 3 种可能方法。当 PPP(以我​​有限的经验)很好且轻松地处理这个问题时,我不想通过 AT 命令控制 gprs。 RPi 只有一个串口,所以我无法复用多个串口。

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

    我找不到太多关于如何设置多路复用的信息,但最终我在 linux 内核中的 n_gsm 模块上找到了this 文档。我几乎可以按照它在说什么,但还不足以编写我自己的程序来设置多个虚拟串行端口。

    谢天谢地,在google了一番之后,我发现这位非凡的绅士有created a C program可以使用n_gsm模块为我们设置虚拟串口。

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

    对于 SIM900,我必须更改第 322 行以删除 AT+IPR 命令末尾的 &w。它应该知道的样子:

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

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

    所以我运行 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,但我希望这对其他人有帮助。如果您确实找到了解决方案或可以提出一些我可能错过的建议,请务必说出来。谢谢

    【讨论】:

      【解决方案2】:

      我会回答这个问题,因为它也可能对其他人有所帮助。但我想先分享我在多路复用 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
      
      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
      
      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
      

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

      1. 下载并编译GSM MUX驱动(CMUX)
      cd /usr/local/src/
      git clone https://github.com/Rtone/cmux.git
      cd cmux
      

      通常需要在编译前编辑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");
      

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

      make
      cp cmux /usr/bin/cmux
      cmux
      
      1. 使用新的串行接口

      我们现在应该可以使用新界面了。我们现在可以同时使用/dev/ttyGSM1/dev/ttyGSM2,而不是使用/dev/ttyAMA0。我将第一个与 pppd 一起使用,第二个用于同时发送 AT 命令。由于某种原因,我无法继续使用wvdial,所以我完全放弃了它并开始直接使用pppd。对于cmuxpppd,我创建了一个在启动时运行的 systemd 服务,因此在启动时 Raspbian 正在设置多路复用器并通过 PPP 与 Internet 连接。当连接处于活动状态时,我正在发送一条 SMS 消息(通过辅助多路复用器)以报告终端现在在线。


      我也在Seeed forum to answer a similar question 上写了这篇文章。我很好奇是否有人分享我在稳定性方面的经验,或者是否有人能够分享一些改进。

      【讨论】:

      • 您好,我尝试了您的步骤,但在下载内核时遇到了问题。在使用rpi-source 时,我遇到了以下问题:``` Makefile:590: include/config/auto.conf: No such file or directory Makefile:621: include/config/auto.conf.cmd: No such file or directory /bin/sh: 1: flex: not found scripts/Makefile.lib:188: recipe for target 'scripts/kconfig/zconf.lex.c' failed ``` 还有几行我不能在评论中写这里。请帮帮我。
      • @theashwanisingla 似乎缺少flex 先决条件。您可以使用apt install flex 安装它,然后就可以了。
      • 您好,我按照您的建议安装了 flex。但是在构建内核模块的第三步中执行 make 命令时仍然遇到同样的问题。
      • @theashwanisingla 也许这个来源可以帮助你? github.com/notro/rpi-source/wiki
      【解决方案3】:

      我也在尝试同样的方法,你的帖子对我帮助很大,最后我按照指南成功地做到了:https://github.com/guowenxue/embedded_project/tree/master/program/ldattach_gsm0701

      没有 n_gsm 驱动程序的补丁,实际上这样做设备1 到3 消失了。使用标准的 n_gsm.c,ldattach 创建了 63 个设备 1 到 4 正在工作,其他的没有。

      我在设置方面玩了很多,如果您有任何问题,我可以将整个 ldattach.c 发布给您,无论如何我认为它会作为标准工作。

      现在唯一的缺点是当使用 ppp 时带宽太低以至于大多数 at 命令需要几秒钟才能回复,我也在努力让 pop 运行良好,现在真的很慢。

      我认为我应该降低虚拟串行的带宽,因为我没有硬件流量控制(我也在 ldattach 的串行配置中禁用了它)

      让我知道它是否适合你。

      【讨论】:

      • 在这里恢复旧帖子 - 但有类似问题(移远 M95 除外)。开箱即用,PPP 运行良好。我已经按照上面的方法重新编译了内核以添加 n_gsm,并且可以使用 cmux 获得 4 个 ttyGSM* 设备。在此之后,我可以向 ttyGSM1 发送 AT 命令,但 ppp 现在已损坏 - 似乎不适用于任何 ttyGSM* 设备。如果我不使用 cmux,它将无法在 /dev/serial0 上工作(就像以前一样) - 尽管 cmux 在启动 ppp 时对 /dev/serial0 工作,但它在聊天脚本中的第一个 AT 命令上超时
      【解决方案4】:

      我遇到了同样的问题([屏幕正在终止],第 2 级停止)。注意write() cmux AT 命令到串行端口和通过ioctl() 设置线路规则之间的sleep() 延迟。延迟应该。如果您没有及时设置线路规则,调制解调器有超时从 cmux 模式重置。 Here 是一些细节和证明。

      至于我,我完全消除了这种延迟。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多