VEYE摄像头调试

购买链接汇总:

参考资料汇总:

对于摄像机模块的参数配置方面,VEYE使用了DRA(直接寄存器访问)的方法,而不是将接口封装在v4l2驱动中,以便实现更好的灵活性和更直接的参数配置功能。官方提供对应的shell脚本来直接访问这些寄存器,在下文中的shell操作脚本即指的该官方脚本

注意,这些脚本在Windows上编写,在Linux上会导致格式错误,此时需要借助dos2unix工具转换下编码,否则运行这些脚本会报一些莫名其妙的错误:

1
2
sudo apt install dos2unix
dos2unix ./xxx.sh

jetson官方底板

参考链接:http://wiki.veye.cc/index.php/VEYE_CS_Camera_for_Jetson_TX2/zh

使用预编译固件

基本步骤:

  1. 通过jtop命令或者cat /etc/nv_tegra_release命令获取当前系统的L4T版本号

  2. 通过官方github仓库获取对应的kernel image(veye增加了对应相机的驱动,通过下面的wget可以获得kernel image,直接download github的master分支会少kernel image)和设备树文件

即:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 确定版本号
cat /etc/nv_tegra_release
# 获取bsp包
wget https://github.com/veyeimaging/nvidia_jetson_veye_bsp/releases/latest/download/nvidia_jetson_veye_bsp.tgz
tar -xzvf nvidia_jetson_veye_bsp.tgz
# 升级kernel image
cd kernel_image
tar -xzvf Image_l4t_r32.7.1_veyecam.tar.gz # 不带签名的内核
tar -xzvf Image_l4t_r32.7.1_veyecam_signed_4_xavier.tgz # 带签名的内核

sudo cp /boot/Image /boot/Image.backup
sudo cp /boot/Image.sig /boot/Image.sig.backup
sudo cp <对应版本号下的image文件夹下>/Image /boot/Image -f
sudo cp <path to your Image dir>/Image.sig /boot/Image.sig -f # 仅仅针对Jetson Xavier NX(该内核需要签名文件验证)
# 升级dtb
sudo cp <对应版本号下的dtb文件夹下>/<DTB file name> /boot/ -f # 记得备份
cp /boot/extlinux/extlinux.conf /boot/extlinux/extlinux.conf.back # 备份extlinux.conf文件
# 编辑 /boot/extlinux/extlinux.conf文件,新增如下内容:
FDT /boot/<DTB file name>

# 重启后即可生效
sudo reboot

检验是否成功:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 对于kernel:
ls /sys/bus/i2c/drivers/
dmesg | grep x307
# 对于dtb(DTB在不同的平台和不同的摄像头模组都会有所不同):
# - Nano A02/ Nano 2G
ls /proc/device-tree/host1x/i2c@546c0000/
# - Nano B01
ls /proc/device-tree/cam_i2cmux/i2c@*
# - TX2 Devkit
ls /proc/device-tree/i2c@3180000/tca9548@70/i2c@*
ls /proc/device-tree/i2c@3180000/tca9548@77/i2c@*
# - AGX Xavier
ls /proc/device-tree/i2c@3180000/tca9548@70/i2c@*
ls /proc/device-tree/i2c@3180000/tca9548@77/i2c@*
# - Xavier NX and TX2 NX(p3509-0000 carrier board)
ls /proc/device-tree/cam_i2cmux/i2c@*
# 检测i2c地址是否为0x3b
sudo i2cdetect -y 9
sudo i2cdetect -y 10

防止kernel和dtb被系统升级所覆盖(可选):

1
sudo apt-mark hold nvidia-l4t-kernel nvidia-l4t-kernel-dtbs

源代码

