2024-03-16
在本地没有联网的数字中继或本地数字中继较远的情况下, MMDVM 盒子是数字电台全球通联的常用设备。MMDVM 盒子通常使用树莓派作为上位机,控制 MMDVM 单/双工热点板。相对 MMDVM 热点板来说,树莓派更为昂贵,故尝试使用便宜得多的 Milkv Duo 替代树莓派。
准备工作
- 有效的业余无线电台执照和呼号( DMR 制式还需要有效的 DMR ID)
- 一块刷好镜像、能动、能使用 RNDIS 的 Milkv Duo(这里以刷好 v1.0.9 镜像的 64M 版本 Milkv Duo 为例)
- 一台正常运行着 Archlinux (其他发行版也行)的计算机
- MMDVM 单工或双工热点板
MMDVM 选型
上位机软件选择 MMDVMHost;而 MMDVM 热点板选择某宝最便宜的 99 元人民币单工热点板,该热点板支持 DMR、 D-STAR、 C4FM、 P25、 NXDN 等常用制式。
线路连接
由于 Milkv Duo 具有 5V 和 3V3 电源引出,故可以直接由 Milkv Duo 给 MMDVM 热点板供电。板间通信使用 Milkv Duo 的 UART4 串口。
Milkv Duo 的引脚复用配置可以使用 duo-pinmux
命令查看,通常 GP2 和 GP3 已经被默认配置为 UART4 串口。热点板的引脚则通常使用树莓派引脚顺序。
详细的连接对应关系如下,热点板上多个 5V 和多个 GND 引脚接一个即可。
Milkv Duo | 热点板 |
---|---|
VBUS | 5V |
3V3(OUT) | 3.3V |
GND | GND |
UART4_TX | TXD |
UART4_RX | RXD |
注意热点板上 TXD 和 RXD 引脚连接的分别是 stm32c8t6 上 USART 的 RXD 和 TXD,故热点板和 Milkv Duo 连接时应当为 UART4_TX 对 TXD、 UART4_RX 对 RXD。
构建 MMDVMHost
这里使用 RUYI 包管理安装 Milkv Duo 交叉编译工具链,在 Archlinux 上构建 Milkv Duo 所需的二进制。
首先建立并进入编译环境。
$ ruyi install gnu-plct
$ ruyi venv -t gnu-plct milkv-duo venv-duo
$ . venv-duo/bin/ruyi-activate
当前目录被认为是 <ruyi_venv_dir>
,这个变量后面会用到。基于此,建立的编译环境目录为 <ruyi_venv_dir>/venv-duo
。
构建 MMDVMHost 之前需要解决前置依赖,这里依次构建。
首先解决 fftw3。
$ wget http://fftw.org/fftw-3.3.10.tar.gz
$ tar xf fftw-3.3.10.tar.gz
$ cd fftw-3.3.10/
$ ./configure CC="riscv64-plct-linux-gnu-gcc" --host=riscv64-linux
$ make -j4
$ make install DESTDIR=<ruyi_venv_dir>/venv-duo/fftw3/
再构建 libsamplerate。
$ git clone https://github.com/libsndfile/libsamplerate
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DLIBSAMPLERATE_EXAMPLES=OFF -DCMAKE_C_COMPILER=riscv64-plct-linux-gnu-gcc -DCMAKE_C_FLAGS=-I<ruyi_venv_dir>/venv-duo/fftw3/usr/local/include
$ make -j4
$ make install DESTDIR=<ruyi_venv_dir>/venv-duo/libsamplerate
前置依赖已经满足,此时可以构建 MMDVMHost。
$ git clone https://github.com/g4klx/MMDVMHost
修改 Makefile,这里给出一个 patch。
diff --git a/Makefile b/Makefile
index aa7dec7..3bd1c34 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,10 @@
# This makefile is for all platforms, but doesn't include support for the HD44780, OLED, or PCF8574 displays on the Raspberry Pi.
-CC = cc
-CXX = c++
-CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHAVE_LOG_H -I/usr/local/include
-LIBS = -lpthread -lutil -lsamplerate
-LDFLAGS = -g -L/usr/local/lib
+CC = riscv64-plct-linux-gnu-gcc
+CXX = riscv64-plct-linux-gnu-g++
+CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHAVE_LOG_H -I/home/hachi/Documents/Working/ruyi-venv/venv-duo/libsamplerate/usr/local/include/
+LIBS = -lpthread -lutil -lsamplerate -L/home/hachi/Documents/Working/ruyi-venv/venv-duo/libsamplerate/usr/local/lib/
+LDFLAGS = -g -static
OBJECTS = \
AMBEFEC.o BCH.o AX25Control.o AX25Network.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \
注意 LDFLAGS 给出了 -static
指定构建静态链接的二进制。
开始构建。
$ make -j4
上传二进制到 Milkv Duo。
$ scp -O MMDVMHost root@192.168.42.1:~
$ scp -O RemoteCommand root@192.168.42.1:~
$ scp -O MMDVM.ini root@192.168.42.1:~
安装和配置 MMDVMHost
登陆 Milkv Duo,这个 IP 地址可能需要根据实际情况修改。
$ ssh root@192.168.42.1
添加 mmdvm 用户和组。
addgroup mmdvm
adduser -H -D -S -G mmdvm -s /bin/false mmdvm
将 MMDVMHost
和 RemoteCommand
安装在 /opt/MMDVMHost
目录下, MMDVM.ini
则放置在 /etc/MMDVM.ini
本文不涉及 MMDVMHost 的详细配置,但还是提醒更改 /etc/MMDVM.ini
中的配置 Daemon=1
。
建立 /opt/MMDVMHost/start_mmdvm
启动脚本。
#/bin/sh
echo Check Internet Connection
while ! ping -c 1 bing.com 2>&1 > /dev/null; do
sleep 5s
done
echo Check NTP time update
wt=1
while [ `date '+%Y'` = 1970 ]; do
wt=`expr $wt + 1`
if [ $wt -ge 30 ]; then
echo Wait NTP timeout 30s
break
fi
try $wt
sleep 1s
done
echo Start MMDVMHost
[ -d /var/log/mmdvm ] || mkdir /var/log/mmdvm
chown mmdvm:mmdvm /var/log/mmdvm /dev/ttyS4
/opt/MMDVMHost/MMDVMHost
注意 /var/log/mmdvm
是 MMDVM.ini 中配置的日志目录; /dev/ttyS4
是 Milkv Duo 和 MMDVM 热点板通信的串口,这里使用的 UART4 即为 Pin4(GP2) 和 Pin5(GP3)。
使其可执行。
chmod +x /opt/MMDVMHost/start_mmdvm
最后配置网络。
首先编辑 /etc/dnsmasq.conf
固定上位机的 IP。
dhcp-range=192.168.42.46,192.168.42.46,1h
编写 /etc/init.d/S99zuser
脚本,上电自动添加 Gateway 和启动 MMDVMHost。
#!/bin/sh
${CVI_SHOPTS}
#
# Add Default Gateway
#
case "$1" in
start)
if /sbin/ip link | grep usb0; then
echo Add default gateway 192.168.42.46 > /var/log/mylog
else
echo RNDIS not on > /var/log/mylog
fi
for i in $(seq 1 30); do
/sbin/ip route add default via 192.168.42.46 && break
sleep 1s
echo Try $i >> /var/log/mylog
done
/opt/MMDVMHost/start_mmdvm >> /var/log/mylog &
;;
stop)
;;
restart|reload)
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit $?
在 /etc/resolv.conf.tail
添加 nameserver,这也需要根据实际情况修改。
nameserver 192.168.0.1
nameserver 192.168.1.1
nameserver 223.5.5.5
nameserver 8.8.8.8
重启 Milkv Duo,目的是查看这些配置是否生效。
reboot
查看 ip route
的输出是否有默认网关。
# ip route
default via 192.168.42.46 dev usb0
192.168.42.0/24 dev usb0 scope link src 192.168.42.1
此时应当能够共享上位机的网络,如果不能访问则可能需要检查上位机的配置。
# ping bing.com
PING bing.com (204.79.197.200): 56 data bytes
64 bytes from 204.79.197.200: seq=0 ttl=113 time=69.016 ms
^C
--- bing.com ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 69.016/69.016/69.016 ms
在上位机中,首先确认已经允许 IPv4 Forward。
# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
再允许两个 interface 之间的转发,其中 eth0
是上位机可以访问外网的端口,而 usb0
是 Milkv Duo 的 USB 网络。这两个端口名称需要根据实际情况修改。
sudo iptables -A FORWARD -i usb0 -j ACCEPT
sudo iptables -A FORWARD -o usb0 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
由于 MMDVMHost 的启动脚本在外网不通的情况下会一直等待,在外网访问畅通时 MMDVMHost 才会启动。
查看日志 /var/log/mylog
和 /var/log/mmdvm
确认此时 MMDVMHost 运行正常。
不再使用 RNDIS
若不再希望使用 RNDIS 进行网络连接,那么有线网络是一个最容易实现的选择,在解决了无线网卡驱动的情况下也可以使用 USB 无线网卡。
首先关闭 RNDIS 并启用 USB Host 模式,这主要为了后续能够使用 USB 无线网卡。
rm /mnt/system/usb.sh
ln -sf /mnt/system/usb-host.sh /mnt/system/usb.sh
连接 RJ45,这里连接公头母头均可,它们的线序是一样的。
Milkv Duo | RJ45 |
---|---|
TX+ | 1 |
TX- | 2 |
RX+ | 3 |
RX- | 6 |
连接网线后会自动配置网络。
ethtool
实验板是用洞洞板飞线飞起来的,连线质量不高导致,网口速率高了就会断联。
# dmesg
[ 108.724734] bm-dwmac 4070000.ethernet eth0: Link is Down
[ 110.773714] bm-dwmac 4070000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[ 111.796713] bm-dwmac 4070000.ethernet eth0: Link is Down
[ 112.821740] bm-dwmac 4070000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[ 113.844730] bm-dwmac 4070000.ethernet eth0: Link is Down
[ 115.893750] bm-dwmac 4070000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[ 116.916746] bm-dwmac 4070000.ethernet eth0: Link is Down
[ 117.941771] bm-dwmac 4070000.ethernet eth0: Link is Up - 10Mbps/Full - flow control rx/tx
[ 118.964725] bm-dwmac 4070000.ethernet eth0: Link is Down
[ 119.989769] bm-dwmac 4070000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[ 121.012725] bm-dwmac 4070000.ethernet eth0: Link is Down
[ 125.109749] bm-dwmac 4070000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[ 126.132731] bm-dwmac 4070000.ethernet eth0: Link is Down
[ 127.157731] bm-dwmac 4070000.ethernet eth0: Link is Up - 10Mbps/Full - flow control rx/tx
[ 139.444722] bm-dwmac 4070000.ethernet eth0: Link is Down
[ 143.541737] bm-dwmac 4070000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[ 144.564727] bm-dwmac 4070000.ethernet eth0: Link is Down
[ 145.589742] bm-dwmac 4070000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[ 146.612728] bm-dwmac 4070000.ethernet eth0: Link is Down
[ 148.661731] bm-dwmac 4070000.ethernet eth0: Link is Up - 10Mbps/Full - flow control rx/tx
MMDVM 并不需要多高的网络连接速度,故尝试限制到 10Mbps。
$ git clone https://github.com/Distrotech/ethtool --depth=1
$ cd ethtool
$ LDFLAGS=-static ./configure CC="riscv64-plct-linux-gnu-gcc" --host=riscv64-linux
$ make -j4
得到 ethtool 二进制,传送到 Milkv Duo 上。
限制网络连接速度。
ethtool -s eth0 speed 10
应该也可以用 tc
命令,不过 ethtool
显然更简洁些。
局限性
- 在没有显示屏的情况下,只能通过 MMDVM 热点板上的 LED 指示灯观察工作情况
其他工作
- 由于官方镜像至多只有 29M 可供使用,建议自行重新构建镜像
- 该 MMDVMHost 构建不携带 LCD/OLED 显示屏驱动,这是因为这个驱动依赖于 WiringPi,驱动支持还需要额外的工作
这些工作已经更新在这篇中。
这里是桜風の狐,将美好的 73 送上。