19. 摄像头

19.1. 使能设备树插件

想要使能OV5640摄像头需要打开camera的设备树插件。 如下所示:

/boot/uEnv.txt
1
dtoverlay=/usr/lib/linux-image-5.4.47-imx8mm/freescale/overlays/imx8mm-fire-cam.dtbo

19.2. v4l-utils工具使用

v4l-utils工具安装

1
 sudo apt install v4l-utils

查看可用的视频设备,其中/dev/video0对应OV5640的物理设备

1
2
3
4
5
6
 #执行命令
 v4l2-ctl --list-devices

 #显示信息如下
 i.MX6S_CSI (platform:32e20000.csi1_bridge):
     /dev/video0

查看摄像头所有参数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
 #执行命令
 sudo v4l2-ctl -d  /dev/video0 --all


 #显示信息如下
 Driver Info:
     Driver name      : mx6s-csi
     Card type        : i.MX6S_CSI
     Bus info         : platform:32e20000.csi1_bridge
     Driver version   : 5.4.47
     Capabilities     : 0x84200001
             Video Capture
             Streaming
             Extended Pix Format
             Device Capabilities
     Device Caps      : 0x04200001
             Video Capture
             Streaming
             Extended Pix Format
     Priority: 0
     Video input : 0 (Camera: ok)
     Format Video Capture:
             Width/Height      : 0/0
             Pixel Format      : ''
             Field             : Any
             Bytes per Line    : 0
             Size Image        : 0
             Colorspace        : Default
             Transfer Function : Default (maps to Rec. 709)
             YCbCr/HSV Encoding: Default (maps to ITU-R 601)
             Quantization      : Default (maps to Full Range)
             Flags             :
     Crop Capability Video Capture:
             Bounds      : Left 0, Top 0, Width 0, Height 0
             Default     : Left 0, Top 0, Width 0, Height 0
             Pixel Aspect: 1/1
     Crop: Left 0, Top 0, Width 0, Height 0
     Selection: crop, Left 0, Top 0, Width 0, Height 0, Flags:
     Selection: crop_default, Left 0, Top 0, Width 0, Height 0, Flags:
     Selection: crop_bounds, Left 0, Top 0, Width 0, Height 0, Flags:
     Selection: compose, Left 0, Top 0, Width 0, Height 0, Flags:
     Selection: compose_default, Left 0, Top 0, Width 0, Height 0, Flags:
     Selection: compose_bounds, Left 0, Top 0, Width 0, Height 0, Flags:
     Selection: compose_padded, Left 0, Top 0, Width 0, Height 0, Flags:
     Selection: native_size, Left 0, Top 0, Width 0, Height 0, Flags:
     Streaming Parameters Video Capture:
             Capabilities     : timeperframe
             Frames per second: 30.000 (30/1)
             Read buffers     : 0

查看摄像头所支持的分辨率

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
 #执行命令
 sudo v4l2-ctl --list-formats-ext -d /dev/video0

 #显示信息如下
 ioctl: VIDIOC_ENUM_FMT
     Type: Video Capture

     [0]: 'YUYV' (YUYV 4:2:2)
             Size: Discrete 640x480
                     Interval: Discrete 0.033s (30.000 fps)
             Size: Discrete 320x240
                     Interval: Discrete 0.033s (30.000 fps)
             Size: Discrete 720x480
                     Interval: Discrete 0.033s (30.000 fps)
             Size: Discrete 1280x720
                     Interval: Discrete 0.033s (30.000 fps)
             Size: Discrete 1920x1080
                     Interval: Discrete 0.033s (30.000 fps)
             Size: Discrete 2592x1944
                     Interval: Discrete 0.067s (15.000 fps)

19.3. 安装gstreamer

可以使用gstreamer对摄像头做个简单测试,安装命令如下

1
 sudo apt install libgstreamer1.0-0 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

19.3.1. 简单测试

使用以下命令可对摄像头进行录制视频、拍照或将摄像头的拍摄到的视频显示到显示屏上。

1
2
3
4
5
6
7
 #录制视频
 #录制的视屏可以用MobaXter软件通过ssh连接到开发板,将视屏下载到pc,用potplayer播放
 sudo gst-launch-1.0 -v v4l2src device=/dev/video0 ! "video/x-raw, format=(string)YUY2, width=(int)640,height=(int)480, framerate=(fraction)30/1" ! videoconvert ! avimux ! filesink location=webcam.avi


 #拍照 (拍照命令对使用OV5640摄像头有问题,建议使用 USB免驱摄像头 章节部分的用的摄像头)
 sudo gst-launch-1.0 v4l2src num-buffers=1 device=/dev/video0 ! jpegenc ! filesink location=picture.jpg

