Bootstrap

OpenHD改造实现廉价高清数字图传-OrangePi i96移植篇

        前面说到,天空端的树莓派zero也涨价的厉害,以及500多块了,实在是贵的离谱啊,所以还是要找国产化替代。先从最便宜的OrangePi i96开始吧,毕竟只有39元的价格,还能跑ubuntu,实在是厉害了。

目录

一、搭建OrangePi i96内核和驱动的编译环境

1、源代码下载

2、内核镜像和驱动编译

3、更新到sd卡中

二、RTL8812AU网卡驱动修改和编译

1. 下载驱动源代码

2. 添加到内核和模块中编译

3.修改rtl8812的bug和内核头文件

4.编译内核和模块

5.其他存在的问题及解决措施

三、编译和运行svpcom版本的wifibroadcast

1. 首先下载wfb源代码

2. 安装一些依赖

3. 编译wifibroadcast

4.补充安装软件

5. 单独运行发送程序

6. 将密钥文件拷贝到接收端

7. 在地面端启动接收软件

8. 测试一下通联情况

四、使用gstreamer采集和显示视频

1、OrangePi i96 摄像头驱动安装

2、gstreamer采集视频和接收显示

 五、测试效果


一、搭建OrangePi i96内核和驱动的编译环境

编译环境是搭建在ubuntu pc上

1、源代码下载

git clone https://github.com/orangepi-xunlong/OrangePi_Build.git

注意:这个下的不是源代码,是构建编译环境的相关脚本

然后执行 ./Build_OrangePi.sh
提示输入root密码,按照提示选择i96开发板。
这个脚本会自动下载编译内核镜像所需要的全部源代码。
下载时间比较慢,最好用git代理,不然非常慢。

2、内核镜像和驱动编译

下载完成后,出现文件夹OrangePiRDA
有一个脚本build.sh,使用root权限执行,即可对内核镜像等进行编译。
第一次的编译过程会比较长,耐心等待。

3、更新到sd卡中

还是执行./build.sh脚本,根据界面提示操作
选择update XXXX,可以更新内核文件、驱动模块、uboot
将sd卡插入到系统中,并挂在到相应的目录
一共有两个分区:
小一点的是boot分区,内核更新的时候就写这个路径
大一点的是rootfs分区,就是系统的根目录,更新模块的时候填写这个路径

每次编译内核或驱动,都要执行一遍更新。

二、RTL8812AU网卡驱动修改和编译

搭建完内核和驱动的编译环境,就可以编译rtl8812au的驱动了

1. 下载驱动源代码

进入内核驱动目录kernel/drivers/net/wireless
在这里下载驱动代码
git clone -b v5.2.20 https://github.com/svpcom/rtl8812au.git
注意要选择正确的版本v5.2.20
会生成一个文件夹rtl8812au,里面就是我们的驱动代码
我们不妨将这个文件夹改名为rtl8812au-svpcom,便于区分

2. 添加到内核和模块中编译

2.1 修改Kconfig
在kernel/drivers/net/wireless/Kconfig
添加一行,将驱动的配置增加进去

source "drivers/net/wireless/rtl8812au-svpcom/Kconfig"

可以加在source "drivers/net/wireless/rdaw80211/Kconfig" 下一行

2.2 修改Makefile
在kernel/drivers/net/wireless/Makefile添加一行

obj-$(CONFIG_RTL8812AU)                += rtl8812au-svpcom/

可以放在obj-$(CONFIG_RTLWIFI)          += rtlwifi/  的下一行

这样就可以添加到编译环境中去了,到时会自动编译

3.修改rtl8812的bug和内核头文件

3.1 修改内核头文件
        编译的时候会遇到好几个问题,主要还是这个linux的内核还是太老了,有些头文件都不是新的,所以会有问题。
        主要是这两个文件,可以从最新的linux内核中找到这两个文件,替换掉当前内核的文件即可。

