[英]Setting ctrl with V4L2 on ov5640
我想通過以下方式使用 V4L2 中的ioctl
和VIDIOC_S_CTRL
來控制各種ov5640
相機參數:
#include <string>
#include <iostream>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <malloc.h>
#include <cstring>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#define IOCTL_TRIES 3
#define CLEAR(x) memset (&(x), 0, sizeof (x))
static int xioctl(int fd, int request, void *arg)
{
int r;
int tries = IOCTL_TRIES;
do {
r = ioctl(fd, request, arg);
} while (--tries > 0 && r == -1 && EINTR == errno);
return r;
}
bool v4l2_ctrl_set(int fd, uint32_t id, int val)
{
struct v4l2_control ctrl;
CLEAR(ctrl);
ctrl.id = id;
ctrl.value = val;
if (xioctl(fd, VIDIOC_S_CTRL, &ctrl) == -1) {
std::cout << "Failed to set ctrl with id "
<< id << " to value " << val
<< "\nerror (" << errno << "): " << strerror(errno) << std::endl;
return false;
}
return true;
}
int main()
{
int fd = open("/dev/video0", O_RDWR | O_NONBLOCK);
if (fd == -1) {
std::cout << "Failed to open the camera" << std::endl;
return -1;
}
v4l2_ctrl_set(fd, V4L2_CID_SATURATION, 100);
return 0;
}
不幸的是ioctl
失敗,我收到error (25): Inappropriate ioctl for device
。 我將Intrinsyc Open-Q 820 µSOM與linaro 4.14一起使用。 我已經設法在if (sensor->power_count == 0) {
(以防省電模式出現問題)之前在ov5640_s_ctrl 函數中向 ov5640 驅動程序文件添加一些調試打印並重新編譯內核。 我運行了代碼,但是通過dmesg
查看我的printk
消息沒有被打印出來,這意味着即使設置了回調也沒有調用ov5640_s_ctrl
:
static const struct v4l2_ctrl_ops ov5640_ctrl_ops = {
.g_volatile_ctrl = ov5640_g_volatile_ctrl,
.s_ctrl = ov5640_s_ctrl,
};
我使用 V4L2 錯了嗎? 我應該在設置控件之前啟用某些功能嗎? 這更加令人困惑,因為我設法使用 v4l2 從相機獲取圖像,但我無法設置/獲取任何控件。
在您提供的 ov5640.c 的內核源代碼中,驅動程序被分配了標志V4L2_SUBDEV_FL_HAS_DEVNODE
這意味着它可能提供一個子開發節點/dev/v4l-subdevX
。 根據內核文檔:
可以在 /dev 中創建名為 v4l-subdevX 的設備節點,以直接訪問子設備。 如果子設備支持直接用戶空間配置,則它必須在注冊前設置 V4L2_SUBDEV_FL_HAS_DEVNODE 標志。
因此,您可以嘗試直接從 v4l-subdevX 節點設置控件(如果存在)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.