基本步骤:

  1. 下载kernel源码以及设置交叉编译工具链(可以参考JetsonNano摄像头驱动开发

  2. 配置开发环境

  3. 下载veye提供的bsp包

  4. 根据bsp包中的补丁对kernel进行修改并编译

  5. 编译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
# 以下步骤假设SDK安装目录为<TOPDIR>,源代码在$L4T_DIR/sources目录
export TOP_DIR=<源码的绝对路径,如/home/xumm/nvidia/nvidia_sdk/JetPack_4.5_Linux_JETSON_XAVIER_NX_DEVKIT/>
# 设置其他环境变量
export L4T_DIR=$TOP_DIR/Linux_for_Tegra
export LOCALVERSION=-tegra
export LDK_ROOTFS_DIR=$TOP_DIR/Linux_for_Tegra/rootfs
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
export CROSS32CC=arm-linux-gnueabihf-gcc
export TEGRA_KERNEL_OUT=$L4T_DIR/sources/kernel/out_kernel
export KERNEL_PATH=$L4T_DIR/sources/kernel/out_kernel
export NVIDIA_PATH=$L4T_DIR/sources/kernel/nvidia
export NANO_DTS_PATH=$L4T_DIR/sources/hardware/nvidia/platform/t210/
export TX2_DTS_PATH=$L4T_DIR/sources/hardware/nvidia/platform/t18x
export XAVIER_DTS_PATH=$L4T_DIR/sources/hardware/nvidia/platform/t19x

# 下载bsp包
cd $L4T_DIR
git clone https://github.com/veyeimaging/nvidia_jetson_veye_bsp.git
export RELEASE_PACK_DIR=$L4T_DIR/nvidia_jetson_veye_bsp

# patch kernel 源码
cp $RELEASE_PACK_DIR/drivers_source/cam_drv_src/* $NVIDIA_PATH/drivers/media/i2c/
cp $RELEASE_PACK_DIR/drivers_source/kernel_veyecam_config_<l4t_version> $L4T_DIR/sources/kernel/kernel-4.9/arch/arm64/configs/tegra_veyecam_defconfig
# 修改Kconfig和Makefile
cp $RELEASE_PACK_DIR/drivers_source/cam_drv_src/Kconfig_<ver> $NVIDIA_PATH/drivers/media/i2c/
cp $RELEASE_PACK_DIR/drivers_source/cam_drv_src/Makefile_<ver> $NVIDIA_PATH/drivers/media/i2c/

# 编译 kernel,最终生成的image文件在:$TEGRA_KERNEL_OUT/arch/arm64/boot/Image 中
cd $L4T_DIR/sources/kernel/kernel-4.9/
make ARCH=arm64 O=$TEGRA_KERNEL_OUT tegra_veyecam_defconfig
make ARCH=arm64 O=$TEGRA_KERNEL_OUT Image -j4
# 对于Xavier这种需要内核签名的:
cd $L4T_DIR
./l4t_sign_image.sh --file kernel/Image --chip 0x19

编译dts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 对于 jetson Nano
cp $RELEASE_PACK_DIR/Nano/JetPack_<ver>_Linux_JETSON_NANO_DEVKIT/dts\ dtb/common/t210/* -r $NANO_DTS_PATH/
cp $RELEASE_PACK_DIR/Nano/JetPack_<ver>_Linux_JETSON_NANO_DEVKIT/dts\ dtb/<camera model>/tegra210-porg-plugin-manager.dtsi -r $NANO_DTS_PATH/porg/kernel-dts/porg-plugin-manager
# 对于 jetson Xavier NX
cp $RELEASE_PACK_DIR/Xavier-NX/JetPack_<ver>_Linux_JETSON_XAVIER_NX_DEVKIT/dts\ dtb/common/t19x/* -r $XAVIER_DTS_PATH/
cp $RELEASE_PACK_DIR/Xavier-NX/JetPack_<ver>_Linux_JETSON_XAVIER_NX_DEVKIT/dts\ dtb/<camera model>/tegra194-p3509-0000-a00.dtsi $XAVIER_DTS_PATH/jakku/kernel-dts/common/

# 编译
cd $L4T_DIR/sources/kernel/kernel-4.9/
make ARCH=arm64 O=$TEGRA_KERNEL_OUT dtbs

# 编译完成后 拷贝出来
# jetson Nano
cp $TEGRA_KERNEL_OUT/arch/arm64/boot/dts/tegra210-p3448-0000-p3449-0000-a02.dtb $L4T_DIR/kernel/dtb/
cp $TEGRA_KERNEL_OUT/arch/arm64/boot/dts/tegra210-p3448-0000-p3449-0000-b00.dtb $L4T_DIR/kernel/dtb/
cp $TEGRA_KERNEL_OUT/arch/arm64/boot/dts/tegra210-p3448-0003-p3542-0000.dtb $L4T_DIR/kernel/dtb/
# jetson Xavier NX
cp $TEGRA_KERNEL_OUT/arch/arm64/boot/dts/tegra194-p3668-all-p3509-0000.dtb $L4T_DIR/kernel/dtb/

访问图像

kernel和设备树好了后,仍可以通过常用方式访问摄像头,如:

1
2
# 预览:
gst-launch-1.0 v4l2src device=/dev/video0 ! "video/x-raw,format=(string)UYVY, width=(int)1920, height=(int)1080" ! nvvidconv ! "video/x-raw(memory:NVMM),format=(string)I420" ! nvoverlaysink sync=false
  • 注意,如果使用官方默认驱动,使用gstreamer做应用层调用,每次gstreamer的调用都会覆盖i2c脚本配置好的帧率模式。

  • 官方提供的解决办法是修改官方提供的驱动源码,屏蔽修改帧率相关代码,详见 如何在英伟达Jetson平台使用灵活帧率模式

IMX307

wiki:http://wiki.veye.cc/index.php/CS-MIPI-IMX307_STARVIS_Module_index

shell操作脚本:cs_mipi_i2c.sh

支持三种分辨率(通过bash ./cs_mipi_i2c.sh -r -f videofmtcap可以查询,帧率和工频频率有关):

  • 1920*1080*30fps

  • 1280*720*60fps

  • 640*480*130fps

测试例子:

1
2
3
4
5
6
7
8
9
10
11
# 1080p 视频 在显示屏(只能通过hdmi口)上实时预览
gst-launch-1.0 nvv4l2camerasrc device=/dev/video0 ! "video/x-raw(memory:NVMM),format=(string)UYVY, width=(int)1920, height=(int)1080" ! nvvidconv ! "video/x-raw(memory:NVMM),format=(string)I420" ! nvoverlaysink sync=false
# 拍照并保存
gst-launch-1.0 v4l2src num-buffers=1 ! "video/x-raw,format=(string)UYVY, width=(int)1920, height=(int)1080" ! nvvidconv ! "video/x-raw(memory:NVMM),format=(string)I420" ! nvjpegenc ! filesink location=jpgname.jpg

# 脚本分辨率设置
./cs_mipi_i2c.sh -w -f videofmt -p1 1920 -p2 1080 -p4 30
./cs_mipi_i2c.sh -w -f videofmt -p1 1280 -p2 720 -p4 60
./cs_mipi_i2c.sh -w -f videofmt -p1 640 -p2 480 -p4 130
./cs_mipi_i2c.sh -w -f sysreboot -p1 1 # 重启摄像头模组上cpu程序
./cs_mipi_i2c.sh -w -f sysreboot -p1 2 # 完全重启摄像头模组(6-8秒)
  • 注意,默认分辨率为1920108030fps,如需切换,需要通过shell配置脚本手动修改

Python 采集demo:

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
import os
import time
import sys

# 默认保存目录
DEFAULT_SAVE_PATH = "./img"

DEFAULT_SET_SHELL_PATH = "/home/jetson/nvidia_jetson_veye_bsp/i2c_cmd/bin"

GST_STR = 'gst-launch-1.0 v4l2src num-buffers=1 ! "video/x-raw,format=(string)UYVY, width=(int)%d, height=(int)%d" ! nvvidconv ! "video/x-raw(memory:NVMM),format=(string)I420" ! nvjpegenc ! filesink location=%s'

if __name__ == "__main__":
save_path = DEFAULT_SAVE_PATH
if not os.path.exists(save_path):
os.mkdir(save_path)

camstr = 'imx307'
index = time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime())

resolution = [[1920, 1080, 30],
[1280, 720, 60],
[640, 480, 120]]

mode = 0
print(GST_STR%(resolution[mode][0], resolution[mode][1], f'{save_path}/{camstr}_mode{mode}_{index}.jpg'))
nowpath = os.getcwd()
os.chdir(DEFAULT_SET_SHELL_PATH)
os.system("bash cs_mipi_i2c.sh -w -f videofmt -p1 %d -p2 %d -p4 %d"%(resolution[mode][0], resolution[mode][1], resolution[mode][2]))
os.chdir(nowpath)
os.system(GST_STR%(resolution[mode][0], resolution[mode][1], f'{save_path}/{camstr}_mode{mode}_{index}.jpg'))

IMX335

wiki:http://wiki.veye.cc/index.php/VEYE-MIPI-IMX335_Starlight_Camera

shell操作脚本:veye5_mipi_i2c.sh

IMX385

wiki:http://wiki.veye.cc/index.php/VEYE-MIPI-IMX385_Starlight_Camera

shell操作脚本:veye_mipi_i2c.sh