2. Ubuntu 使用手册

Ubuntu 使用手册是针对 Firefly 官方发布的 Ubuntu 系统固件特性所编写,适用于 Ubuntu Desktop 与 Minimal 系统,部分与 UI 显示相关的介绍,只针对 Desktop 系统。

_images/Ubuntu_Desktop1.jpg

Ubuntu Desktop 系统特点如下:

  • 桌面环境采用 LXDE,Lubuntu + Firefly 定制主题,简洁美观。(Ubuntu 20.04 采用 LXQt)

  • Xserver 使用 GPU + RGA 进行 2D 加速,运行流畅,占用 CPU 资源少。

  • 针对嵌入式平台,精简系统服务。

  • 提供基于 Arm Mali GPU 的 OpenGL、OpenCL 支持。

  • 提供基于 Rockchip VPU + Mpp 的视频硬编解码支持。

  • 适配 QT、Docker、Electron 等开发框架。

  • 提供一系列接口,以操作板载资源设备。

  • 系统采用 overlayfs 文件系统,支持导出 rootfs,二次打包,恢复出厂设置等功能。

Ubuntu Minimal 系统特点如下:

  • 没有桌面环境,占用资源少,在简化网络管理之后,只需 40M 内存。

  • 针对嵌入式平台,精简系统服务。

  • 适配 QT、Docker、Electron 等开发框架。

  • 提供一系列接口,以操作板载资源设备。

  • 系统采用 overlayfs 文件系统,支持导出 rootfs,二次打包,恢复出厂设置等功能。

下面开始是手册具体内容,用户可以在手册目录中选择需要的章节进行阅读。

2.1. 用户和密码

2.1.1. Ubuntu Desktop 系统

Ubuntu Desktop 系统开机启动后,自动登录到 firefly 用户。

如果有连接调试串口,串口终端自动登录 root 用户。

  • firefly 用户密码: firefly

  • root 用户:默认没有设置 root 密码,firefly 用户通过 sudo passwd root 命令自行配置 root 密码。

2.1.2. Ubuntu Minimal 系统

  • Ubuntu Minimal 系统开机启动后,自动登录到 root 用户,密码为 firefly。

  • 系统已经添加 OpenGL ES, OpenCL, DRM 支持。

  • 由于安全策略,sshd 默认不支持远端通过 root 用户登陆,可以通过以下方式开启:

sed -i -e 's/#PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config

2.2. ADB 使用

2.2.1. ADB

用Type-C data cable连接设备和主机,然后输入以下命令:

adb devices
adb shell

2.2.2. 网络ADB

查看开发板 IP 地址,PC 端通过网络访问:

adb connect + IP
adb shell

注意点: Core-3399-JD4 要支持使用 ADB 需要修改kernel/arch/arm64/boot/dts/rockchiprk3399-firefly-aiojd4.dts,将usbdrd_dwc3_0设置为peripheral模式,之后该usb只能作为从设备使用。

&usbdrd_dwc3_0 {
    dr_mode = "peripheral";
};

同理,AIO-3399Pro-JD4 要支持使用 ADB 需要修改kernel/arch/arm64/boot/dts/rockchip/rk3399pro-firefly-aioc.dts

然后重新编译和烧写Kernel。

Core-3399-JD4 与 AIO-3399Pro-JD4 是用双公头USB数据线连接设备usb3.0接口和PC主机。

2.3. linux-headers 和 linux-image

linux-headers 和 linux-image 是两个 deb 包,可安装在 Debian/Ubuntu 系统中。

linux-headers 包含各种头文件,可以让设备具有本地编译驱动的能力。

linux-images 包含编译内核时产生的驱动模块,将这些模块安装到设备中,设备才能 modprobe/insmod 进行使用。如果设备使用了 extboot,linux-image 内还会包含内核,安装即可直接升级内核,免去烧写步骤。

如何确定是否使用了 extboot?请前往板卡对应维基的编译 Ubuntu 固件页面,部分编译章节查看。如果没有 extboot 相关内容,则说明不支持。

2.3.1. 获取方法

2.3.1.1. 下载

Firefly 官方提供了两个 linux-headers 和 linux-image,方便客户在开发板进行内核编译。

各个板卡的下载请到 Firefly 官方《资料下载》页面下载。选择板卡后一般在“资源”处,名称为 linux-headers

2.3.1.2. 制作

官方提供的 headers 和 image 版本和实际固件可能有差异,并且有定制需求的客户也无法使用,因此建议通过 SDK 制作:

首先准备环境、获取 SDK、编译前配置,请前往不同板卡的维基查看,接下来在 SDK 根目录进行编译:

