0%

前言

当初买FT-8900R时笔者还是纯纯的小白,买它的原因之一是《业余无线电通信(第五版)》的推荐,其二是电台支持四频段双工操作,其三是DATA插孔具有极强的迷惑性。我一度以为只要用数据线连接电台和电脑,就能传输数字信息,当然实际上并非如此。后来读了几遍手册,说是要用到TNC这个东西,然而国内根本没得卖,资料也近乎为零,ham群里大多在讨论mmdvm和FT8,没有人在玩Packet Radio。经过一段时间摸索,笔者终于验证出FT-8900R进行Packet Radio操作的一套可行方案。

Packet Radio沿革

讨论Packet Radio无法跳过它的发展历史,否则许多疑惑就很难解答。一个比较系统的介绍是 WB9LOZ 成稿于上世纪九十年代的INTRODUCTION TO PACKET RADIO,里面详细介绍了硬件构成、TNC命令、中继与节点的区别、BBS使用等内容。简而言之,Packet Radio起源于1980年的加拿大,并迅速在美国、西欧等地流行。那时Packet Radio的硬件系统一般为 电台-TNC-电脑/哑终端 ,也有 电台-调制解调器-电脑(运行软件充当软TNC) 这种比较少见的形式。TNC实现了 ASCII字符 - AFSK语音 之间的转换,是一种硬件设备,比较经典的TNC有TAPR出品的TNC-1和TNC-2,当年售价大概100美元。同时期国内爱好者能凑齐电台、电脑、TNC的恐怕凤毛麟角,这解释了为什么许多国内爱好者对Packet Radio、TNC之类名词毫无概念。

2022年利用FT-8900R操作Packet Radio所需的软硬件

硬件

  1. FT-8900R电台。
  2. 马工盒子,充当电台连接器,同时提供PTT控制。对于八重洲那些采用6 PIN mini-DIN接口(笔者按:貌似就是PS/2接口)的车台,国外的成品连接器Dinah提供了更简洁的接口。Dinah使用CM119声卡方案,利用CM119的GPIO针脚实现了PTT控制功能,这样连接器只需要通过一个6 PIN mini-DIN接口连接电台,一个USB接口连接电脑就可以了,不再需要额外的声卡,也不需要额外的USB接口提供PTT控制。动手能力强的爱好者可以购买CM108/CM119方案的USB声卡自行改造。
  3. USB声卡,9.9元包邮款即可,需要Speaker与MIC有独自接口。高级一些的还会有Line IN接口不过非必需。
  4. 电脑。为降低成本,我在一个40元的电视盒子上运行Manjaro ARM系统,充当电脑主机。这个盒子具备4核2GHz的处理器,令当年专门用来搭建Node、BBS的奔腾处理器电脑望尘莫及,所以不需要担心硬件性能不够。

    软件

  5. Direwolf
    我们用它来充当软件KISS TNC。通过KISS OVER TCP功能可以方便地进行远程连接,即运行Direwolf和与电台直接连接的电脑,与我们运行客户端软件用来收发消息的电脑不必是同一台,这为远程使用提供了便利。Direwolf也可以创建伪终端设备(编者按:该特性仅对Linux有效)供老式程序使用。此外Direwolf还可以提供APRS GPS Tracker、Digipeater、IGate、APRStt gateway等功能,有兴趣的可以深入了解。
    Direwolf的编译毫无难度,拉取Github源码后编译即可,需要的依赖Manjaro仓库中都有提供。
  6. LinBPQ
    LinBPQ可以在一台电脑上同时提供Node、BBS、聊天服务器、WinLink网关等功能,支持KISS OVER TCP。编译和配置稍显麻烦,方法可以参考Manjaro ARM编译LinBPQLinBPQ配置
  7. ax25tools

ax25tools 提供了ax25apps, ax25tools和libax25,需要分别编译安装。注意对于ax25app,需要将linuxax25-ax25tools-1.0.4/ax25apps/call/call.c中第45行 #include <ncursesw/ncurses.h> 修改为 #include <ncurses.h> 才能顺利编译。可以参考在Manjaro ARM中编译运行Pat
4. Pat
Pat是一个跨平台的 Winlink 客户端,提供了命令行界面和网页界面,特性和编译使用方法可以参考在Manjaro ARM中编译运行Pat

系统测试

硬件连接

电视盒子1号USB连接USB声卡,2号USB口连接马工盒子。马工盒子Data口连接电台,speaker与mic分别连接声卡的speaker与mic。

编解码测试

测试了1200与9600两种模式,经测试PTT控制正常,1200模式下能够清楚收听到经过调制的音频信号,编码解码正常。packet-1200对设备的要求很小,甚至用喇叭对着麦克风也能工作。
9600模式不经历 数字信号-调制语音之间的转换,通过FSK方式调制,听起来就像沙沙的噪音,无法分辨细节。Direwolf提供了几个便利的小工具用于测试:

$ gen_packets -o x.wav -B 9600 #生成音频
$ atest -B 9600 x.wav # 对音频解码
44100 samples per second.  16 bits per sample.  1 audio channels.
32576 audio bytes in file.  Duration = 0.4 seconds.
Fix Bits level = 0
Channel 0: 9600 baud, K9NG/G3RUH,  , 44100 sample rate x 3.
The ratio of audio samples per sec (44100) to data rate in baud (9600) is 4.6
This is on the low side for best performance.  Can you use a higher sample rate?
For example, can you use 48000 rather than 44100?

DECODED[1] 0:00.091 WB2OSZ-15 audio level = 50(+33/-33)
[0] WB2OSZ-15>TEST:,The quick brown fox jumps over the lazy dog!  1 of 4

DECODED[2] 0:00.183 WB2OSZ-15 audio level = 50(+33/-33)
[0] WB2OSZ-15>TEST:,The quick brown fox jumps over the lazy dog!  2 of 4

DECODED[3] 0:00.275 WB2OSZ-15 audio level = 50(+33/-33)
[0] WB2OSZ-15>TEST:,The quick brown fox jumps over the lazy dog!  3 of 4

