SOLVED VEYE imx385 驱动问题+
-
@veye_xumm 我也得觉得不对,IMX385 veye系列的最新的驱动是哪个,是1.7下的吗
-
@flaty 驱动源码你直接用github最新的就行。
-
@veye_xumm 编译错误 我把信息发给您看一下,是驱动里面的结构体
CC drivers/media/i2c/veyecam2m.o
drivers/media/i2c/veyecam2m.c: In function 'veyecam2m_g_mbus_config':
drivers/media/i2c/veyecam2m.c:419:24: error: 'V4L2_MBUS_CSI2' undeclared (first use in this function); did you mean 'V4L2_MBUS_CSI1'?
419 | config->type = V4L2_MBUS_CSI2;
| ^~~~~~~~~~~~~~
| V4L2_MBUS_CSI1
drivers/media/i2c/veyecam2m.c:419:24: note: each undeclared identifier is reported only once for each function it appears in
drivers/media/i2c/veyecam2m.c: At top level:
drivers/media/i2c/veyecam2m.c:898:3: error: 'const struct v4l2_subdev_video_ops' has no member named 'g_mbus_config'
898 | .g_mbus_config = veyecam2m_g_mbus_config,
| ^~~~~~~~~~~~~
drivers/media/i2c/veyecam2m.c:898:19: error: initialization of 'int (*)(struct v4l2_subdev *, struct v4l2_subdev_frame_interval )' from incompatible pointer type 'int ()(struct v4l2_subdev *, struct v4l2_mbus_config *)' [-Werror=incompatible-pointer-types]
898 | .g_mbus_config = veyecam2m_g_mbus_config,
| ^~~~~~~~~~~~~~~~~~~~~~~
drivers/media/i2c/veyecam2m.c:898:19: note: (near initialization for 'veyecam2m_video_ops.s_frame_interval')
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:273:drivers/media/i2c/veyecam2m.o] 错误 1一下是内核配置
============Start building kernel============
TARGET_ARCH =arm64
TARGET_KERNEL_CONFIG =rockchip_linux_defconfig
TARGET_KERNEL_DTS =roc-rk3588s-pc-mipi101-BSD1218-A101KL68
TARGET_KERNEL_CONFIG_FRAGMENT =rk3588_linux.config firefly-linux.config -
[0_1756784079945_log.zip](正在上传 100%) 这个是完整的编译log,您看一下,我使用firefly最新的SDK 进行的编译,采用5.10的内核
-
@flaty
参见代码的注释,你的内核缺少这个接口,需要注掉这个函数。
-
@veye_xumm 您这边 适配过 SDK1.4.0G 这个版本吗 firefly
-
@flaty 可以的。
-
-
@flaty 就是这个。
-
@veye_xumm zhge dsi的头您看 有问题吗 检测不到相机,
#include "roc-rk3588s-pc.dtsi"//#include "rk3588-roc-pc-cam-8ms1m.dtsi"
//open this line to enable fpdlink-III link
//#include "rk3588-roc-pc-fpdlink-90ub954.dtsi"//open this line to enable v-by-one hs link
#include "rk3588-roc-pc-vbyone-overlay.dtsi"#include "rk3588-roc-pc-cam-veyecam2m.dtsi"
#include "rk3588-roc-pc-cam-veyemvcam.dtsi"#include "roc-rk3588s-pc-v10-diff.dtsi"
#define WHICHDSI 0 /* dsi0 = 0,dsi1 = 1*/ -
-
@veye_xumm 我再试一下吧,不知道咋回事,,,编译什么都没问题
-
@veye_xumm
[ 7.047946] veyecam2m 7-003b: veye camera driver version: 00.01.01
[ 7.047980] veyecam2m 7-003b: Failed to get power-gpios, maybe no use
[ 7.048101] veyecam2m 7-003b: supply avdd not found, using dummy regulator
[ 7.048213] veyecam2m 7-003b: supply dovdd not found, using dummy regulator
[ 7.048278] veyecam2m 7-003b: supply dvdd not found, using dummy regulator
[ 7.048303] veyecam2m 7-003b: could not get default pinstate
[ 7.048309] veyecam2m 7-003b: could not get sleep pinstate
[ 7.048320] veyecam2m 7-003b: Success to get veyecam2m endpoint data lanes, dts uses 2 lanes
[ 7.170539] veyecam2m 7-003b: camera id is veyecam2m
[ 7.173503] veyecam2m 7-003b: sensor is IMX385
[ 7.173564] veyecam2m 7-003b: board type is ONE board
[ 7.219705] rockchip-csi2-dphy csi2-dphy0: dphy0 matches m00_b_veyecam2m 7-003b:bus type 5
以上电源的错误,但是ls /dev/video0 可以看到设备了 -
@flaty 这些报错都不用管。 我们的模组不需要这些供电。
-
@veye_xumm 测试 出图像了,搞定了 ,谢谢
-
@flaty 不客气。
-
@veye_xumm 现在遇到个新的问题,我不知道是板子硬件支持,我是用DMABUF 作为V4L2的qbuf, 但是返回错误 Failed to queue buffer: Invalid argument,您看一下我这部分代码,是不是该驱动支持,
//将缓冲区注册到摄像头
struct v4l2_buffer buf={0};
struct v4l2_plane planes[1]={0};
buf.index =0;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
buf.memory = V4L2_MEMORY_DMABUF;
buf.length = 1;
buf.m.planes = planes;
planes[0].m.fd = frame_buffers[i].dmabuf_fd;
planes[0].length =buffer_size;if (ioctl(cam_fd, VIDIOC_QBUF, &buf) < 0) { perror("Failed to queue buffer"); return -1; }
-
@flaty 建议您参考一下yavta的源码。git clone https://github.com/veyeimaging/yavta.git
-
@veye_xumm 我看了 那个源码 内存采用 普通的内存,我希望的是用 drm 或dmaheap 的,这样可以实现零copy
-
@flaty 我的理解中,相机驱动并不涉及到BUFF模式的限制。实际上数据的收取和防止到内存是rk的mipi接收单元的驱动所决定的。
下面是网上插到的信息,希望能有帮助。从你贴的代码来看,报错
Failed to queue buffer: Invalid argument
(EINVAL)通常意味着结构体成员设置有问题,或者驱动不支持 DMABUF 模式。结合你写的代码,我帮你逐条排查一下:
1.
v4l2_buffer
初始化问题你这里写的是:
struct v4l2_buffer buf={0}; struct v4l2_plane planes[1]={0};
这是对的,但要注意
buf.length
必须和planes
数组元素数量一致,并且buf.m.planes
不能为空。
2.
buf
关键字段设置你代码里:
buf.index = 0; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; buf.memory = V4L2_MEMORY_DMABUF; buf.length = 1; buf.m.planes = planes;
buf.type
用V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
是对的(说明驱动是 multiplanar 类型)。buf.memory
设置成DMABUF
正确。buf.index
不是 0 就行,它必须是你在VIDIOC_REQBUFS
时分配的 buffer 数量里的一个合法索引。比如如果你req.count = 4
,那么只能用0..3
。
3. plane 字段设置
planes[0].m.fd = frame_buffers[i].dmabuf_fd; planes[0].length = buffer_size;
问题可能出在这里:
planes[0].m.fd
:必须是dma-buf
的有效fd
。planes[0].length
:应该是该 plane 的大小,但 通常驱动并不依赖这个值。有些驱动要求设置bytesused
,即:
planes[0].bytesused = buffer_size;
如果
bytesused
没设,驱动可能直接返回EINVAL
。
4. 建议的正确写法
试着改成这样:
struct v4l2_buffer buf; struct v4l2_plane planes[VIDEO_MAX_PLANES]; // 通常 >= 1 memset(&buf, 0, sizeof(buf)); memset(planes, 0, sizeof(planes)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; buf.memory = V4L2_MEMORY_DMABUF; buf.index = i; // 循环里的 buffer 索引 buf.length = 1; // plane 数量 buf.m.planes = planes; planes[0].m.fd = frame_buffers[i].dmabuf_fd; planes[0].length = buffer_size; // plane 总大小 planes[0].bytesused = buffer_size; // 必须加上
5. 确认驱动是否支持 DMABUF
不是所有 V4L2 驱动都支持
V4L2_MEMORY_DMABUF
。你可以用下面的方法确认:v4l2-ctl -d /dev/video0 --querycap
如果
ioctl
里不支持DMABUF
,就算代码写对了也会EINVAL
。
有些驱动只支持MMAP
,那就得用V4L2_MEMORY_MMAP
。
建议:先在
QBUF
前打印出buf
和planes[0]
的值,确认index
、fd
、bytesused
都合理。