# 选择板卡配置文件
./build.sh xxxx.mk
# 编译
./build.sh kerneldeb

生成的文件会在 SDK 根目录:

linux-headers-x.xx.xxx_x.xx.xxx-xxx_arm64.deb
linux-image-x.xx.xxx_x.xx.xxx-xxx_arm64.deb

2.3.2. 安装

以下以 ROC-RK3568-PC 安装为例:

将得到的 deb 包放入设备中,然后安装,对于 headers,安装后还需要进行编译处理:

对于使用了 extboot 的板卡,安装后重启即可完成内核更新,之后再进行编译 headers

# 安装
sudo dpkg -i linux-headers-4.19.172_4.19.172-189_arm64.deb
sudo dpkg -i linux-image-4.19.172_4.19.172-189_arm64.deb

# 编译
cd /usr/src/linux-headers-4.19.172
make headers_check
make headers_install

# make scripts 可能会出错,如果出错在 tools,可以直接忽略,安装完成
make scripts

2.4. Qt 交叉编译环境支持

Firefly 发布了两个 Qt 交叉编译工具链,适用于以下环境,请根据需求选择:

  • Qt: 5.12.2

  • Host: x86-64 / Ubuntu 18.04

  • Target: Firefly RK3568 RK3566 RK3399 RK3328 PX30 / Ubuntu 18.04 Minimal&Desktop

  • Qt: 5.15.3

  • Host: x86-64 / Ubuntu 20.04

  • Target: Firefly RK3568 RK3566 / Ubuntu 20.04 Desktop

工具链完整支持 wenEngine, 支持 EGLFS LinuxFB XCB 等 backend。

  • 下载地址

点击下载链接(提取码:FFQT)

  • 部署

详情参见工具链中的 Qt5.1x.x_Release.md 文件

注意,文档中所有路径的名称不可更改,否则会导致编译或者运行出错。

  • 编译

在host端,进入 Qt 工程目录,qmake && make 即可.

  • 运行

工具链中提供了两个测试 Demo,分别对应 EGLFS 和 LinuxFB Backend,用户在部署完成后,可以在 host 端 build demo,在 tartget 端运行 demo 以测试部署是否成功。

确定目标 Backend 后,可以修改设备中 /etc/profile.d/target_qtEnv.sh 文件,去除对应平台环境变量前面的#使其一直生效

# 例如,使用 XCB ,则将文件内 XCB 部分前面的 # 删除

#XCB
export QT_QPA_PLATFORM=XCB
export QT_QPA_EGLFS_INTEGRATION=XCB_EGL

2.6. 导出设备系统

此章节适用于: 当用户已经在一台设备上完成工作环境的部署,需要将当前环境完整导出,以批量部署到其它同平台设备上。用户也可以通过导出设备文件系统来备份当前的开发环境。

导出设备系统分为两步

  1. 导出设备rootfs

  2. 二次打包完整固件,将rootfs与其它固件组成部分二次打包,生成完整固件

2.6.1. 导出设备rootfs

  1. 在ubuntu18.04环境下,安装 fireflydev

    sudo apt update
    sudo apt install fireflydev
    
  2. 使用ff_export_rootfs导出根文件系统

    • 建议使用容量较大的移动硬盘

    • 导出工具会执行apt clean等操作以减小文件系统大小

    • 将根文件系统导出到/media/firefly/AC91-C4AE/目录下,实际例子如下:

        root@firefly:~# ff_export_rootfs
        ff_export_rootfs </path/to/store> [-t <ext4|btrfs>]
    
    ff_export_rootfs /media/firefly/AC91-C4AE/
    
    • 压缩文件系统,删除不必要的空白空间以减少存储器资源的占用

        #有部分客户说导出的rootfs大小为3.3G可实际只用了3G,原因是没有对rootfs进行压缩
        e2fsck -p -f Firefly_Ubuntu_18.04.6_rootfs.img
        resize2fs  -M Firefly_Ubuntu_18.04.6_rootfs.img
    

2.6.2. 二次打包完整固件

点击下载链接(提取码:1234)。

sudo apt-get install lib32stdc++6

firefly-linux-repack
    ├── bin
    │   ├── afptool
    │   └── rkImageMaker
    ├── pack.sh
    ├── Readme_en.md
    ├── Readme.md
    └── unpack.sh
  1. 解包 把官方发布的固件拷贝到当前目录,重命名为update.img , 执行unpack.sh 解包完成后,生成的文件在output目录下.

  2. 合包 保持当前目录结构,文件名等不变,用客户自己的文件替换output/下同名的文件 执行pack.sh, 执行完后,生成new_update.img,即为打包好的固件 rootfs文件名必须为rootfs.img parameter.txt文件名必须为parameter.txt

  • 注意: 合包过程中,如果rootfs分区不是最后一个分区,那么程序会根据rootfs文件的大小, 自动修改parameter.txt中rootfs分区的大小。 如果用户自己有改动parameter.txt,请留意整个合包的流程。