DECODED[4] 0:00.368 WB2OSZ-15 audio level = 50(+33/-33)
[0] WB2OSZ-15>TEST:,The quick brown fox jumps over the lazy dog!  4 of 4


4 from x.wav
4 packets decoded in 0.014 seconds.  25.8 x realtime

在另一台笔记本电脑上使用gen_packets生成音频,笔记本speaker输出口连接运行Direwolf主机的USB声卡MIC口,测试解码效果。经过测试音频中包含的4条信息在95%以上的情况下只能解码出前3条,最后一条消失不见。调整输出音频与声卡音量后,问题无改善。或许是USB声卡的带宽不够?这说明9600对系统硬件的要求更高。

Node,BBS,聊天服务器测试

由于附近没有操作Packet Radio的爱好者故未能完成测试,不过不连接电台直接通过AX.25本地连接测试没问题,推测运行正常。另外LinBPQ的管理页面Bug较多,如需修改配置请直接改动配置文件,在网页修改容易报错崩溃。

Pat测试

国内没有2米段的节点所以无法测试通过电波访问情况,不过使用telnet收发信正常,AX.25支持正常,推断无问题。

前几天发现QQ号上不去了,提示需要输入密码。登录密码早就忘了,试图通过短信验证码登录,发现当初注册QQ号的号码早已注销,于是号就没了~~~
号里没有绑定支付手段,也没有敏感信息,不过可惜了包括辽宁省业余无线电在内的一些群。为防止有人上去捣乱,还是特此声明一下:

本人尾号为5834的QQ号已无法登录,该号后续一切活动均与本人无关。我是BH2VJW。

当日更新:试了几个常用密码后成功登录。改绑手机号比较麻烦,就这么凑合用吧,等哪天真上不去了再说。

加载驱动后看一看RTL8189ETV支持的特性:
$ iw list
Wiphy phy0
        wiphy index: 0
        max # scan SSIDs: 9
        max scan IEs length: 2304 bytes
        max # sched scan SSIDs: 0
        max # match sets: 0
        Retry short limit: 7
        Retry long limit: 4
        Coverage class: 0 (up to 0m)
        Supported Ciphers:
                * WEP40 (00-0f-ac:1)
                * WEP104 (00-0f-ac:5)
                * TKIP (00-0f-ac:2)
                * CCMP-128 (00-0f-ac:4)
                * CMAC (00-0f-ac:6)
        Available Antennas: TX 0 RX 0
        Supported interface modes:
                 * IBSS
                 * managed
                 * AP
                 * P2P-client
                 * P2P-GO
        Band 1:
                Capabilities: 0x1962
                        HT20/HT40
                        Static SM Power Save
                        RX HT20 SGI
                        RX HT40 SGI
                        RX STBC 1-stream
                        Max AMSDU length: 7935 bytes
                        DSSS/CCK HT40
                Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
                Minimum RX AMPDU time spacing: 16 usec (0x07)
                HT Max RX data rate: 150 Mbps
                HT TX/RX MCS rate indexes supported: 0-7
                Bitrates (non-HT):
                        * 1.0 Mbps
                        * 2.0 Mbps
                        * 5.5 Mbps
                        * 11.0 Mbps
                        * 6.0 Mbps
                        * 9.0 Mbps
                        * 12.0 Mbps
                        * 18.0 Mbps
                        * 24.0 Mbps
                        * 36.0 Mbps
                        * 48.0 Mbps
                        * 54.0 Mbps
                Frequencies:
                        * 2412 MHz [1] (20.0 dBm)
                        * 2417 MHz [2] (20.0 dBm)
                        * 2422 MHz [3] (20.0 dBm)
                        * 2427 MHz [4] (20.0 dBm)
                        * 2432 MHz [5] (20.0 dBm)
                        * 2437 MHz [6] (20.0 dBm)
                        * 2442 MHz [7] (20.0 dBm)
                        * 2447 MHz [8] (20.0 dBm)
                        * 2452 MHz [9] (20.0 dBm)
                        * 2457 MHz [10] (20.0 dBm)
                        * 2462 MHz [11] (20.0 dBm)
                        * 2467 MHz [12] (20.0 dBm) (no IR)
                        * 2472 MHz [13] (20.0 dBm)
                        * 2484 MHz [14] (disabled)
        Supported commands:
                 * new_interface
                 * set_interface
                 * new_key
                 * start_ap
                 * new_station
                 * set_bss
                 * join_ibss
                 * set_pmksa
                 * del_pmksa
                 * flush_pmksa
                 * remain_on_channel
                 * frame
                 * set_channel
                 * connect
                 * disconnect
        WoWLAN support:
                 * wake up on anything (device continues operating normally)
        software interface modes (can always be added):
        interface combinations are not supported
        Device supports SAE with AUTHENTICATE command
        Device supports scan flush.
        max # scan plans: 1
        max scan plan interval: -1
        max scan plan iterations: 0
        Supported TX frame types:
                 * IBSS: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                 * managed: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                 * AP: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                 * AP/VLAN: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                 * P2P-client: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
                 * P2P-GO: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
        Supported RX frame types:
                 * IBSS: 0xd0
                 * managed: 0x40 0xb0 0xd0
                 * AP: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
                 * AP/VLAN: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
                 * P2P-client: 0x40 0xd0
                 * P2P-GO: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
        Supported extended features:

看起来支持的无线加密类型只有这几个:

 Supported Ciphers:
                * WEP40 (00-0f-ac:1)
                * WEP104 (00-0f-ac:5)
                * TKIP (00-0f-ac:2)
                * CCMP-128 (00-0f-ac:4)
                * CMAC (00-0f-ac:6)

看起来这就是我们的R3300-M无法连接到WIFI的原因,现在的路由器都是WPA起步了,好一些的可以支持到WPA3。

Manjaro ARM 22.06已经发布一段时间,刚好我们需要重新刷系统,镜像还是选用Vim2: https://github.com/manjaro-arm/vim2-images/releases
在最近的几个版本中,系统的启动方式经历了几次变化。在Vim2 22.06镜像中,boot分区只包含下述文件/目录:

$ ls -l /boot
drwxr-xr-x 8 root root     8192 Aug  3 22:49 dtbs
drwxr-xr-x 2 root root     8192 Jun  4 05:03 extlinux
-rw-r--r-- 1 root root 24730112 Jul 12 23:44 Image
-rw-r--r-- 1 root root  8382621 Aug  3 22:50 initramfs-linux.img
-rw-r--r-- 1 root root  1363968 Feb 12 00:11 u-boot.bin

需要稍加变动以支持R3300-M启动:

-rw-r--r-- 1 root root      713 Jul 28 15:17 aml_autoscript
-rw-r--r-- 1 root root      463 Jul 28 15:17 aml_autoscript.zip
drwxr-xr-x 8 root root     8192 Aug  3 22:49 dtbs
drwxr-xr-x 2 root root     8192 Jun  4 05:03 extlinux
-rw-r--r-- 1 root root 24730112 Jul 12 23:44 Image
-rw-r--r-- 1 root root  8382621 Aug  3 22:50 initramfs-linux.img
-rw-r--r-- 1 root root      537 Aug  4 06:34 s905_autoscript
-rw-r--r-- 1 root root  1363968 Feb 12 00:11 u-boot.bin
-rw-r--r-- 1 root root   609247 Aug  4 06:30 u-boot.ext

注意补充的几个文件,u-boot.bin可以删掉。这几个文件我已经打包好: bootfiles.tgz,注意你需要选择合适的u-boot文件,然后重命名为u-boot.ext。

Manjaro ARM Mininal 22.06非常简洁,总共占用空间1.5GB,提供了206个软件包:

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
dev             331M     0  331M   0% /dev
run             465M  7.5M  457M   2% /run
/dev/mmcblk0p2  115G  1.4G  109G   2% /
tmpfs           465M     0  465M   0% /dev/shm
tmpfs           465M     0  465M   0% /tmp
/dev/mmcblk0p1  458M   45M  413M  10% /boot
tmpfs            93M     0   93M   0% /run/user/1000

$ pacman -Q | wc
206     412    3746

软件包还可以继续精简,比如 ap6398s-firmware 显然可以删掉因为R3300-M使用的是RTL8189ETV。另外经过测试,主线内核在22.06中支持良好,关机重启都正常,没必要使用odroid内核了。不过Vim2镜像自带的 linux-khadas 内核简单使用也没发现问题,根据个人喜好选用吧。
另外之前将Manjaro ARM安装到emmc分区的试验没有成功:

U-Boot 2015.01-gf813653 (Oct 30 2015 - 09:47:48)

DRAM:  1 GiB
Relocation Offset is: 36ed6000
register usb cfg[0][1] = 0000000037f62b98
register usb cfg[0][2] = 0000000037f62bb8
register usb cfg[2][0] = 0000000037f62bd8
vpu detect type: 5
vpu clk_level = 7
set vpu clk: 666667000Hz, readback: 666660000Hz(0x300)
boot_device_flag : 1
Nand PHY Ver:1.01.001.0006 (c) 2013 Amlogic Inc.
init bus_cycle=6, bus_timing=8, system=5.0ns
reset failed
get_chip_type and ret:fffffffe
get_chip_type and ret:fffffffe
chip detect failed and ret:fffffffe
nandphy_init failed and ret=0xfffffff1
MMC:   aml_priv->desc_buf = 0x0000000033ec6770
aml_priv->desc_buf = 0x0000000033ec8900
SDIO Port B: 0, SDIO Port C: 1
[mmc_init] mmc init success
mmc read lba=0x14000, blocks=0x400
start dts,buffer=0000000033ecad70,dt_addr=0000000033ecad70
parts: 11
00:      logo   0000000002000000 1
01:  recovery   0000000002000000 1
02:       rsv   0000000000800000 1
03:       tee   0000000000800000 1
04:     crypt   0000000002000000 1
05:      misc   0000000002000000 1
06: instaboot   0000000020000000 1
07:      boot   0000000002000000 1
08:    system   0000000050000000 1
09:     cache   0000000020000000 2
10:      data   ffffffffffffffff 4
get_dtb_struct: Get emmc dtb OK!
[mmc_get_partition_table] skip cache partition.
Partition table get from SPL is :
        name                        offset              size              flag
===================================================================================
   0: bootloader                         0            400000                  0
   1: reserved                     2400000           4000000                  0
   2: cache                        6c00000          20000000                  2
   3: env                         27400000            800000                  0
   4: logo                        28400000           2000000                  1
   5: recovery                    2ac00000           2000000                  1
   6: rsv                         2d400000            800000                  1
   7: tee                         2e400000            800000                  1
   8: crypt                       2f400000           2000000                  1
   9: misc                        31c00000           2000000                  1
  10: instaboot                   34400000          20000000                  1
  11: boot                        54c00000           2000000                  1
  12: system                      57400000          50000000                  1
  13: data                        a7c00000          41400000                  4
mmc read lba=0x12000, blocks=0x1
mmc read lba=0x12001, blocks=0x1
mmc_read_partition_tbl: mmc read partition OK!
eMMC/TSD partition table have been checked OK!
mmc env offset: 0x27400000
In:    serial
Out:   serial
Err:   serial
[store]To run cmd[emmc dtb_read 0x1000000 0x40000]
read emmc dtb
Net:   Meson_Ethernet
wipe_data=successful
wipe_cache=successful
upgrade_step=2
reboot_mode=normal
hpd_state=0
[CANVAS]addr=0x3f800000 width=3840, height=2160