include/uapi/linux/nl80211.h
include/net/ieee80211_radiotap.h

3.2 修改rtl8812的bug
(1)第一个bug
位于rtl8812au-svpcom/os_dep/linux/wifi_regd.c b/os_dep/linux/wifi_regd.c 

@@ -334,11 +334,11 @@ static void _rtw_reg_apply_flags(struct wiphy *wiphy)
                                if (ch)
                                        ch->flags &= ~(IEEE80211_CHAN_DISABLED|IEEE80211_CHAN_NO_HT40PLUS|
                                                IEEE80211_CHAN_NO_HT40MINUS|IEEE80211_CHAN_NO_80MHZ|
-                                               IEEE80211_CHAN_NO_160MHZ);
+                                               IEEE80211_CHAN_NO_160MHZ |
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
                                                IEEE80211_CHAN_NO_IBSS|IEEE80211_CHAN_PASSIVE_SCAN);
 #else
-                                               IEEE80211_CHAN_NO_IR;
+                                               IEEE80211_CHAN_NO_IR);
 #endif
                                                //ch->flags = IEEE80211_CHAN_DISABLED;
                        }

在内核版本低于3.14.0的时候会出现bug,估计是肉眼可见的笔误,括号写的有问题。

(2)第二个bug
在Makefile里面也有一个bug
位于rtl8812au-svpcom/Makefile
这个TopDIR实际上没有什么用,但是这个值确实不太对,导致编译时候找不到
这里我直接修改成绝对路径,确保编译通过。
这路径应该替换成你自己的路径即可。

-include $(TopDIR)/hal/phydm/phydm.mk
+#include $(TopDIR)/hal/phydm/phydm.mk
+include /home/hooper/Orangepi/new/OrangePiRDA/kernel/drivers/net/wireless/rtl8812au-svpcom/hal/phydm/phydm.mk

3.3 修改rtl8812的编译的CPU平台配置
还是修改Makefile
找到CONFIG_PLATFORM_I386_PC,将后面的y改成n
找到CONFIG_PLATFORM_ARM_RPI,将后面的n改成y

CONFIG_PLATFORM_I386_PC = n
CONFIG_PLATFORM_ARM_RPI = y

4.编译内核和模块

        注意,由于修改了内核头文件,所以要连同内核一起编译才行,否则光编译模块,放到板子上跑会有问题的。

        执行编译脚本,根据提示编译内核和模块,然后更新到sd卡即可。

./buid.sh

5.其他存在的问题及解决措施

5.1 驱动添加进去但是没有被编译
如果发现内核模块添加进去,但没有被编译到,那就要把编译的脚本稍微修改一下。
在scripts/lib/compilation.sh,找到这一行

make -C $LINUX ARCH=${ARCH} CROSS_COMPILE=$TOOLS ${BOARD}_linux_defconfig

可以把它注释掉,当然你要确保先编译并生成过.config文件了
这样再编译的时候会提示你增加了新驱动,你可以选择将它编译成模块,输入m即可

5.2 bsdtar找不到
        这个安装包已经过时了,所以你可以选择自己手动安装,或者换名字

Package bsdtar is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
  libarchive-tools:i386 libarchive-tools

在scripts/lib/general.sh中,找到

apt-get -y --no-install-recommends --fix-missing install \
                       bsdtar mtools u-boot-tools pv bc \

将bsdtar删除掉
自己手动安装替换的包

sudo apt install libarchive-tools

三、编译和运行svpcom版本的wifibroadcast

        编译wifibroadcast是在OrangePi i96上直接编译,下面所有的操作是在开发板上进行的。使用串口连接到开发板,通过串口命令行进行交互。

1. 首先下载wfb源代码

git clone -b release-22.09 https://github.com/svpcom/wifibroadcast.git

如果慢可以通过代理下载

2. 安装一些依赖