tar -xzf firefly-linux-repack.tgz
cd firefly-linux-repack
mv /xxx/FIREFLY-RK3399-UBUNTU18.04-GPT-20200714-1510.img update.img
./unpack.sh

cp /customer/rootfs.img  output/Image/rootfs.img

./pack.sh
ls new_update.img

2.7. 屏幕旋转

Firefly Ubuntu Desktop 使用ff_rotate 脚本来控制屏幕旋转:

  • ff_rotate

root@firefly:~# ff_rotate

        rotate screen and touchscreen
                run as root
                ff_rotate <orientation>
                        orientation: left, right, normal, inverted
#图像输出翻转
root@firefly:~# ff_rotate inverted

2.8. 显示版本信息

  • ffgo

通过 Firefly 提供的 ffgo 命令可以方便的查看固件信息,便于开发者调试以及定位问题。

当用户需要向 Firefly 反馈信息时,需要附上 ffgo version 显示的版本信息。

root@firefly:~# ffgo
Usage:
         ffgo :         show this usage
         ffgo update:   update ffgo
         ffgo version:  get version
         ffgo cmdlist:  get support cmd list
         ffgo [cmd]:    run cmd in cmd list

root@firefly:~# ffgo update
update success
root@firefly:~# ffgo version
OS:      Ubuntu 18.04.5 LTS
MODEL:   Firefly RK3566-ROC-PC HDMI(Linux)
FIREFLY: v2.04-1-g618089a
DATE:    20210316-1035
KERNEL:  Linux version 4.19.172 (liaoxt@tchip16) (gcc version 6.3.1 20170404 (Linaro GCC 6.3-2017.05), GNU ld (Linaro_Binutils-2017.05) 2.27.0.20161019) #107 SMP Mon Apr 19 09:01:32

2.9. 恢复出厂设置

Firefly Ubuntu 支持恢复出厂设置。

注意,此出厂设置表示恢复为设备最后一次升级固件之后的初始状态。

root@firefly:~# recovery
Usage: update <option>

Options are:
        ota | update [path]:
                update firmware, if no path, use default path
                "/userdata/update.img"
                "/sdcard/update.img"
        factory | reset:
                reset to factory

使用 recovery reset 可以恢复到出厂设置。

2.10. 开机自启动程序

Firefly Ubuntu18.04 Desktop 可以使用以下方法设置开机自启动程序,不过需要注意操作权限和当前环境变量:

$ vim /home/firefly/.config/lxsession/Lubuntu/autostart
@/bin/mkdir /home/firefly/ssddd

每个命令使用 @ 开头,以上面的例子为例会创建 /home/firefly/ssddd 目录。

Firefly Ubuntu20.04 Desktop 中,在 LXQt 主菜单中依次点击 Preferences > LXQt Setings > Session Settings,在弹出的窗口中点击 Autostart 页面来添加自启动程序

也可以直接在 /etc/xdg/autostart/ 文件夹下直接添加需要自启动程序的 .desktop 文件

2.11. 视频硬件编解码支持

RK3568/RK3566/RK3399/RK3288 集成的 VPU 具有优秀的视频编解码能力,Mpp 是 Rockchip 为 VPU 提供的一套视频编解码的 api, 并且基于 mpp。Rockchip 提供了一套 gstreamer 的编解码插件。用户可以根据自己的需求,基于 gstreamer 来做视频编解码的应用,或者直接调用 mpp,来实现硬件的编解码加速。

系统提供了一个测试视频文件,位于 /usr/local/test.mp4,测试文件为 1080P, 24Fps, H264 编码, Mp4 格式。

可以通过一下几种方式,验证和开发视频编解码相关应用。

2.11.1. Gstreamer

  • Ubuntu 16.04 下,gstreamer 已经安装在 /opt/ 目录下。

  • Ubuntu 18.04 和 20.04 下,gstreamer 已经安装到系统中。

/usr/local/bin/h264dec.sh 测试硬件 H264 解码。

/usr/local/bin/h264enc.sh 测试硬件 H264 编码。

用户可以参照这两个脚本,配置自己的 gstreamer 应用。

2.11.2. Mpv

系统提供的Mpv播放器,可以直接调用 rkmpp 解码插件。