Not find '576cvbs' mapped VIC
Err imgread(L315):Logo header err.
There is no valid bmp file at the given address
amlkey_init() enter!
[EFUSE_MSG]keynum is 4
[KM]Error:f[key_manage_query_size]L504:key[usid] not programed yet
[KM]Error:f[key_manage_query_size]L504:key[deviceid] not programed yet
gpio: pin GPIOAO_3 (gpio 122) value is 1
Hit any key to stop autoboot:  0
ret = 1 .(Re)start USB...
USB0:   dwc_usb driver version: 2.94 6-June-2012
USB (0) peri reg base: c0000000
USB (0) use clock source: XTAL input, div: 1
USB (0) base addr: 0xc9000000
Force id mode: Host
dwc_otg: No USB device found !
lowlevel init failed
USB1:   dwc_usb driver version: 2.94 6-June-2012
USB (1) peri reg base: c0000020
USB (1) use clock source: XTAL input, div: 1
USB (1) base addr: 0xc9100000
Force id mode: Host
dwc_otg: No USB device found !
lowlevel init failed
USB error: all controllers failed lowlevel init
** Bad device usb 0 **
** Bad device usb 1 **
** Bad device usb 2 **
** Bad device usb 3 **
[mmc_init] mmc init success
switch to partitions #0, OK
mmc1(part 0) is current device

MMC read: dev # 1, block # 8192, count 3 ... 3 blocks read: OK
## Executing script at 01020000
########## cmd=    echo "Select EMMC"
    mmc dev 1
    sleep 3
    echo "Set env variables"
    setenv dtb_addr 0x1000000
    setenv dtb_sector 0x2003
    setenv dtb_block_cnt 0x47
    setenv env_addr 0x1040000
    setenv env_sector 0x204a
    setenv env_block_cnt 0x1
    setenv env_size 329
    setenv kernel_addr 0x11000000
    setenv kernel_sector 0x204b
    setenv kernel_block_cnt 0xbcae
    setenv initrd_addr 0x13000000
    setenv initrd_sector 0x32000
    setenv initrd_block_cnt 0x3fe7
    setenv boot_start booti ${kernel_addr} ${initrd_addr} ${dtb_addr}
    setenv addmac 'if printenv mac; then setenv bootargs ${bootargs} mac=${mac}; elif printenv eth_mac; then setenv bootargs ${bootargs} mac=${eth_mac}; elif printenv ethaddr; then setenv bootargs ${bootargs} mac=${ethaddr}; fi'

    echo "Read mmc partitions"
    echo "Read /boot/uEnv_emmc.txt from EMMC"
    if mmc read ${env_addr} ${env_sector} ${env_block_cnt}; then env import -t ${env_addr} ${env_size};setenv bootargs ${APPEND};printenv bootargs;echo "Read zImage from EMMC";if mmc read ${kernel_addr} ${kernel_sector} ${kernel_block_cnt}; then echo "Read uInitrd from EMMC";if mmc read ${initrd_addr} ${initrd_sector} ${initrd_block_cnt}; then echo "Read FDT from EMMC";if mmc read ${dtb_addr} ${dtb_sector} ${dtb_block_cnt}; then run addmac;echo "Start booting system...";run boot_start;fi;fi;fi;fi

Select EMMC
[mmc_init] mmc init success
switch to partitions #0, OK
mmc1(part 0) is current device
Set env variables
Read mmc partitions
Read /boot/uEnv_emmc.txt from EMMC

MMC read: dev # 1, block # 8266, count 1 ... 1 blocks read: OK
bootargs=root=/dev/mmcblk1p1 rootflags=data=writeback rw console=ttyAML0,115200n8 console=tty0 no_console_suspend consoleblank=0 fsck.fix=yes fsck.repair=yes net.ifnames=0 quiet splash plymouth.ignore-serial-consoles blkdevparts=mmcblk1:-@116M(rootfs)
Read zImage from EMMC

MMC read: dev # 1, block # 8267, count 48302 ... 48302 blocks read: OK
Read uInitrd from EMMC

MMC read: dev # 1, block # 204800, count 16359 ... 16359 blocks read: OK
Read FDT from EMMC

MMC read: dev # 1, block # 8195, count 71 ... 71 blocks read: OK
mac=76:f1:6c:90:00:03
Start booting system...
"Synchronous Abort" handler, esr 0x96000010
ELR:     37ee00cc
LR:      37ee00c0
x0 : 0000000037f73a00 x1 : 0000000000000000
x2 : 0000000001830000 x3 : 0000000001830000
x4 : 0000000000000086 x5 : 0000000011000000
x6 : 0000000037f455c0 x7 : 0000000000000044
x8 : 0000000000000001 x9 : 0000000000000002
x10: 8c400409c940146c x11: a850c8189a6e9ad0
x12: 0000000000000000 x13: 0000000000000000
x14: 0000000000000000 x15: 0000000037ed70d0
x16: 0000000037ed72b4 x17: 0000000000000000
x18: 0000000033ec5e28 x19: 0000000037f738c0
x20: 0000000000000003 x21: 0000000033ed1068
x22: 0000000037f73000 x23: 0000000037f738c0
x24: 0000000000000000 x25: 0000000033ed1060
x26: 0000000037f685e0 x27: 0000000033ed1090
x28: 0000000000000000 x29: 0000000033ec4ca0

Resetting CPU ...

虽说没成功,但是从UART输出来看已经很接近,而且盒子也没变砖,还是可以从TF卡启动,感兴趣的可以继续研究,我不缺TF卡就不折腾了。

参考 https://github.com/d51x/armbian-s905 ,计划再次试验将Linux系统刷入R3300-M盒子的emmc分区。
试验内容:

  1. 试验能否将Armbian刷入R3300-M,验证可行性;
  2. 试验能否通过uEnv.txt方式启动最新版Manjaro ARM系统;
  3. 试验能否将Manjaro ARM刷入 R3300-M。

为方便调试,笔记本电脑通过UART与盒子通信,观察盒子启动状态。如果UART无法交互,可通过在u-boot启动文件中指定printenv观察。

首先弄清几个启动文件的关系

boot.cmd与boot.scr
boot.cmd为纯文本文件,通过mkimage生成boot.scr:

mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr

uEnv.txtboot.scr
根据uEnv.txt vs boot.scr的说法,uEnv.txt可以预设置u-boot的环境变量,先于bootcmd运行。boot.scr可以执行u-boot脚本程序,同样先于bootcmd运行。不过我高度怀疑这段描述的准确性,具体参见下文。
补充:bootcmdbootargs为u-boot中的环境变量。