19.4. 摄像头设备树插件

野火IMX8M MINI提供了很多的设备树插件源码,若想要修改不同的引脚作为v5640摄像头的引脚, 可参考:

设备树插件为 imx8mm-fire-cam.dtbo ,源码如下所示

arch/arm64/boot/dts/freescale/overlays/imx8mm-fire-cam-overlay.dts
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
 /dts-v1/;
 /plugin/;

 #include "../imx8mm-pinfunc.h"
 #include "dt-bindings/gpio/gpio.h"
 #include "dt-bindings/clock/imx8mm-clock.h"
 / {
             fragment@0 {
                     target = <&csi1_bridge>;
                     __overlay__ {
                             fsl,mipi-mode;
                             status = "okay";
                             port {
                                     csi1_ep: endpoint {
                                             remote-endpoint = <&csi1_mipi_ep>;
                                     };
                             };
                     };
             };

             fragment@1 {
                     target = <&mipi_csi_1>;
                     __overlay__{
                             #address-cells = <1>;
                             #size-cells = <0>;
                             status = "okay";
                             port {
                                     /* must before mipi1_sensor_ep  */
                                     csi1_mipi_ep: endpoint@0 {
                                             remote-endpoint = <&csi1_ep>;
                                     };

                                     mipi1_sensor_ep: endpoint@1 {
                                             remote-endpoint = <&ov5640_mipi1_ep>;
                                             data-lanes = <2>;
                                             csis-hs-settle = <13>;
                                             csis-clk-settle = <2>;
                                             csis-wclk;
                                     };
                             };
                     };
             };

             fragment@2 {
                     target = <&i2c2>;
                     __overlay__{
                             clock-frequency = <400000>;
                             pinctrl-names = "default";
                             pinctrl-0 = <&pinctrl_i2c2>;
                             status = "okay";

                             #address-cells = <1>;
                             #size-cells = <0>;

                             ov5640_mipi: ov5640_mipi@3c {
                                     compatible = "ovti,ov5640_mipi";
                                     reg = <0x3c>;
                                     status = "okay";
                                     pinctrl-names = "default";
                                     pinctrl-0 = <&pinctrl_csi_pwn>, <&pinctrl_csi_rst>;
                                     clocks = <&clk IMX8MM_CLK_CLKO1>;
                                     clock-names = "csi_mclk";
                                     assigned-clocks = <&clk IMX8MM_CLK_CLKO1>;
                                     assigned-clock-parents = <&clk IMX8MM_CLK_24M>;
                                     assigned-clock-rates = <24000000>;
                                     csi_id = <0>;
                                     pwn-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
                                     rst-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
                                     mclk = <24000000>;
                                     mclk_source = <0>;
                                     port {
                                             ov5640_mipi1_ep: endpoint {
                                                     remote-endpoint = <&mipi1_sensor_ep>;
                                             };
                                     };
                             };
                     };
             };

             fragment@3 {
                     target= <&iomuxc>;
                     __overlay__{
                             pinctrl_i2c2: i2c2grp {
                                     fsl,pins = <
                                             MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL                  0x400001c3
                                             MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA                  0x400001c3
                                     >;
                             };

                             pinctrl_csi_pwn: csi_pwn_grp {
                                     fsl,pins = <
                                             MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7               0x19
                                     >;
                             };

                             pinctrl_csi_rst: csi_rst_grp {
                                     fsl,pins = <
                                             MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6               0x19
                                     >;
                             };
                     };
             };
     };

19.5. USB免驱摄像头

当插入UVC(全称USB Video Class)免驱摄像头时, 内核将会打印信息,使用lsusb再次查看lsusb设备时可发现多了一个新的USB设备。 同时在 /dev/ 目录下将多出新的video设备,其中 /dev/video2 则为USB摄像头设备, 不同板子的摄像头设备文件可能不同。

本实验使用的设备为USB免驱摄像头

注意得支持USB2.0的,可以先在PC上的ubuntu测试可以用再在板子上试。

1
2
3
4
5
6
7
8
9
 root@lubancat:~# lsusb
 Bus 001 Device 003: ID 05a3:9230 ARC International Camera
 Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
 Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

 root@lubancat:~#  ls -l /dev/video*
 crw-rw---- 1 root video 81, 0 2月  14  2019 /dev/video0
 crw-rw---- 1 root video 81, 1 2月  14  2019 /dev/video1
 crw-rw---- 1 root video 81, 2 2月  14  2019 /dev/video2

若提示找不到lsusb命令,可使用 sudo apt install usbutils 安装usbutils。

关于USB摄像头的相关操作与章节前面介绍的OV5640摄像头控制方式完全相同,请参照章节前面说明。