OpenIPC开发文档
跟踪日志
2024/1/9
通过 TFTP 和 UART 逐步安装 OpenIPC 固件。
2024//
2024//
参考文章
说明
核心就是利用网络摄像头,而且网络监控的市场很大,网络摄像头可选择的范围很大,可以根据主控芯片、图像传感器的型号,以及板载的串口(刷鞋固件、通信),USB(连接WIFI网卡)的情况自由选择
我这里选择的是 SigmaStar SsC338Q 分辨率4K@20FPS 内置2Gb DDR3
架构:
我的工作任务:
- 硬件环境的搭建
- openipc固件的烧写
- 天空端电路搭建
- 地面端环境的烧写
- 固件的编译和编译脚本
- 裁剪的openipc linux内核中执行启动脚本的过程
- rtl8812网卡天空端驱动(内核配置的)、rtl8812au地面端驱动(开源项目)
- 摄像头驱动(开源的),视频编码器(闭源方案)
- wfb-ng数据链路
- 地面端解码方案(安卓、linux、嵌入式开发板)
固件安装
这里是利用的TFTP和UART来安装固件
SoC识别
SoC(系统级芯片)包括相机的 CPU 内核以及所有必要的外围设备,例如相机和网络接口。这部分由摄像头厂商确定,需要看IC标记丝印来查看,或者使用ipctool软件识别SoC型号
闪存芯片大小
通常是摄像头8引脚的一个芯片,可以通过U-boot启动过程确认,也可以查看丝印(丝印包含64,即是8M,包含128,即16M)
TFTP服务器
TFTP(Trivial File Transfer Protocol)服务器是一种简单的文件传输协议服务器,用于在网络设备之间传输文件。与FTP(File Transfer Protocol)相比,TFTP更轻量级,通常用于在局域网(LAN)中传输小文件,如配置文件、固件更新等。
说白了就是用它来传固件的
连接相机的UART端口
最好是看摄像头手册 好用的就是一个usb转ttl的串口适配器
将适配器上的引脚连接到 UART 端口的可能触点。使用标准电源适配器为相机供电。如果幸运,就可以在终端窗口中看到 Booting log。在某些情况下,如果在屏幕上看到乱码文本而不是引导内核,需要将连接速度更改为 57600 bps,然后重试。RX、TX
访问bootloader
通过按计算机键盘上的组合键来引导加载程序控制台, 在 bootloader 启动和 Linux 内核启动之前。 在上电的时候疯狂enter
进入u-boot的命令行
setenv ipaddr 10.81.1.230;setenv serverip 10.81.1.102 |
U-Boot 命令系列显示了一个典型的嵌入式系统启动流程,尤其是在网络启动(TFTP)和闪存操作方面的详细步骤。
-
setenv ipaddr 10.81.1.230
和setenv serverip 10.81.1.102
这两个命令设置了 U-Boot 环境变量,用于指定网络设置,用于通过 TFTP 下载内核或文件系统镜像:ipaddr
:这设置了 U-Boot 启动时使用的本机 IP 地址,10.81.1.230
是设备将会使用的 IP 地址。serverip
:指定了 TFTP 服务器的 IP 地址,10.81.1.102
是存储内核镜像的服务器。
-
mw.b x21000000 x x1000000
清空或初始化内存区域,确保内存中没有残留数据mw.b
是 U-Boot 中的 “Memory Write Byte” 命令,它用于在内存中写入数据。x21000000
是目标内存地址,这里是指将数据写入设备内存的地址0x21000000
(通常是设备的 RAM)。x
是要写入的值,代表数据的内容。x1000000
是写入的字节数,表示要写入的字节数为0x1000000
(即 16MB)。
-
tftpboot 0x21000000 openipc-ssc338q-fpv-16mb.bin
通过网络从10.81.1.102
服务器上获取openipc-ssc338q-fpv-16mb.bin
文件,并将其存储到设备内存中,准备进行闪存写入。tftpboot
命令从 TFTP 服务器下载文件,并将文件加载到指定的内存地址。0x21000000
是目标内存地址,这里表示将下载的文件存储在内存地址0x21000000
开始的位置。openipc-ssc338q-fpv-16mb.bin
是要下载的文件名,通常是嵌入式设备的固件或内核镜像文件。
-
sf probe 0; sf lock 0;
在闪存上执行写入操作时,相关区域不会被意外覆盖。sf probe 0
:初始化并识别闪存设备,0
是闪存设备的编号。在 U-Boot 中,sf
是指闪存(SPI Flash),这个命令确保设备能够识别并与闪存进行通信。sf lock 0
:锁定闪存的第一个区域,通常用于防止闪存区域被意外擦除或写入。
-
sf erase 0x0 0x1000000
这个命令用于擦除闪存的特定区域,擦除操作确保闪存上的旧数据被清除,为写入新的镜像做准备。:sf erase 0x0 0x1000000
表示擦除从地址0x0
开始,大小为0x1000000
(即 16MB)的闪存区域。
-
sf write 0x21000000 0x0 0x1000000
将内核镜像(或者其他固件文件)写入到设备的闪存中,为下次启动准备好内核。sf write
用于将数据从内存写入闪存。0x21000000
是内存中的数据起始地址,前面的 TFTP 操作已经将内核镜像存放在该地址。0x0
是闪存的起始地址,表示将数据写入闪存的第一个位置。0x1000000
是写入的字节数,表示将 16MB 的数据从内存写入闪存。
-
reset
reset
命令重启设备,使设备重新启动并从闪存或其他启动介质加载操作系统。
U-Boot 命令,设备完成了以下操作:
- 配置了网络设置(
ipaddr
和serverip
)。 - 清空并初始化了内存区域。
- 从 TFTP 服务器下载了一个固件镜像到内存。
- 对闪存进行了操作,包括擦除和写入内核镜像。
- 最终触发系统重启,准备从新写入的镜像启动。
保存原始固件
固件烧写
串口登录设置
网络配置及远程登录
连接wifi网卡
检查WiFi模块的识别情况
生成和安装 WFB-NG 的密钥配对
编辑 wfb.conf 以设置正确的 wifi 频道
在相机上配置 majestic.yaml 文件
视频延时组成
视频链路:摄像头==》编码==》传输==》解码==》显示
整个图传系统的延时主要是:编码延时、传输延时、解码延时:
- 摄像头数据采集延时(camera)
- 编码器编码延时(H264 codec)
- 无线网络延时(wfb_ng): ~ 5ms
- 解码器解码延时(H264 decoder)
- 显示器刷新延时(monitor refresh rate)
解码延时
解码延时中包含
- Wfb 解包时间
- 内核队列延迟
- 硬件解码时间
gstreamer
Jetson 的 NVIDIA V4L2 解码器(如 nvv4l2decoder)通过专用硬件模块(如 NVDEC)实现 H.264/H.265 视频流的硬解码,显著降低 CPU 负载并减少处理延迟
V4L2 驱动:
V4L2 是 Linux 内核中用于视频设备的标准接口。
- 用户空间程序(如 GStreamer)访问摄像头数据。
- Jetson 平台上的 V4L2 驱动经过优化,能够直接将数据传递到硬件加速器(如 NVDEC 和 NVENC),从而减少 CPU 的负载。
当摄像头驱动捕获到一帧数据后,会将其放入内核中的缓冲区队列中。GStreamer 应用程序通过 V4L2 接口从内核队列中读取数据。
GStreamer 缓冲区与网络弹性
动态缓冲管理:
- 流媒体场景中,通过监听 GST_MESSAGE_BUFFERING 消息动态调整缓冲区大小。例如,当缓冲级别低于 100% 时暂停流水线,待缓冲恢复后继续播放,避免因网络波动导致的数据饥饿。
时钟同步机制:
- GStreamer 全局时钟(如 GST_CLOCK_TYPE_REALTIME)的丢失会触发重新同步。处理 GST_MESSAGE_CLOCK_LOST 消息时,需暂停并重启流水线以重建时钟基准。
使用 queue 插件限制缓冲区大小
udpsrc port=5600 ! queue max-size-buffers=2 ! rtph265depay ! ...
基础的解码脚本:
#!/bin/bash |
在 jetson 上查看是否调用硬件解码的方法是使用 jtop 工具,具体方法参考《 NVIDIA查看CPU、内存、GPU使用情况 》
地面站
接收端网卡
目前开发的地面站支持的大多是rtl8812au这一款网卡(主要是网卡驱动问题)
并支持monitor 模式
monitor模式
什么是monitor模式
WiFi Monitor模式需要WiFi芯片本身支持,并且驱动要支持相应的接口。
在非Monitor模式 (平时正常使用的状态)下,内核会将802.11帧封装成普通网络帧传递给上层; 而在Monitor模式 下,内核则会直接将802.11帧传给上层,不会进行封装,用户层就通过接口拿到RAW包,可以按802.11帧格式进行包解析处理。
在Linux内核中,hostap_80211_rx 函数是IEEE 802.11接收无线skb的tasklet函数,其作用是处理802.11网卡传递过来的数据包。倘若网卡被设置成monitor模式,该函数中会调用如下分支:
if (local->iw_mode == IW_MODE_MONITOR) { |
在monitor_rx 函数中,主要是prism2_rx_80211 函数,将带有802.11头的skb直接发送给netif。netif为linux内核网络数据包的标准框架。在prism2_rx_80211中,在skb里补充了一个抓包的头,给用户提供更多的包信息。这个头对应的数据结构为linux_wlan_ng_cap_hdr ,具体声明如下:
struct linux_wlan_ng_cap_hdr { |
如何开启
使用如下命令可以实现:
iwconfig wlan0 mode Monitor
其调用了如下ioctl来配置:
ret = ioctl(skfd, SIOCSIWMODE, &wrq);
对应的配置模式,通过wrq参数来定义。而上面的skfd则由下面操作获取:
skfd = socket(AF_INET, SOCK_DGRAM, 0);
网卡选择
网卡官方支持:
RTL8812AU、ar9271、rtl8812eu
https://forums.developer.nvidia.com/t/rtl8822ce-access-point-mode/288083
板载算力板上的网卡型号为rtl8812CE,不支持monitor mode
WIfibroadcast的原理分析:
远距离wifi技术:
2.4GHz 频率
RSSI(Received Signal Strength Indicator)值代表设备接收到的信号强度,通常用负值表示。RSSI 值范围一般如下:
接近 0(如 -30): 信号非常强,设备与信号源的距离较近。
中等值(如 -50 至 -70): 信号质量良好,适合正常通信。
较弱值(如 -80 至 -90): 信号较弱,可能会影响通信质量。
非常弱(小于 -90): 信号几乎不可用,设备可能会断开连接。
解读你的 RSSI 值
你当前的 RSSI 值是 -41:
这是一个非常强的信号,表示设备离信号源很近,通信质量应该非常好。
pkt/s代表每秒传输的数据包数量(packets per second)。这是一种衡量网络性能的指标,用于表示网络接口在一秒钟内可以发送或接收的数据包的数量。这个数值可以帮助评估网络的负载情况和传输效率。较高的pkt/s值意味着网络接口能够处理更多的数据包
8 Mbps (MCS #1 调制) 涉及到的是无线网络通信中的两个概念:数据传输速率和调制编码方案(MCS,Modulation and Coding Scheme)。
-
8 Mbps:指的是数据传输速率,即每秒可以传输的数据量为8兆比特。这是一个衡量网络速度的指标,表示理论上一秒钟内可以传送8兆比特(Mb)的数据。
-
MCS #1:MCS代表调制编码方案,它用于指定在无线通信中使用的调制方式和编码率。不同的MCS索引号对应着不同的调制方式和编码率组合,从而影响数据传输速率和可靠性。MCS #1通常指使用相对较低复杂度的调制和编码策略,以确保更稳定的传输质量,特别是在信号条件不是最优的情况下。
对于802.11n标准(Wi-Fi 4),MCS #1一般对应于使用BPSK(二进制相移键控)调制和1/2编码率。这意味着每个符号携带1个比特的信息,并且有一半的数据位被用于前向纠错编码,以增强数据传输的可靠性。在单空间流(Single Spatial Stream)和20 MHz带宽的条件下,这种配置可以达到大约7.2 Mbps到8 Mbps的数据传输速率。
因此,“8 Mbps (MCS #1调制)”意味着在网络使用特定的调制和编码设置(在此例中为MCS #1,涉及BPSK调制和1/2编码率)时,能够实现的最大理论数据传输速率为8 Mbps。需要注意的是,实际传输速率可能会受到环境因素、设备性能等多种因素的影响。
目标板配置
devices/ssc338q_fpv_openipc-urllc-aio/br-ext-chip-sigmastar/configs/ssc338q_fpv_openipc-urllc-aio_defconfig#L103
BR2_PACKAGE_WIFIBROADCAST=y
配置好选项
软件版配置
general/package/wifibroadcast/wifibroadcast.mk#L7
WIFIBROADCAST_VERSION = 24.08
视频数据发送 & 接收
general/package/wifibroadcast/files/wifibroadcast#L109-L117
运行:
start_drone_wfb() { |
datalink
devices/ssc338q_fpv_openipc-urllc-aio/br-ext-chip-sigmastar/configs/ssc338q_fpv_openipc-urllc-aio_defconfig#L102
BR2_PACKAGE_DATALINK=y
软件版配置
general/package/datalink/files/telemetry#L13-L16
if [ ! -f /usr/bin/telemetry_rx ] && [ ! -f /usr/bin/telemetry_tx ]; then |
general/package/datalink/files/telemetry_drone.conf#L15-L20
stream_rx=144 |
general/package/datalink/files/telemetry_gs.conf#L15-L20
stream_rx=16 |
数据发送 & 接收
start_drone_telemetry() { |
🧱 WiFiBroadcast (WFB-TX) 架构分析图
main(int argc, char* const *argv) |
📊 总结说明
模块 | 功能 |
---|---|
main() | 程序入口,负责参数解析、初始化、启动主循环 |
LocalTransmitter | 负责 FEC 编码、加密、时间戳管理、标签分配 |
RemoteTransmitter | 负责 FEC 解码、丢包恢复、数据注入到 wlanX |
data_source / data_source_local | 主事件循环,处理数据流和控制信号 |
FEC 编解码 | 基于 Reed-Solomon(k,n),支持前向纠错 |
加密机制 | 使用 libsodium 库进行 session key 管理和数据加密 |
Radiotap Header | 封装物理层参数,兼容多种无线网卡 |
控制接口 | 支持通过 control_port 动态调整 FEC 参数 |
日志系统 | 输出运行状态、丢包率、延迟等关键指标 |
📎 示例命令对照
模式 | 命令示例 | 对应函数 |
---|---|---|
发射端 | wfb_tx -u 5600 -k 8 -n 12 -f data wlan0 |
local_loop_udp() |
接收端 | wfb_rx -d -u 5600 host:5600 |
distributor_loop() |
本地测试 | wfb_rx -U /tmp/wfb -d host:port |
distributor_loop_unix() |
注入测试 | wfb_rx -I 10000 wlan0 |
injector_loop() |
Linux 内核启动过程
一旦 U-Boot 把内核加载到内存并将控制权交给内核,Linux 内核就开始启动。内核启动的过程可以分为几个重要的阶段:
内核说明
内核初始化:
解压内核:如果内核是压缩格式(uImage),它会首先被解压。
设置系统环境:内核初始化过程中,会初始化硬件环境,包括内存、CPU、时钟、I/O 控制器等。
启动内核主线程:内核开始执行第一个用户空间进程,通常是 init 进程。
设备驱动加载:内核会根据设备树(Device Tree,DT)或者硬编码的设备信息来加载相关硬件设备的驱动,确保硬件能够被正确识别并与操作系统交互。
内核调度和管理资源:内核的调度器开始工作,管理系统资源,如 CPU、内存、I/O 等。
init 进程和用户空间启动
在 Linux 内核初始化完毕后,控制权会传递给第一个用户空间进程 init,它通常会启动系统中所有的守护进程和服务。
- 挂载 /proc 文件系统。
- 检查并挂载支持的根文件系统。
- 通过 overlay 或 overlayfs 文件系统进行联合挂载,允许在嵌入式系统中以最小化的方式实现根文件系统的可写层。
- 使用 pivot_root 更改根文件系统。
- 挂载其他系统关键文件系统(如 /proc、/dev 和 /overlay)。
RootFS 的内容
在 Buildroot 中,根文件系统(RootFS)是由多个目录和文件构成的,这些目录和文件用于支持系统运行。常见的文件夹有:
/bin/:基本的可执行文件,如 sh、ls 等。
/sbin/:系统管理程序,如 init、ifconfig 等。
/etc/:系统配置文件,如网络配置、服务启动配置等。
/lib/:共享库。
/tmp/:临时文件。
/proc/:虚拟文件系统,提供系统信息。
/sys/:虚拟文件系统,提供内核信息。
/dev/:设备文件。
├── bin |
在这些目录中,init 文件是根文件系统中用于启动系统的第一个进程。
init 与文件系统的关系
在Linux嵌入式系统的开发和维护过程中,了解系统启动和服务管理机制是至关重要的。init 文件本身就是嵌入在构建的文件系统中的。
其中,/etc/init.d/目录扮演了关键角色,它包含了用于初始化、启动、重启或停止各种服务的脚本。
init.d是指包含一系列 Shell脚本 的目录,这些脚本用于控制服务(也称为守护进程)的生命周期。当系统启动时,init进程会根据预定义的规则执行这些脚本,以确保必要的服务能够正确启动。
rcK S01syslogd S30customizer S40network S60crond S98datalink |
系统脚本运行情况
rcS
先看一下rcS文件,它是本目录在开机时最先启动的文件。也是系统进入多用户模式之前的初始化脚本。它会根据配置启动各种系统服务,通常会依赖其他脚本来执行特定的任务。
rcS通常用于:
- 初始化基本系统服务
- 挂载文件系统
- 启动 init.d 目录下的所有 S 开头的脚本
- init.d 目录结构遵循了 SysV init 启动方式,rcS 主要是用来遍历 S 开头的脚本,并依次执行它们。
- 在使用 Buildroot 进行内核裁剪之后,init进程的启动工作流会根据
/etc/init.d
中的启动脚本顺序来执行。
#!/bin/sh |
- 循环遍历
/etc/init.d/
目录下所有以S
开头且后面跟有两位数字(S??*
)的文件。 [ ! -f "$i" ] && continue
检查每个文件是否是普通文件(不是目录等其他类型),如果不是普通文件,则跳过该文件。case "$i" in *) $i start ;; esac
对每个文件(即每个服务脚本)执行start
参数。触发服务脚本的启动。服务脚本内会定义如何启动服务(如启动系统守护进程、初始化硬件设备、配置网络等)。
rcK
与rcS相对
这个脚本通常在系统关闭或者进入单用户模式时运行。它主要用来停止一些服务,清理系统资源。
#!/bin/sh |
S01seedrng
作用是启动一个随机数生成服务,确保系统在启动时能够使用持久化的种子数据来生成加密级别的随机数。其主要作用是增强系统的随机性,确保用于加密和安全任务时生成的随机数质量高,防止系统依赖不安全或预测性的随机数。脚本还支持动态配置种子存储位置和一些特定的安全选项。
S01syslogd
S01syslogd
脚本的作用是启动和管理 syslogd
服务,syslogd
是一个日志守护进程,用于收集、存储和转发系统日志。这个脚本确保 syslogd
正常运行,并在系统启动时自动启动它。
DAEMON="syslogd" |
DAEMON="syslogd"
:定义了守护进程的名称,即syslogd
,它是负责处理系统日志的服务。PIDFILE="/var/run/$DAEMON.pid"
:定义了守护进程的 PID 文件位置,/var/run/syslogd.pid
用于存储syslogd
的进程 ID。DAEMON_ARGS="-n -C64 -t"
:定义了syslogd
启动时的参数:-n
:告诉syslogd
以非守护进程模式启动,即不将其转为后台进程。-C64
:设置日志缓冲区大小为 64 KB。-t
:标记每条日志信息,通常用于调试日志输出。
start
函数
start() { |
start
函数用于启动syslogd
:start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "$DAEMON" -- $DAEMON_ARGS
:该命令通过start-stop-daemon
启动守护进程syslogd
,并将其参数传递给进程。选项解析:-b
:使进程在后台运行。-m
:以守护进程的方式启动。-S
:启动进程时保持锁定。-q
:安静模式,不显示多余信息。-p "$PIDFILE"
:指定存储 PID 文件的位置。-x "$DAEMON"
:指定要启动的守护进程程序,即syslogd
。-- $DAEMON_ARGS
:传递参数给syslogd
,如日志缓冲区大小等。
启动成功后输出
OK
,失败则输出FAIL
。
stop
函数
stop() { |
stop
函数用于停止syslogd
:start-stop-daemon -K -q -p "$PIDFILE"
:使用start-stop-daemon
停止守护进程,-K
表示终止进程,-q
表示安静模式,-p "$PIDFILE"
用于指定 PID 文件。- 停止成功后,删除 PID 文件并输出
OK
,否则输出FAIL
。
处理脚本参数
case "$1" in |
- 脚本通过
case
语句根据传入的参数来决定执行哪个操作:start
:调用start
函数,启动syslogd
。stop
:调用stop
函数,停止syslogd
。restart
或reload
:先停止进程,等待 1 秒后重新启动,确保服务能平滑重启。- 如果参数无效,输出使用提示并退出脚本。
S02klogd
klogd 会收集内核级别的日志信息,通常与 syslogd 配合使用,将内核日志发送到合适的位置。
这个 S02klogd
脚本是一个 SysV-style 启动脚本,专门用于管理 klogd
进程(Kernel Logging Daemon)。它遵循传统的 init 脚本格式,使用 start-stop-daemon
命令来启动和停止 klogd
,并且能够创建 PIDFILE
以便于进程管理。
详细解析
这个脚本的主要作用是控制 klogd
(Kernel Log Daemon)的启动、停止和重启,并且遵循 SysV init 脚本的标准格式。它的结构清晰,主要由以下几个部分组成:
1. 变量定义
DAEMON="klogd" |
DAEMON="klogd"
:定义守护进程的名称。PIDFILE="/var/run/$DAEMON.pid"
:定义进程的 PID 文件路径。KLOGD_ARGS=""
:定义klogd
运行时的附加参数,默认是空的。
2. 读取默认配置
[ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON" |
- 这里会检查
/etc/default/klogd
文件是否可读,如果存在,则加载它的内容。 - 这个设计使得
klogd
的启动参数可以在/etc/default/klogd
里定义,而不是硬编码在脚本中,增强了灵活性。
3. start()
函数
start() { |
- 先打印
"Starting klogd: "
提示信息。 - 使用
start-stop-daemon
启动klogd
:-b
:后台运行(daemonize)。-m
:创建PIDFILE
。-S
:启动服务(start)。-q
:安静模式(quiet),不打印额外信息。-p "$PIDFILE"
:指定PIDFILE
。-x "/sbin/$DAEMON"
:执行/sbin/klogd
。-- -n $KLOGD_ARGS
:传递-n
选项给klogd
,表示不创建PIDFILE
,因为BusyBox
版klogd
不会自己管理PIDFILE
,所以这里用start-stop-daemon
处理。
status=$?
获取start-stop-daemon
的退出状态码:0
代表成功,打印"OK"
。- 非
0
代表失败,打印"FAIL"
。
return "$status"
返回状态码,以便于外部脚本检查。
4. stop()
函数
stop() { |
- 先打印
"Stopping klogd: "
提示信息。 start-stop-daemon -K -q -p "$PIDFILE"
:-K
选项用于停止(kill)进程。-q
选项是安静模式(quiet)。-p "$PIDFILE"
选项指定PIDFILE
,以便找到并杀死klogd
进程。
- 如果进程成功终止:
- 删除
PIDFILE
。 - 打印
"OK"
。
- 删除
- 如果失败,打印
"FAIL"
并返回错误码。
5. restart()
函数
restart() { |
- 先调用
stop()
终止进程。 sleep 1
等待 1 秒,确保进程完全退出。- 重新调用
start()
启动klogd
。
6. 命令行参数解析
case "$1" in |
- 允许
start|stop|restart
作为参数,直接调用相应的函数。 reload
其实是restart
,因为klogd
本身没有reload
机制,所以用restart
代替。- 其他情况打印用法说明,并返回
exit 1
表示参数错误。
S02sysctl
sysctl 用于配置和调整内核参数。这个脚本会设置一些内核的运行时参数,比如文件系统、内存、网络等方面的配置。
脚本概述
这个 S02sysctl
脚本用于管理 sysctl
配置文件的加载。它读取多个配置文件,并将其应用到内核参数中。它还根据是否存在 logger
命令来决定是将输出发送到系统日志中,还是直接输出到标准输出。
详细结构
变量定义
PROGRAM="sysctl"
SYSCTL_ARGS=""PROGRAM
:定义要运行的程序,这里是sysctl
。SYSCTL_ARGS
:用于传递给sysctl
的附加参数,默认为空。
加载配置
[ -r "/etc/default/$PROGRAM" ] && . "/etc/default/$PROGRAM"
- 通过检查
/etc/default/sysctl
文件是否可读,来加载该文件中的配置。
- 通过检查
配置文件源定义
SYSCTL_SOURCES="/etc/sysctl.d/ /usr/local/lib/sysctl.d/ /usr/lib/sysctl.d/ /lib/sysctl.d/ /etc/sysctl.conf"
- 这是一个包含多个路径的列表,
sysctl
配置文件会在这些路径中查找,并按顺序加载。
- 这是一个包含多个路径的列表,
日志功能:
run_logger()
和run_std()
run_logger()
:如果logger
可用,将sysctl
的输出发送到系统日志。run_std()
:如果logger
不可用,将输出直接发送到标准输出或错误输出。
启动函数
start()
start() {
printf '%s %s: ' "$1" "$PROGRAM"
status=$("$run_program" 4>&1)
echo "$status"
if [ "$status" = "OK" ]; then
return 0
fi
return 1
}- 根据配置执行
sysctl
,并根据status
输出结果。
- 根据配置执行
命令行参数处理
case "$1" in
start)
start "Running";;
restart|reload)
start "Rerunning";;
stop)
:;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac- 提供了
start|stop|restart|reload
的参数,执行相应的操作。对于stop
,没有实际操作,:
是一个空操作。
- 提供了
S30customizer
功能概述
脚本入口
- 使用
case "$1"
判断传入参数(如start
或stop
)。 - 通常由
/etc/init.d/
框架调用,传入参数为start
。
- 使用
主要功能
- 设置系统时间。
- 执行自定义化脚本(
customizer.sh
)。 - 配置无线网络(
wireless.sh
)。 - 配置多路复用器和 GPIO(
muxes.sh
)。 - 检查 MAC 地址。
S35modules
负责加载内核模块,这里没有用到。
S38mdev
mdev 是一个轻量级的设备管理工具,类似于 udev,它会管理和创建设备节点,确保设备被正确识别和配置,由于系统没有使用设备接口,没有使用。
S40network
管理网络接口的启动和停止,包括有线网络和无线网络。通过读取 U-Boot 环境变量来动态配置网络设备,并根据设备类型调用不同的初始化逻辑。
脚本内容
1. 读取 U-Boot 环境变量
dev=$(fw_printenv -n wlandev) |
fw_printenv
:- 这是一个工具,用于读取 U-Boot 的环境变量。
-n
参数表示只输出变量值,而不包含变量名。
- 变量含义:
dev
(wlandev
):- 表示无线网络设备的类型或标识符(如 USB、SDIO 或 Modem)。
mac
(wlanmac
):- 表示无线网卡的 MAC 地址。
net
(netaddr_fallback
):- 表示默认的网络地址(如 IP 地址),当没有其他配置时使用。
- 默认值为
192.168.2.10
。
2. 配置无线网络接口
set_wireless() { |
- 功能:
- 根据
dev
的值判断无线设备的类型,并执行相应的初始化逻辑。
- 根据
- 逻辑分支:
- USB 或 SDIO 设备:
if $path/usb "$dev" || $path/sdio "$dev"; then
[ -n "$mac" ] && ip link set dev wlan0 address "$mac"
ifup wlan0- 检查
/etc/wireless/usb
或/etc/wireless/sdio
脚本是否支持当前设备。 - 如果支持:
- 设置无线网卡
wlan0
的 MAC 地址(如果有wlanmac
)。 - 启动无线接口
wlan0
。
- 设置无线网卡
- 检查
- Modem 设备:
elif $path/modem "$dev"; then
ifup usb0
ifup eth1- 如果设备是 Modem 类型,则启动
usb0
和eth1
接口。
- 如果设备是 Modem 类型,则启动
- 回退配置:
[ -e /sys/class/net/eth0 ] && ifconfig eth0 "${net:-192.168.2.10}"
- 如果存在
eth0
接口,则为其分配一个默认 IP 地址(netaddr_fallback
或192.168.2.10
)。
- 如果存在
- USB 或 SDIO 设备:
3. 启动网络服务
start() { |
- 功能:
- 启动网络服务,按以下顺序:
- 启动本地回环接口
lo
。 - 如果存在无线设备(
dev
不为空),调用set_wireless
函数配置无线网络。 - 如果没有无线设备,直接启动有线接口
eth0
。
- 启动本地回环接口
- 启动网络服务,按以下顺序:
4. 停止网络服务
stop() { |
- 功能:
- 停止所有网络接口,包括:
- 本地回环接口
lo
。 - 无线接口
wlan0
。 - USB 网络接口
usb0
。 - 以太网接口
eth1
和eth0
。
- 本地回环接口
-f
参数强制关闭接口,即使接口不存在也不会报错。
- 停止所有网络接口,包括:
5. 脚本入口
case "$1" in |
- 功能:
- 根据传入参数执行相应的操作:
start
:启动网络服务。stop
:停止网络服务。restart
或reload
:先停止再启动网络服务。- 默认:打印用法提示并退出。
- 根据传入参数执行相应的操作:
总结
核心功能
- 动态配置网络接口:
- 根据 U-Boot 环境变量(
wlandev
、wlanmac
、netaddr_fallback
)动态配置网络设备。 - 支持多种无线设备类型(USB、SDIO、Modem)。
- 根据 U-Boot 环境变量(
- 启动和停止网络服务:
- 启动时按需配置无线或有线网络接口。
- 停止时关闭所有网络接口。
运行流程
- 启动流程:
- 启动本地回环接口
lo
。 - 如果存在无线设备,调用
set_wireless
配置无线网络。 - 如果没有无线设备,直接启动有线接口
eth0
。
- 启动本地回环接口
- 停止流程:
- 关闭所有网络接口。
S49ntpd
网络时间协议守护进程,同步系统时间,校准系统的时钟。
S49ntpd
脚本
这个脚本的主要功能是管理 NTP 守护进程(ntpd
)的启动、停止和重启。它通过 start-stop-daemon
工具来控制守护进程的生命周期,并使用 PID 文件来跟踪进程状态。
脚本内容
1. 变量定义
DAEMON="ntpd" |
DAEMON
:- 表示要管理的守护进程名称,这里是
ntpd
(网络时间协议守护进程)。
- 表示要管理的守护进程名称,这里是
PIDFILE
:- 存储
ntpd
进程的 PID 文件路径,用于跟踪进程状态。
- 存储
DAEMON_ARGS
:- 传递给
ntpd
的启动参数:-n
:表示以非后台模式运行(但实际会通过start-stop-daemon
后台化)。
- 传递给
2. 启动函数
start() { |
- 功能:
- 启动
ntpd
守护进程。
- 启动
- 关键命令:
start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "$DAEMON" -- $DAEMON_ARGS
-b
:以后台模式运行进程。-m
:创建 PID 文件。-S
:启动进程。-q
:静默模式,不输出额外信息。-p "$PIDFILE"
:指定 PID 文件路径。-x "$DAEMON"
:指定要启动的可执行文件。-- $DAEMON_ARGS
:传递给守护进程的参数。
- 错误处理:
- 检查
start-stop-daemon
的返回值:- 如果成功(返回值为 0),打印
OK
。 - 如果失败,打印
FAIL
。
- 如果成功(返回值为 0),打印
- 检查
3. 停止函数
stop() { |
- 功能:
- 停止
ntpd
守护进程。
- 停止
- 关键命令:
start-stop-daemon -K -q -p "$PIDFILE"
-K
:发送信号终止进程。-q
:静默模式。-p "$PIDFILE"
:根据 PID 文件找到目标进程并终止。
- 清理工作:
- 如果成功停止进程,则删除 PID 文件。
- 错误处理:
- 检查
start-stop-daemon
的返回值:- 如果成功,打印
OK
。 - 如果失败,打印
FAIL
。
- 如果成功,打印
- 检查
4. 脚本入口
case "$1" in |
- 功能:
- 根据传入参数执行相应的操作:
start
:调用start
函数启动ntpd
。stop
:调用stop
函数停止ntpd
。restart
或reload
:先停止再启动ntpd
。- 默认:打印用法提示并退出。
- 根据传入参数执行相应的操作:
- 注意:
- 在
restart
和reload
中,停止后等待 1 秒再启动,避免资源冲突。
- 在
总结
核心功能
- 启动 NTP 守护进程:
- 使用
start-stop-daemon
后台运行ntpd
,并生成 PID 文件。
- 使用
- 停止 NTP 守护进程:
- 根据 PID 文件终止
ntpd
进程,并清理 PID 文件。
- 根据 PID 文件终止
- 支持重启和重载:
- 提供
restart
和reload
操作,方便重新配置或恢复服务。
- 提供
运行流程
- 启动流程:
- 检查是否可以启动
ntpd
。 - 使用
start-stop-daemon
启动守护进程,并记录 PID。
- 检查是否可以启动
- 停止流程:
- 根据 PID 文件终止进程,并删除 PID 文件。
- 重启流程:
- 先停止,再启动,确保服务重新加载。
S50dropbear
dropbear,这是一种轻量级的SSH服务器,允许远程访问系统。这个脚本会初始化SSH服务,允许通过SSH连接。
S60crond
启动 crond,即定时任务守护进程。它负责执行预定的定时任务,比如周期性地运行某些脚本或程序。
S70vendor
这个脚本通常用于执行供应商特定的初始化任务,为了加载厂商的特定驱动、配置或者服务。
S70vendor
脚本
这个脚本的主要功能是在系统启动时加载特定厂商的模块(可能包括驱动程序或其他硬件相关的初始化逻辑)。它通过调用 ipcinfo
工具获取设备的厂商信息,并动态加载与该厂商相关的模块。
脚本内容
1. 脚本入口
case "$1" in |
- 功能:
- 根据传入参数执行相应的操作:
start
:加载厂商模块。stop
:当前为空,表示不支持停止操作。- 默认:打印用法提示并退出。
- 根据传入参数执行相应的操作:
2. 加载厂商模块
echo "Loading vendor modules..." |
- 功能:
- 使用
ipcinfo -v
获取设备的厂商信息。 - 动态调用与厂商相关的加载函数(如
load_<vendor>
)。
- 使用
- 关键命令:
ipcinfo -v
:- 这是一个工具,用于查询设备的硬件或固件信息。
-v
参数返回设备的厂商名称(如sony
、samsung
等)。
load_"$vendor"
:- 动态构造函数名,例如:
- 如果
vendor="sony"
,则调用load_sony
。 - 如果
vendor="samsung"
,则调用load_samsung
。
- 如果
- 动态构造函数名,例如:
-i
参数:- 传递给加载函数的参数,可能是初始化选项。
3. 停止分支
stop) |
- 功能:
- 当前为空,表示该脚本不支持停止操作。
- 可能原因:
- 厂商模块通常是内核模块或硬件驱动,加载后无需显式卸载。
- 或者,卸载逻辑由其他脚本(如
rcK
或其他Kxx
脚本)处理。
总结
核心功能
- 动态加载厂商模块:
- 使用
ipcinfo
工具获取设备的厂商信息。 - 根据厂商信息调用对应的加载函数(如
load_sony
或load_samsung
)。
- 使用
- 支持启动操作:
- 脚本仅支持
start
操作,用于加载厂商模块。
- 脚本仅支持
- 不支持停止操作:
- 当前未实现停止逻辑,可能由其他机制处理。
运行流程
- 启动流程:
- 打印提示信息:“Loading vendor modules…”。
- 调用
ipcinfo -v
获取厂商名称。 - 动态调用对应的加载函数(如
load_<vendor>
),并传递-i
参数。
- 停止流程:
- 当前未实现停止逻辑。
适用场景
- 该脚本适用于嵌入式设备(如 IP 摄像头)中加载厂商特定的硬件模块或驱动程序。
- 它通过动态调用的方式支持多种厂商,灵活性较高。
S95majestic
S95majestic
脚本
这个脚本的主要功能是管理 majestic
守护进程的启动、停止、重启和重载。它通过 start-stop-daemon
工具来控制守护进程的生命周期,并使用 PID 文件来跟踪进程状态。相比之前的 ntpd
脚本,该脚本增加了对 reload
操作的支持。
脚本内容
1. 变量定义
DAEMON="majestic" |
DAEMON
:- 表示要管理的守护进程名称,这里是
majestic
。 majestic
是 OpenIPC 项目中的一个核心组件,通常用于处理视频流(如 RTSP、HTTP 等)。
- 表示要管理的守护进程名称,这里是
PIDFILE
:- 存储
majestic
进程的 PID 文件路径,用于跟踪进程状态。
- 存储
DAEMON_ARGS
:- 传递给
majestic
的启动参数:-s
:可能是以静默模式或后台模式运行的选项。
- 传递给
2. 启动函数
start() { |
- 功能:
- 启动
majestic
守护进程。
- 启动
- 关键命令:
start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "$DAEMON" -- $DAEMON_ARGS
-b
:以后台模式运行进程。-m
:创建 PID 文件。-S
:启动进程。-q
:静默模式,不输出额外信息。-p "$PIDFILE"
:指定 PID 文件路径。-x "$DAEMON"
:指定要启动的可执行文件。-- $DAEMON_ARGS
:传递给守护进程的参数。
- 错误处理:
- 检查
start-stop-daemon
的返回值:- 如果成功(返回值为 0),打印
OK
。 - 如果失败,打印
FAIL
。
- 如果成功(返回值为 0),打印
- 检查
3. 停止函数
stop() { |
- 功能:
- 停止
majestic
守护进程。
- 停止
- 关键命令:
start-stop-daemon -K -q -p "$PIDFILE"
-K
:发送信号终止进程。-q
:静默模式。-p "$PIDFILE"
:根据 PID 文件找到目标进程并终止。
- 清理工作:
- 如果成功停止进程,则删除 PID 文件。
- 错误处理:
- 检查
start-stop-daemon
的返回值:- 如果成功,打印
OK
。 - 如果失败,打印
FAIL
。
- 如果成功,打印
- 检查
4. 重启函数
restart) |
- 功能:
- 先调用
stop
函数停止majestic
。 - 等待 3 秒(避免资源冲突)。
- 再调用
start
函数重新启动majestic
。
- 先调用
- 注意:
- 等待时间(
sleep 3
)可以防止频繁操作导致的问题。
- 等待时间(
5. 重载函数
reload) |
- 功能:
- 向
majestic
发送SIGHUP
信号(信号编号为 1),触发其重新加载配置。
- 向
- 关键命令:
killall -1 "$DAEMON"
-1
:发送SIGHUP
信号。$DAEMON
:目标进程名称。
- 用途:
SIGHUP
通常用于通知守护进程重新读取配置文件,而无需完全重启。
6. 脚本入口
case "$1" in |
- 功能:
- 根据传入参数执行相应的操作:
start
:启动majestic
。stop
:停止majestic
。restart
:先停止再启动majestic
。reload
:向majestic
发送SIGHUP
信号以重载配置。- 默认:打印用法提示并退出。
- 根据传入参数执行相应的操作:
总结
核心功能
- 启动
majestic
守护进程:- 使用
start-stop-daemon
后台运行majestic
,并生成 PID 文件。
- 使用
- 停止
majestic
守护进程:- 根据 PID 文件终止进程,并删除 PID 文件。
- 支持重启和重载:
- 提供
restart
和reload
操作,方便重新加载配置或恢复服务。
- 提供
- 动态配置管理:
reload
操作允许在不停止服务的情况下重新加载配置。
运行流程
- 启动流程:
- 检查是否可以启动
majestic
。 - 使用
start-stop-daemon
启动守护进程,并记录 PID。
- 检查是否可以启动
- 停止流程:
- 根据 PID 文件终止进程,并删除 PID 文件。
- 重启流程:
- 先停止,再启动,确保服务重新加载。
- 重载流程:
- 向
majestic
发送SIGHUP
信号,触发配置重载。
- 向
适用场景
- 该脚本适用于嵌入式设备(如 IP 摄像头)中管理视频流服务。
- 它通过标准化的方式管理
majestic
守护进程,适合资源受限的环境。
S98datalink
S98datalink
脚本
这个脚本的主要功能是管理数据链路服务(如 LTE 模块、ZeroTier 网络和 Wi-Fi 广播)。它根据设备的硬件信息(通过 ipcinfo
和 U-Boot 环境变量)以及配置文件 /etc/datalink.conf
的内容,动态启动或停止相关服务。
脚本内容
1. 变量定义
chip=$(ipcinfo -c) |
chip
:- 使用
ipcinfo -c
获取设备的芯片型号。 - 示例是
ssc338q
或其他 SoC 名称。
- 使用
fw
:- 从
/etc/os-release
文件中提取BUILD_OPTION
的值。 - 示例输出可能是
lte
或其他构建选项。
- 从
2. 加载配置文件
if [ -e /etc/datalink.conf ]; then |
- 功能:
- 如果存在
/etc/datalink.conf
文件,则加载其内容。 . /etc/datalink.conf
表示将该文件的内容作为当前脚本的一部分执行。
- 如果存在
- 用途:
- 配置文件可能包含以下变量:
usb_modem
:是否启用 USB LTE 模块。use_zt
:是否启用 ZeroTier 网络。zt_netid
:ZeroTier 网络 ID。telemetry
:是否启用遥测功能。
- 配置文件可能包含以下变量:
3. 启动 LTE 数据链路
start_lte() { |
- 功能:
- 启动 LTE 数据链路相关的服务。
- 逻辑分支:
- USB LTE 模块:
if [ "$usb_modem" = "true" ]; then
echo "Starting lte modem configuration..."
fi- 如果
usb_modem="true"
,表示启用了 USB LTE 模块,并打印提示信息。
- 如果
- ZeroTier 网络:
if [ "$use_zt" = "true" ]; then
echo "Starting ZeroTier-One daemon..."
zerotier-one -d &
if [ ! -f "/var/lib/zerotier-one/networks.d/$zt_netid.conf" ]; then
sleep 8
zerotier-cli join "$zt_netid" > /dev/null
echo "Don't forget to authorize my.zerotier.com!"
fi
fi- 如果
use_zt="true"
,启动 ZeroTier 守护进程(zerotier-one
)。 - 如果尚未加入指定的网络(
$zt_netid
),则等待 8 秒后尝试加入,并提醒用户在 ZeroTier 控制台授权设备。
- 如果
- 遥测功能:
if [ "$telemetry" = "true" ]; then
telemetry start
fi- 如果
telemetry="true"
,启动遥测服务。
- 如果
- USB LTE 模块:
4. 启动分支
case "$1" in |
- 功能:
- 根据传入参数执行相应的操作。
- 逻辑分支:
- 检查无线设备:
if [ -n "$(fw_printenv -n wlandev)" ]; then
exit 0
fi- 如果 U-Boot 环境变量中存在
wlandev
,直接退出脚本。 - 这可能是因为无线设备已由其他脚本(如
S40network
)处理。
- 如果 U-Boot 环境变量中存在
- 系统初始化:
if [ ! -f /etc/system.ok ]; then
tweaksys "$chip"
fi- 如果
/etc/system.ok
文件不存在,调用tweaksys
函数对系统进行初始化。 tweaksys
可能是一个自定义函数,用于调整系统配置以适配特定芯片。
- 如果
- 启动 LTE 数据链路:
if [ "$fw" = "lte" ]; then
start_lte
fi- 如果
BUILD_OPTION=lte
,调用start_lte
函数启动 LTE 相关服务。
- 如果
- 启动 Wi-Fi 广播:
echo "Starting wifibroadcast service..."
wifibroadcast start- 启动 Wi-Fi 广播服务(
wifibroadcast
)。
- 启动 Wi-Fi 广播服务(
- 检查无线设备:
5. 停止分支
stop) |
- 功能:
- 停止 Wi-Fi 广播服务。
6. 默认分支
*) |
- 功能:
- 如果传入参数无效,打印用法提示并退出。
总结
核心功能
- 动态加载配置:
- 根据
/etc/datalink.conf
文件的内容,决定启用哪些服务(如 LTE 模块、ZeroTier 网络、遥测功能)。
- 根据
- 启动数据链路服务:
- 包括 LTE 模块、ZeroTier 网络、Wi-Fi 广播等。
- 系统初始化:
- 根据芯片型号调用
tweaksys
函数进行系统调整。
- 根据芯片型号调用
- 支持启动和停止操作:
- 提供
start
和stop
操作,分别用于启动和停止服务。
- 提供
运行流程
- 启动流程:
- 检查无线设备是否存在。如果存在,直接退出。
- 如果系统未初始化,调用
tweaksys
函数。 - 根据
BUILD_OPTION
决定是否启动 LTE 数据链路。 - 启动 Wi-Fi 广播服务。
- 停止流程:
- 停止 Wi-Fi 广播服务。
适用场景
- 该脚本适用于嵌入式设备(如 IP 摄像头或无人机)中管理数据链路服务。
- 它通过动态加载配置和硬件信息,灵活地支持多种网络和服务。
S98vtun
启动 vtun,这是一个虚拟隧道工具,通常用于建立加密隧道,这里没有用到
S99rc.local
rc.local 是启动过程的最后一个步骤,通常用于执行最后的初始化任务或者自定义命令。系统初始化完成后,这里可以添加需要的启动命令,或者启动一些不属于其他服务的应用。
工作流:
- 系统初始化阶段:
rcS
脚本会启动,并执行一些基础的系统配置,包括随机数生成、日志守护进程、内核参数配置等。 - 服务启动:之后,系统会依次启动一些基本的服务,如内核模块加载、设备管理、网络配置、时间同步等。
- 特定应用和服务:进入更具体的应用服务启动,如SSH服务、定时任务、供应商服务、特定功能应用等。
- 最后的清理和自定义配置:
rc.local
负责执行最后的清理、日志保存、或者启动一些额外的定制化服务。
天空端启动总结
/etc/init.d/rcS |
.bin文件角色:作为固件被内核加载,初始化摄像头硬件。
数据流路径:摄像头 → 内核驱动(通过固件) → /dev/video0节点 → 用户空间应用(通过V4L2接口)。
关键检查点:设备节点存在性、内核日志中的固件加载记录、V4L2工具(如v4l2-ctl)测试。
地面站选择
虚拟机Ubuntu
泰山派Android系统
泰山派Ubuntu
算力版jetson
ROS端部署:
|
配合ROS实现
|
|