boot.ini
boot.ini是一个纯文本文件。通过观察ophub发布的镜像可知,boot.ini读取了uEnv.txt,并将 APPEND 参数传递给了 bootargs这个环境变量。

boot.iniboot.scr
参考 https://wiki.odroid.com/odroid-n2/software/boot_sequence ,boot.ini与boot.scr是bootloader支持的两种启动脚本。boot.ini是纯文件,便于修改。这个文件最初被Hardkernel’s ODROID的开发板使用。如果文件首行是 ODROIDN2-BOOT-CONFIG ,那么bootloader就会开始执行boot.ini文件。(这解释了为什么Amlogic盒子的boot.ini文件首行都是这个)

boot.scr是传统形式的u-boot脚本。脚本开头为一段长度64字节的二进制头,包含了整个文件的校验信息以防文件损坏或被修改。其余的语句以test形式为主,设置环境变量或执行命令。由于boot.scr文件的特性,对其做出变更后,需要使用 mkimage 重新生成,具体命令参见前文。

个人猜测,在Amlogic设备上,bootloader会优先试图利用 boot.ini 启动,如果 boot.ini 不存在或者加载失败,再利用 boot.scr 尝试启动。两个文件的执行命令大体上是等价的。可以通过printenv命令检查具体优先顺序。

至此我们的第二步试验已有眉目。我们使用的 Manjaro ARM 22.06 VIM2 Minimal 版本 /boot 分区只包含 u-boot.bin,dtbs目录以及extlinux目录。在先前的测试中,我将 aml_autoscript aml_autoscript.zip u-boot.ext 文件复制了过来,删掉了u-boot.bin并在extlinux.conf中配置了合适dtb,测试系统正常启动,主线内核也关机重启正常。不过尝试使用 uEnv.txt 启动时,由于既没有boot.scr,也没有 boot.ini,所以启动毫无意外地失败了。

小结:Amlogic设备上,bootloader读取boot.scr或者boot.ini启动,uEnv.txt被上述两个文件加载。boot.scr使用mkimage编译,boot.ini纯文本随便改。

最后再补充一些关于extlinux.conf的知识,参考自Using Distro Boot With Xilinx U-Boot:
bootloader会优先试图加载/extlinux/extlinux.conf,如果没有找到,则查询 boot_targets 寻找备用文件,比如上面提到的 boot.scr
extlinux.conf具有很多优点,但是不幸的是我们现在试图将Linux安装到emmc,厂商的老旧bootloader不支持extlinux这一特性。这也是放弃extlinux转而折腾boot.ini boot.scr uEnv.txt的原因所在。

之前搭建packet radio节点的试验告一段落了。由于本地没有使用packet radio的ham,所以没办法测试解码效果。不过编码发送功能没有问题。另外systemd脚本也有一些问题。理想情况下ax25bind应该伴随direwolf一并重启,不过实际中虽然指定了PartOf参数,这个功能没有实现,算是小小的不完美。为了吸引到更多的爱好者参与packet radio,我计划整理出一个从理论到实操比较完整的入门教程。不过业余无线电考试快到了,B级考试还是要准备一下,packet radio暂时要放一放了。

B级考试需要记忆频率、Q短语、名词等比较琐碎的知识点。虽然有取巧记忆方法,不过为了日后规范使用频率,还是应该理解记忆。

频段

业余业务作为专用业务频段

7-7.2MHz(7.03-7.2 LSB) 14-14.25MHz(14.1 IARU, 14.1-14.35 USB) 21-21.45MHz(21.15 IARU, 21.125-21.45可USB, 除去21.1495-21.1505,即避让信标±500Hz) 28-29.7MHz(28.2 IARU, 28.3-29.3 USB, 29.51-29.7 FM) 47GHz

业余业务作为主要业务的频段

1.8-2MHz 3.5-3.9MHz 14.25-14.35MHz 18.068-18.168MHz (WARC, 18.11 IARU, 18.1105-18.168 USB) 24.89-24.99MHz (WARC, 24.93 IARU, 24.9305-24.99 USB) 50-54MHz 144-148MHz(144-146唯一主要,146-148共同主要,避让 144-144.035和145.8-146)

业余业务作为次要业务频段

135.7-137.5KHz 10.1-10.15MHz(WARC,不能用于通话) 430-440MHz(避让431.9-432.240和435-438)

LF(低频,例135.7-137.8KHz)
MF(中频,例1.8-2MHz)
HF(高频,例28-29.87MHz)
VHF(甚高频,米波,例50-54MHz)
UHF(特高频,分米波,例2300-1450MHz)
SHF(超高频,厘米波,例C、Ku波段卫星电视广播)
EHF(极高频,毫米波,例241-250GHz)

Q简语

Q简语 问句含义 答句含义
QRA 你的电台名称是? 我的电台名称是…
QRB 你台离我台多远? 我们相距约为…
QRG 我的准确频率是多少? 你的准确频率是…
QRI 我的音调如何? 你的音调是(T1-T9)
QRJ 我的信号小吗 你的信号小
QRK 我的信号可辩度是多少? 你的信号可辩度是(R1-R5)
QRL 你忙吗? 我正忙
QRM 你受到他台干扰吗? 我正受到他台干扰 1.无 2.稍有 3.中等 4.严重 5.极端
QRN 你受到天电干扰吗? 我正受到天电干扰 1.无 2.稍有 3.中等 4.严重 5.极端
QRO 要我增加发信功率吗? 请增加发信功率
QRP 要我减低发信功率吗? 请减低发信功率
QRQ 要我发得快些吗? 请发快些
QRS 要我发得慢些吗? 请发慢些
QRT 要我停止拍发吗? 请停止拍发
QRU 你有事吗? 无事
QRV 你准备好了吗? 我已准备好了
QRW 需要我转告吗? 请转告
QRX 要我等多长时间? 请等待… …分钟
QRZ 谁在呼叫我? …正在呼叫你