2.11.3. FFmpeg

FFmpeg 对于 Rockchip 暂时只支持通过 Mpp 实现硬件解码,暂时没有硬件编码的支持。

Firefly Ubuntu 已经安装了 FFmpeg,用户可以直接使用。

  • 确认rkmpp解码器

$ ffmpeg -decoders | grep "rkmpp"

 V..... h264_rkmpp           h264 (rkmpp) (codec h264)
 V..... hevc_rkmpp           hevc (rkmpp) (codec hevc)
 V..... vp8_rkmpp            vp8 (rkmpp) (codec vp8)
 V..... vp9_rkmpp            vp9 (rkmpp) (codec vp9)
  • 测试命令

$ ffmpeg -y -c:v h264_rkmpp -i /usr/local/test.mp4 -an output.yuv

特别注意: FFmpeg h264_rkmpp 解码获得的是 AV_PIX_FMT_DRM_PRIME,也就是 DRM 帧数据,如果是基于 drm 显示,可以直接输出帧,否则,需要用 hwdownload 进行转换。

更多内容可以参考 FFmpeg 官网

2.11.4. Mpp

  • Ubunut 系统下, mpp 相关dev包都已经安装到系统中。

    更多相关资料,可参考 linux-sdk/docs/Linux/Multimedia 下的相关文档。

2.12. OpenGL-ES

RK3568/RK3566/RK3399/RK3288 支持 OpenGL ES1.1/2.0/3.0/3.1。

Firefly Ubuntu 已经提供了完整的 OpenGL-ES 支持。

  • 测试命令

$ sudo test_glmark2_normal.sh
  • webGL 支持

在 Chromium 浏览器中, 在地址栏输入:chrome://gpu 可以查看 chromium 下硬件加速的支持。

注意:

  1. EGL 是用arm 平台上 OpenGL 针对 x window system 的扩展,功能等效于 x86 下的 glx 库。

  2. 由于 Xorg 使用的 Driver modesettings 默认会加载 libglx.so (禁用 glx 会导致某些通过检测 glx 环境的应用启动失败),libglx.so 会搜索系统中的 dri 实现库。但是 RK3568/RK3566/RK3399/RK3288 Xorg 2D 加速是直接基于 DRM 实现, 并未实现 dri 库,所以启动过程中,libglx.so 会报告如下的错误。

    (EE) AIGLX error: dlopen of /usr/lib/aarch64-linux-gnu/dri/rockchip_dri.so failed
    

    这个对系统运行没有任何影响,不需要处理。

  3. 基于同样的道理,某些应用启动过程中,也会报告如下错误,不用处理,对应用的运行不会造成影响。

    libGL error: unable to load driver: rockchip_dri.so
    libGL error: driver pointer missing
    libGL error: failed to load driver: rockchip
    
  4. Firefly 之前发布的某些版本的 Ubuntu 软件,默认关闭了加载 libglx.so,在某些情况下,运行某些应用程序会出现下述错误:

    GdkGLExt-WARNING **: Window system doesn't support OpenGL.

    修正的方法如下:

    删除 /etc/X11/xorg.conf.d/20-modesetting.conf 中一下三行配置。

    Section "Module"
         Disable     "glx"
    EndSection
    

2.13. OpenCL

Firefly Ubuntu 已经添加了 opencl1.2 支持,可以运行系统内置的 clinfo 获取平台 opencl 相关参数。

firefly@firefly:~$ clinfo
Platform #0
 Name:                                  ARM Platform
 Version:                               OpenCL 1.2 v1.r14p0-01rel0-git(966ed26).f44c85cb3d2ceb87e8be88e7592755c3

 Device #0
   Name:                                Mali-T860
   Type:                                GPU
   Version:                             OpenCL 1.2 v1.r14p0-01rel0-git(966ed26).f44c85cb3d2ceb87e8be88e7592755c3
   Global memory size:                  1 GB 935 MB 460 kB
   Local memory size:                   32 kB
   Max work group size:                 256
   Max work item sizes:                 (256, 256, 256)
…

2.14. 使用root登录系统界面

  • autologin-user=root

root@firefly:~# cat /etc/lightdm/lightdm.conf.d/20-autologin.conf
[Seat:*]
user-session=Lubuntu
autologin-user=root

2.15. HDMI_IN 图像抓取

这项功能仅仅能够在AIO-3399J板子上使用

  • 需要焊接 HDMI_IN 输入接口

手动编译需要注意:

测试脚本 test_hdmiin-3399_new.sh

#!/bin/bash