sudo apt install python3-all libpcap-dev libsodium-dev python3-pip python3-pyroute2 python3-future python3-twisted
sudo apt install virtualenv

3. 编译wifibroadcast

可以修改Makefile,不需要做测试。在第12行,将test删除即可

# all: all_bin gs.key test
all: all_bin gs.key

然后执行make

4.补充安装软件

This system doesn't provide enough entropy to quickly generate high-quality random numbers.
Installing the rng-utils/rng-tools, jitterentropy or haveged packages may help.
On virtualized Linux environments, also consider using virtio-rng.
The service will not start until enough entropy has been collected.

编译可能报错,按照要求安装一下相关软件

sudo apt install rng-tools haveged 

5. 单独运行发送程序

将scripts文件夹中的tx_standalone.sh拷贝到根目录下,执行以下脚本。

#wlan1替换成你的无线网卡的名称
sudo ./tx_standalone.sh wlan1

命令行输出以下内容,说明发送端已经正常启动了。

Setting wlan1 to channel 149
Listen on 5600 for wlan1

6. 将密钥文件拷贝到接收端

在编译的时候会自动生成密钥对
drone.key和gs.key
分别用于天空端(发送)和地面端(接收)
主要要在两边要保持这两个文件是一对,这样才能确保解码正确

7. 在地面端启动接收软件

在PC上编译过程类似,不再描述
主要是启动脚本不一样,拷贝scrpits文件夹中的rx_standalone.sh到所在目录,执行脚本

#wlan1替换成你的无线网卡的名称
sudo ./rx_standalone.sh wlan1

8. 测试一下通联情况

     wfb程序会通过UDP端口与应用程序进行交互

     在天空端(orangepi),我们可以通过nc指令向wfb程序发送数据,wfb收到后会直接将UDP数据通过wifibroadcast发出去;

     在地面端(PC),我们可以通过nc指令接收来自wfb的UDP数据包,这样可以测试一下链路是否正常。

     还可以使用tcpdump来进行调试

sudo tcpdump -i wlan1 -n -p

四、使用gstreamer采集和显示视频

1、OrangePi i96 摄像头驱动安装

       OrangePi i96自带了摄像头驱动,使用的摄像头是gc2035

        先用sudo orangepi-config,根据提示来安装摄像头驱动

        安装完成后,可以使用系统自带的程序测试一下

        位于home目录下,CameraTest文件夹,执行test.sh,会自动加载驱动,然后拍一张照片到本目录下。

2、gstreamer采集视频和接收显示

         gstreamer 安装

sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools 

        

      在发送端,执行命令行

gst-launch-1.0 v4l2src ! video/x-raw, width=640, height=480, framerate=30/1  ! videoconvert ! x264enc tune=zerolatency speed-preset=ultrafast bitrate=4096 ! h264parse ! rtph264pay pt=96 mtu=1200 ! udpsink host=127.0.0.1 port=5600  sync=false 

        这个命令从摄像头采集数据,编码成H264,然后打包成RTP协议,通过UDP发送给wifibroadcast进行传输

        这里有几个要注意的:

        1、由于驱动的限制,图像大小只能是640X480,其他大小会出错

        2、x264enc,是软件编码,使用CPU进行,由于开发板性能不高,所以必须设置速度为ultrafast 延迟为zerolatency,bitrate看情况默认是2048kbit/s,这里我用的是4096

                

     在接收端,执行命令行

gst-launch-1.0 -v udpsrc port=5600 caps="application/x-rtp, media=video, encoding-name=H264, payload=96" ! rtph264depay ! decodebin ! videoconvert ! autovideosink sync=false

     这里从wifibroadcast接收到UDP包,使用5600端口,然后用H264解码显示

 五、测试效果

     整体测试看,效果一般,延迟大概在400ms左右,主要原因还是这个开发板的性能确实不太行,但是勉强也是能用的。

     整体功耗比较低,在发送的时候只有3w,电流0.5A左右,已经算比较低了。

;