QSA 我的信号强度是多少? 你的信号强度是…
QSB 我的信号有衰落吗? 你的信号强度是,1.几乎不能抄收 2.弱 3.还好 4.好 5.很好
QSD 我的信号不完整吗? 你的信号不完整
QSL 你确认收妥/QSL卡片吗? 我确认收妥/QSL卡片
QSO 你能否和…直接(或转接)通信? 你能和…直接(或转接)通信?
QSP 你能中转到…吗 我能中转到…
QSU 能在这个频率(或某个频率)回复吗? 我将在此频率(或某频率)回复
QSV 有天电干扰要我在此频率发一串 V 字吗? 请在此频率发一串 V 字
QSW 你将在此频率(或某频率)发吗? 我将在此频率(或某频率)发
QSX 你将在某频率收听吗? 我将在某频率收听
QSY 要我改用其他频率拍发吗? 请改用…KHz/MHz拍发
QSZ 要我每组发两遍吗? 请每组发两遍
QTB 要我查对组数吗? 请查对组数
QTC 你有几分报要发? 我有…分报要发
QTH 你的地理位置是? 我的地理位置是…
QTR 你的标准时间是? 我的标准时间是…

缩写

SASE 写好收信人地址的信封
ALC 发信自动电平控制
AT 自动天线调谐
ATT 收信机自动增益衰减
AGC 收信机自动增益控制
PRE 收信机前置放大器
PROC 发信语音压缩
RIT 接收增量调谐
XIT 发射增量调谐

分区

CQ分区

23 24(东沙、钓鱼) 27(黄岩岛)

ITU分区

我国大区为3区,33 42 43 44(东沙、钓鱼) 50(黄岩岛)

direwolf.service

# /usr/lib/systemd/system/direwolf.service
# direwolf.service

[Unit]
Description=Direwolf management
Documentation=https://tccmu.com
Requires=network-online.target

[Service]
User=marly
Type=oneshot
ExecStart=/usr/bin/screen -dmS direwolf /usr/local/bin/direwolf -c /home/marly/direwolf.conf -p
ExecStop=/usr/bin/killall -s INT direwolf
Restart=on-abnormal
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target

linbpq.service

# /usr/lib/systemd/system/linbpq.service
# linbpq.service

[Unit]
Description=LinBPQ management
Documentation=https://tccmu.com
Requires=network-online.target
Wants=direwolf.service

[Service]
User=marly
Type=oneshot
WorkingDirectory=/home/marly/linbpq/
ExecStart=/usr/bin/screen -dmS linbpq /home/marly/linbpq/linbpq
ExecStop=/usr/bin/killall -s INT linbpq
Restart=on-abnormal
RemainAfterExit=yes
# Use graceful shutdown with a reasonable timeout
TimeoutStopSec=15s
[Install]
WantedBy=multi-user.target

这两个服务是以普通用户 marly 身份,在screen中运行的。开机时,会优先启动direwolf,然后启动linbpq。注意service文件中的用户名、工作路径、配置文件路径要修改成自己的。

ax25bind.service

# /usr/lib/systemd/system/ax25bind.service
# ax25bind.service

[Unit]
Description=Bind PTY created by direwolf to axports
Documentation=https://tccmu.com
Requires=direwolf.service
PartOf=direwolf.service

[Service]
User=root
Type=oneshot
ExecStartPre=sleep 3
ExecStart=/bin/bash -c "/usr/local/sbin/kissattach `/usr/bin/ls -l /tmp/kisstnc | /usr/bin/awk '{ print $11 }'` wl2k && exit"
ExecStartPost=/usr/local/sbin/kissparms -c 1 -p wl2k
ExecStop=/usr/bin/killall kissattach
[Install]
WantedBy=multi-user.target

将上述service文件放在 /usr/lib/systemd/system/ 目录中,然后执行

sudo systemctl daemon-reload
sudo systemctl enable --now direwolf.service
sudo systemctl enable --now linbpq.service
sudo systemctl enable --now ax25bind.service

之前已经成功为Manjaro ARM编译了LinBPQ,现在来研究如何配置。

配置过程中参考了 Winlink Gateway on a Raspberry Pi LinBPQ,这个视频提供了大量配置细节。

生成bpq32.cfg配置文件

这个文件可以参考 G8BPQ Home Page ,不过这个过程比较痛苦。好在 John G8BPQ 制作了图形化的配置文件生成器 BPQConfigGen ,下载运行即可。Windows版本的功能比Linux版少一些,不过在Windows 10下开箱即用,十分便利。生成的配置文件如下:

; Written by BPQConfigGen

SIMPLE
NODECALL=BH2VJW-7
NODEALIAS=FUXIN
LOCATOR=PN02TA

PORT
PORTNUM=1
 ID=Telnet Server
 DRIVER=TELNET
 CONFIG
  LOGGING=1
  TCPPORT=8010
  FBBPORT=8011
  HTTPPORT=8080
  CMS=1
  CMSCALL=BH2VJW
  CMSPASS=密码不告诉你
  USER=本地管理页面用户名,本地管理页面密码,BH2VJW,,SYSOP;
ENDPORT
PORT
 PORTNUM=2
 ID=Direwolf
 TYPE=ASYNC
 PROTOCOL=KISS
 IPADDR=127.0.0.1
 TCPPORT=8001
 CHANNEL=A
 PACLEN=128
 TXDELAY=500
 FRACK=7000
 RESPTIME=1500
 MAXFRAME=4
 RETRIES=6
WL2KREPORT PUBLIC, www.winlink.org, 8778, BH2VJW-10, PN02TA, 00-23, 145020000, PKT1200, 20, 2, 5, 0
ENDPORT


APPLICATION 1,BBS,,BH2VJW-9,,0
APPLICATION 3,RMS,C 1 CMS,BH2VJW-10,,0
APPLICATION 2,CHAT,,BH2VJW-8,,0

LINMAIL
LINCHAT

PORT1是用作本地管理的,不要转发到外部。本地访问8080端口可以打开管理网页,8010可支持telnet连接,FBB端口不知道具体作用。