export DISPLAY=:0
export XAUTHORITY=/home/firefly/.Xauthority
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
export LD_LIBRARY_PATH=/usr/lib/gstreamer-1.0

WIDTH=1920
HEIGHT=1080
SINK=kmssink
#SINK=gtksink

echo autospawn = no > /home/firefly/.config/pulse/client.conf
pkill pulseaudio
sleep 1
amixer -c 1 sset 'IN1 Boost' 0
amixer -c 1 sset "RECMIXL BST1" on
amixer -c 1 sset "RECMIXR BST1" on
amixer -c 1 sset 'Mono ADC MIXR ADC1' on
amixer -c 1 sset 'Mono ADC MIXL ADC1' on

gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-raw,format=NV12,width=${WIDTH},height=${HEIGHT}, framerate=30/1 ! videoconvert ! $SINK & # &>/dev/null &

GST_PID=$!

sleep 2
alsaloop -P hw:1,0 -C hw:1,0 -c 2 -t 500000 &
ALSA_PID=$!

trap '{ kill -9 $GST_PID; kill -9 $ALSA_PID; }' EXIT INT TERM

wait

2.16. TensorFlow Lite

RK3399 支持神经网络的 GPU 加速方案 LinuxNN, Firefly Ubuntu 已经添加了 LinuxNN 的支持。

opt/tensorflowbin/ 下,运行 test.sh, 即可测试 MobileNet 模型图像分类器的 Demo 和 MobileNet-SSD 模型的目标检测 Demo:

firefly@firefly:/opt/tensorflowbin$ ./test.sh
Loaded model mobilenet_ssd.tflite
resolved reporter
nn version: 1.0.0
findAvailableDevices
filename:libarmnn-driver.so     d_info:40432     d_reclen:40s
[D][ArmnnDriver]: Register Service: armnn (version: 1.0.0)!
first invoked time: 1919.17 ms
invoked
average time: 108.4 ms
validCount: 26
car     @ (546, 501) (661, 586)
car     @ (1, 549) (51, 618)
person  @ (56, 501) (239, 854)
person  @ (332, 530) (368, 627)
person  @ (391, 541) (434, 652)
person  @ (418, 477) (538, 767)
person  @ (456, 487) (602, 764)
car     @ (589, 523) (858, 687)
person  @ (826, 463) (1034, 873)
bicycle @ (698, 644) (1128, 925)
write out.jpg succ!

平台限制:目前只有3399、3399PRO支持。

2.17. 屏幕键盘

官方的 Ubuntu 系统中自带屏幕键盘,可以在菜单栏中点击打开: _images/onboard.jpg

2.18. 声音配置

设备一般都有 2 个或以上的音频设备。常见的是耳机和 HDMI 这两个设备的音频输出。下面是音频设置的例子,供用户参考。

2.18.1. 从命令行指定音频设备

系统自带的音频文件在 /usr/share/sound/alsa/ 目录中,播放前请先查看声卡设备:

root@firefly:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: rockchiphdmi [rockchip,hdmi], device 0: fe400000.i2s-i2s-hifi i2s-hifi-0 [fe400000.i2s-i2s-hifi i2s-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: rockchiprk809co [rockchip,rk809-codec], device 0: fe410000.i2s-rk817-hifi rk817-hifi-0 [fe410000.i2s-rk817-hifi rk817-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

然后指定声卡播放音频,其中声卡 card1 的设备 0 对应的是耳机口,card0 的设备 0 对应的是 HDMI。一般播放音频命令是 aplay -Dhw:0,0 Fornt_Center.wav,但系统自带的音频文件是单声道的,所以为了防止播放失败,可以按照下面的命令进行播放:

#选择耳机口输出音频文件
root@firefly:/usr/share/sounds/alsa# aplay -Dplughw:1,0 Front_Center.wav
Playing WAVE 'Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono

#选择 HDMI 输出音频文件
root@firefly:/usr/share/sounds/alsa# aplay -Dplughw:0,0 Front_Center.wav
Playing WAVE 'Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono

2.18.2. 在图形界面中选择音频设备

在图形界面中,播放准备好的音频文件,然后点击声音图标,打开 Sound Setting,选择到 Configuration 。可以看到两个声卡设备,例如设置为 HDMI 输出音频,则把 HDMI 的声卡设备选择为 Output,另一个声卡设置为 Off。(如果 HDMI 无声或者声音小,可以试试按 HDMI 屏上的物理按键调高音量)

_images/sound_setting.jpg

2.19. 创建WIFI热点

硬件要求:

  • 需要有无线网卡,且支持移动热点功能

点击桌面右上角Ethernet Network图标,选择Edit Connection... _images/Hostspot1.png

选择+图标,Add a new connection _images/Hostspot2.png

选择Wi-Fi,后点击Create _images/Hostspot3.png

Wi-Fi设置:

  • 设置SSID

  • Mode:选择Hotspot

  • Device: 选择无线网卡(wlan) _images/Hostspot4.png

选择适当的加密方式: _images/Hostspot5.png

点击Save即刻完成热点创建

2.20. 设置静态IP (使用netplan)

使用netplan设置静态IP

  • addresses

  • gateway4:设置网关

  • nameservers: DNS nameservers

  • ethernets: 以太网配置项

  • wifis: wifi配置项

root@firefly:~# vim /etc/netplan/netplan.yaml
root@firefly:~# netplan apply

netplan的内容如下:

network:
    ethernets:
        eth0:
            addresses: [168.168.4.3/24]
            gateway4: 168.168.0.1
            dhcp4: yes
            optional: true
    wifis:
        wlan0:
            addresses: [168.168.4.23/24]
            gateway4: 168.168.0.1
            dhcp4: yes
            dhcp6: no
            access-points:
            "ssid":
                password: "password"
    version: 2

or

network:
    ethernets:
        eth0:
            addresses: [168.168.4.3/24]
            gateway4: 168.168.0.1
            dhcp4: no
            optional: true
            nameservers:
              addresses: [202.96.128.166]
    wifis:
        wlan0:
            addresses: [168.168.4.23/24]
            gateway4: 168.168.0.1
            dhcp4: no
            dhcp6: no
            access-points:
            "ssid":
                password: "password"
    version: 2

netplan更多配置示例:https://netplan.io/examples

2.21. 串口

设备上的串口分两种,一种是普通串口,另外一种是通过转换芯片把SPI转换而成的串口。转换而成的串口和普通串口功能完全一致但是需要注意它们的设备文件名是不一样的。下面是两者的区别:

# 普通串口
root@firefly:~# ls /dev/ttyS*
ttyS0  ttyS1  ttyS2  ttyS3

# SPI转串口
root@firefly:~# ls /dev/ttysWK*
ttysWK0  ttysWK1  ttysWK2  ttysWK3

2.21.1. 设置波特率

ttyS4 为例,查看串口波特率命令:

root@firefly:~# stty -F /dev/ttyS4
speed 9600 baud; line = 0;
-brkint -imaxbel

设置波特率命令:

# 设置波特率为 115200
root@firefly:~# stty -F /dev/ttyS4 ospeed 115200 ispeed 115200 cs8

# 查看确认是否已经修改
root@firefly:~# stty -F /dev/ttyS4
speed 115200 baud; line = 0;
-brkint -imaxbel
root@firefly:~#

2.21.2. 关闭回显

在做环回收发测试的时候回显功能会影响到我们的测试结果,所以在环回测试或者其他特殊情况下需要关闭回显。以下是关闭回显的命令:

# 关闭回显示
root@firefly:~# stty -F /dev/ttyS4 -echo -echoe -echok

# 查看所有功能的配置,检查是否已经关闭。“-” 号代表该功能已经关闭
root@firefly:~# stty -F /dev/ttyS4 -a | grep echo
isig icanon iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -flusho -extproc

2.21.3. 发送接收原始数据

在实际应用中实际发送数据和我们希望发送的数据可能存在差别,例如多了回车或者其他特殊字符。利用 stty 可以把发送接收设置成 raw 模式确保发送接收的是原始数据,以下是设置命令:

root@firefly:~# stty -F /dev/ttyS4 raw

2.21.4. 工作模式

串口有 2 种工作模式分别是中断模式和 DMA 模式。

2.21.4.1. 中断模式

内核默认把串口配置成中断模式所以不需要做任何修改。中断模式下传输速率比较快但是在传大量数据的时候很容易丢包或者出错,所以当数据量比较大的时候请不要使用中断模式。

2.21.4.2. DMA 模式

DMA 模式主要是传输大量数据的时候使用。内核会为串口提供一个缓存空间接收数据来尽量降低串口传输的丢包率。

注意: 缓存空间限默认大小为 8K 如果一次传输超过缓存大小就会丢包,所以使用 DMA 模式的话需要发送端需要分包发送。

设备树文件配置

&uart4 {
        status = "okay";
+       dmas = <&dmac_peri 8>, <&dmac_peri 9>;
+       dma-names = "tx", "rx";
};

DMA 模式并不能提高传输速率,相反因为需要缓存,传输速率会有所下降,所以如果不是需要传输大量数据的话不要使用 DMA 模式。

2.21.5. 流控

不管是中断模式还有 DMA 模式都无法保证数据传输万无一失,因为长时间传输大量数据的时候 DDR、CPU 变频或者占用率过高都可能导致上层处理数据不及时导致丢包,这个时候就需要是用流控了。流控分两种,一种是软件流控另一种为硬件流控,下面只介绍硬件流控的使用。

2.21.5.1. 硬件支持

硬件流控需要有硬件支持,设备的串口 CTXRTX 脚需要和远端设备相连。

注意: 设备不是所有串口都支持硬件流控,请先从原理图上确认硬件是否支持。

2.21.5.2. 设备树文件配置

  • RK3568:

uart3: serial@ff1b0000 {
        compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart";
        reg = <0x0 0xff1b0000 0x0 0x100>;
        clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
        clock-names = "baudclk", "apb_pclk";
        interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH 0>;
        reg-shift = <2>;
        reg-io-width = <4>;
        pinctrl-names = "default";
+       pinctrl-0 = <&uart3_xfer &uart3_cts &uart3_rts>;
        status = "disabled";
};
  • RK3399:

uart3: serial@ff1b0000 {
        compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
        reg = <0x0 0xff1b0000 0x0 0x100>;
        clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
        clock-names = "baudclk", "apb_pclk";
        interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH 0>;
        reg-shift = <2>;
        reg-io-width = <4>;
        pinctrl-names = "default";
+       pinctrl-0 = <&uart3_xfer &uart3_cts &uart3_rts>;
        status = "disabled";
};
  • RK3288:

uart4: serial@ff1c0000 {
        compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart";
        reg = <0x0 0xff1c0000 0x0 0x100>;
        interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
        reg-shift = <2>;
        reg-io-width = <4>;
        clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
        clock-names = "baudclk", "apb_pclk";
        pinctrl-names = "default";
-       pinctrl-0 = <&uart4_xfer>;
+       pinctrl-0 = <&uart4_xfer &uart4_cts &uart4_rts>;
        status = "disabled";
};

2.21.5.3. 应用层设置

上层也需要打开流控的设置,这里介绍 stty 如何打开流控,如果你使用的是其他应用程序请从应用中打开流控。

# 打开流控
root@firefly:~# stty -F /dev/ttyS4 crtscts

# 检测流控是否打开,“-” 号代表该功能已经关闭
root@firefly:~# stty -F /dev/ttyS4 -a | grep crtscts
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal crtscts

2.22. MIPI 摄像头

以rk3399使用 MIPI 摄像头为例,带有 MIPI CSI 接口的 RK3399 板子都添加了双 MIPI 摄像头 OV13850 的支持,应用中也添加了摄像头的例子。下面介绍一下相关配置。

2.22.1. 设备树文件配置

rk3399-firefly-aiojd4.dts 为例,这些都是摄像头需要打开的配置。由于内核已经添加了双 MIPI 摄像头的支持,所以这里配置了两个摄像头,如果只使用一个摄像只需要打开其中一个摄像头就可以了。

//电源管理
&vcc_mipi {
        status = "okay";
};

&dvdd_1v2 {
        status = "okay";
};

//MIPI 摄像头1
&ov13850 {
        status = "okay";
};
&rkisp1_0 {
        status = "okay";
};

&mipi_dphy_rx0 {
        status = "okay";
};

&isp0_mmu {
        status = "okay";
};
//MIPI 摄像头2
&ov13850_1 {
        status = "okay";
};
&rkisp1_1 {
        status = "okay";
};
&mipi_dphy_tx1rx1 {
        status = "okay";
};

&isp1_mmu {
        status = "okay";
};

注意: 如果使用的是 core-3399 核心板加上 DIY 底板,可能需要修改相应的 GPIO 属性。

2.22.2. 调试

在运行脚本之前先确认一下 OV13850 设备是否注册成功,下面是成功的内核日志:

root@firefly:~# dmesg | grep ov13850
//MIPI 摄像头1
[    1.276762] ov13850 1-0036: GPIO lookup for consumer reset
[    1.276771] ov13850 1-0036: using device tree for GPIO lookup
[    1.276803] of_get_named_gpiod_flags: parsed 'reset-gpios' property of node '/i2c@ff110000/ov13850@36[0]' - status (0)
[    1.276855] ov13850 1-0036: Looking up avdd-supply from device tree
[    1.277034] ov13850 1-0036: Looking up dovdd-supply from device tree
[    1.277170] ov13850 1-0036: Looking up dvdd-supply from device tree
[    1.277535] ov13850 1-0036: GPIO lookup for consumer pwdn
[    1.277544] ov13850 1-0036: using device tree for GPIO lookup
[    1.277575] of_get_named_gpiod_flags: parsed 'pwdn-gpios' property of node '/i2c@ff110000/ov13850@36[0]' - status (0)
[    1.281862] ov13850 1-0036: Detected OV00d850 sensor, REVISION 0xb2
//MIPI 摄像头2
[    1.284442] ov13850 1-0046: GPIO lookup for consumer pwdn
[    1.284461] ov13850 1-0046: using device tree for GPIO lookup
[    1.284523] of_get_named_gpiod_flags: parsed 'pwdn-gpios' property of node '/i2c@ff110000/ov13850@46[0]' - status (0)
[    1.288235] ov13850 1-0046: Detected OV00d850 sensor, REVISION 0xb2

/dev 下应该生成相关设备文件:

root@firefly:~# ls /dev/video
//MIPI 摄像头1
video0  video1  video2  video3
//MIPI 摄像头2
video4  video5  video6  video7

注意: 同理,如果只使用一个摄像头,只需要注册一个摄像头设备就可以了。

2.22.3. 测试预览摄像头

2.22.3.1. v4l2

使用v4l2方式预览摄像头:

apt-get install -y git libopencv-dev cmake libdrm-dev g++ librga-dev

git clone https://github.com/T-Firefly/rkisp-v4l2.git

cd rkisp-v4l2/rkisp_demo/
cmake ./
make

sudo -u firefly DISPLAY=:0 ./rkisp_demo -c 300 -d /dev/video0 -w 640 -h 480
or
sudo -u firefly DISPLAY=:0 ./rkisp_demo -c 300 -d /dev/video5 -w 640 -h 480

2.22.3.2. gstreamer

使用gstreamer方式预览摄像头:

gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-raw,format=NV12,width=640,height=480, framerate=30/1 ! videoconvert ! kmssink &

运行脚本即可,结果如图所示:

_images/mipi_csi.jpg

2.22.4. 开发MIPI 摄像头

2.22.4.1. FFMPEG读取MIPI摄像头

  • 使用v4l2loopback和FFMPEG多路投影

apt-get install -y git libopencv-dev cmake libdrm-dev g++ librga-dev python-dev

git clone https://github.com/umlaeute/v4l2loopback.git

cd v4l2loopback/

#参考 《安装linux-headers和linux-image》
make install
...

//使用v4l2loopback创建 video10、video11和video12设备
sudo insmod v4l2loopback.ko videonr=10,11,12

#打开读取video0设备,并把图像信息写入到video10中
sudo -u firefly DISPLAY=:0  ./rkisp_demo -c 300  -d /dev/video0 -w 640  -h 480 -D /dev/video10

// 使用ffmpeg拷贝功能将video10中的内容,拷贝到video11和video12设备中
ffmpeg -loglevel quiet -f v4l2 -video_size 640x480 -r 10 -i /dev/video10 -preset fast -codec copy -f v4l2 /dev/video11 -preset fast -codec copy -f v4l2 /dev/video12

// 另起一个终端,使用ffplay工具任意预览video11或video12
ffplay -i /dev/video11

2.22.4.2. OpenCV读取MIPI摄像头

MIPI摄像头是不支持OpenCV中 capture.open(index) 方式读取的,在此提供2中读取摄像头的方法:

这种方式推荐OpenCV的C++版本使用,详细使用参考前面的v4l2预览一节。v4l2_simple_demo是rkisp_demo.cpp的精简版本,详细可参考rkisp_demo.cpp。

  • C++

    推荐OpenCV的C++版本使用,详细使用参考前面的v4l2预览一节。v4l2_simple_demo是rkisp_demo.cpp的精简版本,详细可参考rkisp_demo.cpp。

      ```
      参考:
      https://github.com/T-Firefly/rkisp-v4l2.git
    
      git clone https://github.com/T-Firefly/rkisp-v4l2.git
      cd rkisp-v4l2/mipi_video_demo/v4l2_simple_demo
      make
      # open /dev/video0
      sudo -u firefly DISPLAY=:0 ./opencv
      ```
    
  • Python

    使用 OpenCV-Python 方式读取 MIPI 摄像头需要添加Gstreamer支持,并需要重现编译安装OpenCV。参考《Opencv 编译和安装》

    git clone https://gitlab.com/firefly-linux/test_code/rkisp-v4l2.git
    cd mipi_video_demo/OpenCV_Python
    # Please read rkisp-v4l2/mipi_video_demo/OpenCV_Python/README.md carefully.
    python3 opencv_gst_test.py