PORT2配置连接Direwolf。注意这里与Linux下配置AX.25的区别,这里我们使用了Direwolf 的 KISS over TCP 协议,没有与Linux的AX.25协议产生关系,所以可以忘掉 kissattach kissparams axports 了。

完成上述配置后运行 linbpq 即可,注意 linbpqbpq32.cfg 放在同一个目录下。

下面进行连接测试。

连接测试

call wl2k bh2vjw-7  #连接到Node,连接到Node后可以再行选择连接到下面这些
call wl2k bh2vjw-8  #连接到聊天服务器
call wl2k bh2vjw-9  #连接到BBS
call wl2k bh2vjw-10 #连接到Winlink

测试顺利完成,至此距离我们的Node上线运行只有连接电台一步之遥了!

为了能够公开节点信息,还需要联系Winlink管理员进行认证。在Live System Information 页面搜索 BH2VJW 可以看到,我们的网关由于未经认证,所以是红色状态,在Live System Information 地图上也没有显示。话说地图上显示整个东亚地区公共节点数为0,我这个或许会开创先河?

下步计划撰写systemd服务实现开机自启与进程守护。

前言

packet radio由于年代久远,国内相关讨论几乎不存在,偶见只言片语也无法形成体系。今天偶然之间读到了 WB9LOZ 成文于上世纪的 packet radio 专栏 INTRODUCTION TO PACKET RADIO。整个系列由十八篇文章构成,涵盖了packet radio的方方面面,是不可多得的高价值资料,强烈建议对packet radio感兴趣的爱好者阅读。

第一篇 什么是Packet Radio

Packet Radio的起源

Packet Radio起源于1980年。1983年11月,大名鼎鼎的AX.25协议发布,同年TAPR TNC1发布。到1984年,基于Packet Radio的BBS等应用在美国、加拿大等地已经很流行。

Packet Radio的林林总总

你是否已经厌倦了HF频段上的他台干扰?是否想在FM上尝试新玩法?是否想体验比RTTY更快、更好的信息传输方式?那么你应该尝试下Packet Radio。

在上个世纪,Packet Radio硬件一般有以下几个类型:

  1. 电台 - TNC - 电脑
  2. 电台 - TNC - 哑终端
  3. 电台 - 调制解调器 - 电脑(电脑上同时运行特殊软件,比如Baycom)

所谓的TNC(terminal node controller) 实现了 ASCII字符 - AFSK语音 之间的转换,和过去电话线拨号上网很类似。比较经典的硬件TNC包括TAPR出品的TNC-1和TNC-2,以及它们的仿制品。

第二篇 实现Packet Radio发射接收

这篇详细介绍了TNC的使用方式。简言之,硬件连接妥当后,电脑上用terminal连接到TNC,然后进入TNC的命令模式进行交互式操作。

编者按:我们没有这种老式的全功能硬件TNC,所以作者苦心教授的各类 TNC 命令就没用了 。。。 我们用direwolf模拟的只是 KISS TNC

关于传统TNC与KISS TNC的比较可以参考这篇文章:Keep It Simple Stupid – KISS ,文章摘要如下:

  1. KISS协议是电脑与TNC通信的一种协议。TNC在KISS模式下,电脑接管了绝大部分工作。这种模式中,TNC并不关心数据包的来源和目的地(呼号),而是无差别解码收到的全部数据包,由主控电脑决定如何呈现或者处理这些信息。
  2. KISS 模式并没有将PTT控制移交给电脑,PTT仍然由TNC控制。
  3. 有的TNC支持传统与KISS两种模式,文中同时介绍了切换办法。

The KISS TNC: A simple Host-to-TNC communications protocol同样参考阅读。传统的TNC强调与人的交互性,缺点是对人可读性好的格式,对于电脑控制并不友好,反之亦然。KISS TNC完全移除了AX.25以及前一篇文章中介绍的命令解释器,由主控电脑来实现AX.25并运行各种命令。由于AX.25以及控制命令与各种程序运行在一台电脑上,系统整体的耦合型更好了。

值得玩味的是,这篇文章虽然最初发布于1987年,但是作者已经明确指出KISS TNC也只是权宜之计,理想条件下电脑应该有HDLC接口,这样独立的TNC硬件就全无必要了。目前我们 电脑 + 声卡 + Direwolf 的方案,是否实现了作者35年前的设想?

回到第二篇文章本身。虽然TNC命令没有参考价值了,不过几十年来信息呈现方式几乎没有变化:

WB9LOZ > W6PW-3: The meeting will be held at 8:00 pm.
WB9LOZ > W6PW-3,W6PW-1*: The meeting will be held at 8:00 pm.

假设这是作者在频率上收到的信息。WB9LOZ 发送给 W6PW-3 “The meeting will be held at 8:00 pm”,区别在于第一个为直频连接,第二个经过了 W6PW-1 的中转。这个W6PW-1就是所谓的 digipeater,扮演中继作用。

这里引入两个概念: 别名SSID

别名 是有别于呼号的一串由字母和数字组成的字符,常见命名规则为地名,后面可以跟SSID。对于用户而言,呼叫呼号后者呼叫别名是等价的(因为别名会被替换回呼号,比如digipeater中继数据包时,地址里的别名会被替换回呼号)。这部分也可以参考Direwolf文档 Page 90

SSID 是呼号后面0-15的整数,例如 WB9LOZ-5WB9LOZ-0 等价于 WB9LOZ 。SSID一般用于标识同一个呼号下的多个电台/端口。

第三篇 TNC命令(1/3)

该篇讲解了 TNC2 常用命令用法。虽然这些命令已经没有用武之地了,不过从中可以了解到 Packet Radio 应当具有那些功能,因此值得回顾。

CONV

CONV(conversation)为会话模式,当连接到他台时自动进入此模式。在非连接模式下,也可以手动切换到该模式,此时发送的所有信息都会被发送到预设的 UNPROTO 路径,而且只发送一次且没有回执(显而易见)。这个模式一般用于CQ呼叫。

UNPROTO

当发送BEACON或者非连接状态下CONV发送信息的目的地,默认值为CQ,不过也可以设置令其经由digipeater,或者发送给某个别名(比如本地业余无线电协会)。例子:

  • CQ v WB6SDS-2,W6SG-1,AJ7L
  • SFARC v W6PW-1,W6PW-4

编者按:ax25tools 提供的beacon可以实现上述无连接发射功能。

FRACK

TNC 等待回执的最长时间,如超时则重发。

DWAIT

TNC 在频道上收到他台数据包后,自身发射数据前的等待时间,用于避免多个电台同时发射。

PACLEN

一个数据包中的有效字符数量,0~255,0代表256。显然,这个值越大,单个数据包发送时间越长,越容易被干扰破坏。通信距离较短,状况良好时这个值可以大一些,反之小一些较好。

RETRY

TNC如果没有收到他台回执,重新发包的最大次数。不要将其设为0!

MONITOR

监视模式。如果这个选项设置为 OFF ,那么就只能看到当你连接到其他站点时,其他站点发送给你的信息。如果这个选项打开,则可以看到其他电台之间,或者其他电台非连接模式的广播。有几个选项可用:

MAIL:如果打开,可以看到其他电台之间的通信,也可以看到其他电台在非连接模式下广播的数据包。如果这个选项为OFF,就只能看到其他电台在非连接模式下广播的数据包。

MCOM:如果打开,可以额外显示 connect , disconnect , acknowledge ,busy 等信息。

MCON:如果打开,在自身已经与其他电台建立连接的情况下,可以显示第三方电台的信息。

MRPT:显示数据包完整传输路径,否则只显示source和destination,不显示digipeater。

HEADERLN:打印每个数据包的header信息。

MSTAMP:显示每个数据包的时间戳。

编者按:这些功能在AX.25,Direwolf等中有类似实现。

第四篇 中继(Digipeater)与节点(Node)

Digipeater与FM语音中继的区别

FM语音中继一般为双工模式,接收与转发同时进行。Digipeater一般为单工模式,收到数据包后先暂存,然后在合适时机进行转发。 TNC可以通过 DIGIPEAT 命令将自己的站点变成一个 Digipeater。

Digipeater与Node的区别

常见的节点有 Net/RomTheNetG8BPQ packet switch,以及 KA-Node 。使用digipeater时,只需要将digipeater作为路径进行指定。使用节点时,需要首先和节点建立连接。 通过适当配置,一个站点可以同时扮演digipeater与node的角色。

使用Node具有一些好处:

  1. 连接到Node后,可以通过 N 命令列出当前节点可通达的全部节点,在发起DX呼叫时,就可以二次连接到距离目的地最近的节点进行呼叫

  2. 使用Node进行DX QSO时,数据包回执在相邻节点之间进行,而不需要像digipeater那样跑完全程,这样可以大大减少retry次数,提升通信效率。

编者按:Direwolf提供了Digipeater功能,Node可以用LinBPQ搭建。不过我附近这两个都没有。。。看看能不能蹭蹭APRS吧。

第五篇 BBS介绍

连接到BBS的方式与连接到其他普通站点的方式无异,如果目标后面有SSID,不要把它忘记。

编者按:ax25apps提供的call即可用于连接。ax25apps同时提供了ax25_call。二者的显著区别之一在于,call会进行行尾换行符的转换,而ax25_call不会。在旧式系统上,换行符为,即熟悉的 \r。现代Linux系统的换行符为 \n

支持AX.25的内核,ax25app,ax25tools再加上Direwolf即构成了使用Packet Radio的最小软件环境。通过listen监听,call建立连接,beacon发送无连接状态信息。如果熟悉APRS格式还可以手动编制信息发送。

回到文章本身。BBS系统一般不设置密码,因为业余无线电是明文传输,即便设置了密码,在连接过程中也会变得众所周知,所以毫无意义。等完成Packet Radio实操后可以拿LinFBB搭建一个玩玩,不过人们都在玩FT8,所以十有八九又会变成一个自嗨的项目 XD

第六篇 Packet BBS的命令

这篇介绍了BBS的常用命令。各个BBS的命令大同小异,有兴趣可以自行了解,或者自己搭建LinFBB通过telnet连接测试。

第七批 分层寻址

分层寻址(HIERARCHICAL ADDRESSING)这个翻译不知是否贴切。格式如下:

 addressee-call @ BBS-call.#local-area.state-province.country.continent

例子

WB9LOZ @ W6PW.#NCA.CA.USA.NOAM

源码地址: https://www.cantab.net/users/john.wiseman/Downloads/LatestLinBPQSource.zip

为了在Manjaro ARM下成功编译,需要对源文件进行如下改动:

  1. makefile第22行,将

    all: CFLAGS = -DLINBPQ -MMD -g
    

    修改为

    all: CFLAGS = -DLINBPQ -MMD -g -fcommon
    

    如果不加入 -fcommon 选项,编译时gcc会提示 multiple definition 错误。

  2. makefile第31行,将 libminiupnpc.a 修改为 libminiupnpc.so 。谨慎起见先检查一下 miniupnpc 这个包有没有安装,它提供了 /usr/lib/libminiupnpc.so

  3. BBSUtilities.c 第9797行,将

    config_set_auto_convert (&cfg, 1);
    

    修改为

    config_set_option(&cfg, CONFIG_OPTION_AUTOCONVERT, 1); 
    

保存上述修改后执行 make -j$(nproc) 编译即可。结束后当前目录会出现名为 linbpq 的可执行程序。这个程序可以移动到其他方便使用的地方,但是注意 linbpq 默认会在运行路径下寻找配置文件并生成log,暂时还不清楚如何指定配置文件位置。

LinBPQ配置比较复杂,可以参考开发者亲自撰写的LinBPQ Guides

再次致谢LinBPQ的开发者 John G8BPQ ,他对编译中遇到的问题给出了解决办法,使Manjaro ARM运行LinBPQ成为现实。大师教导参见 https://groups.io/g/bpq32/topic/92582455