linux程序与相机驱动的通信
1、fcntl.ioctl()# 定义V4L2控制结构体classv4l2_control(Structure):_fields_[(id,c_uint32),(value,c_int32)]defset_camera_param(device_path,param_id,value):fdopen(device_path,rb,buffering0)ctrlv4l2_control()ctrl.idparam_id ctrl.valuevaluetry:fcntl.ioctl(fd,0xC008561C,ctrl)finally:fd.close()defget_camera_param(device_path,param_id):fdopen(device_path,rb,buffering0)ctrlv4l2_control()ctrl.idparam_idtry:fcntl.ioctl(fd,0xC008561B,ctrl)# 驱动把当前值填入 ctrl.valuereturnctrl.valuefinally:fd.close()fcntl 名字来自 file control可以理解为Python 用来调用 Linux“文件控制类系统调用”的模块。它不只是操作普通文件也能操作摄像头、串口、磁盘、网卡等设备因为在 Linux 中这些设备通常也被表示成“文件”。摄像头除了传输图像还有很多特殊操作这些操作不能简单表示成“读取一段数据”或“写入一段数据”。普通读写不够因此 Linux 提供了 ioctl I/O Control它允许程序告诉驱动我要执行某种特殊操作这是这次操作需要的参数。0xC008561C代表执行什么操作这里表示设置控制参数具体含义如下C 数据可以在程序和内核之间双向传输 008 参数结构体大小为8字节56V4L2 类型标识“V”的 ASCII 编码 1C 第28号操作即设置控制项关于结构体ctypes.Structure 的作用是让 Python 按照 C 语言结构体的内存格式排列数据。因为 Linux 内核驱动是用 C 写的它不认识 Python 字典或 Python 对象只认识固定格式的一段内存。所以不能直接这样传{id:123,value:10000}而是必须准备成驱动期待的二进制布局。ctrl 是一块可以被修改的内存在查询控制参数时工作流程是fcntl.ioctl() 把这块内存交给内核内核驱动将查询结果写回然后 Python 再读取2、V4L2defsend_v4l2_stop_command(device):try:cmdfv4l2-ctl -d{device}--set-ctrlstop1subprocess.run(cmd,shellTrue,checkTrue)logger.debug(命令执行成功)exceptsubprocess.CalledProcessErrorase:logger.error(f命令执行失败:{e})defsend_infra_integral_time_command(device,camera_identity):ifcamera_identityswir_fix:cmdfv4l2-ctl -d{device}--set-ctrlexposure{50}elifcamera_identitymwir_fix:cmdfv4l2-ctl -d{device}--set-ctrlexposure{60000}elifcamera_identitylwir_fix:cmdfv4l2-ctl -d{device}--set-ctrlexposure{1500}else:logger.warning(不存在的积分时间转换)return0try:subprocess.run(cmd,shellTrue,checkTrue)logger.debug(红外初始积分时间命令执行成功)exceptsubprocess.CalledProcessErrorase:logger.error(f红外初始积分时间命令执行失败:{e})defsend_v4l2_focus_absolute_command(device,camera_identity,value10000):ifcamera_identityvis_zoom:returnelifcamera_identityvis_fix:cmdfv4l2-ctl -d{device}--set-ctrlfocus_absolute{13500}elifcamera_identityswir_fix:cmdfv4l2-ctl -d{device}--set-ctrlfocus_absolute{13500}elifcamera_identitymwir_fix:cmdfv4l2-ctl -d{device}--set-ctrlfocus_absolute{13500}elifcamera_identitylwir_fix:cmdfv4l2-ctl -d{device}--set-ctrlfocus_absolute{16500}else:logger.warning(不存在的对焦绝对值转换)return0try:subprocess.run(cmd,shellTrue,checkTrue)logger.debug(对焦绝对值命令执行成功)exceptsubprocess.CalledProcessErrorase:logger.error(f对焦绝对值命令执行失败:{e})3、I2Cdefsend_v4l2_vis_command():try:cmdi2ctransfer -y -f 9 w50x28 0x00 0x64 0x01 0x00 0x00subprocess.run(cmd,shellTrue,checkTrue)logger.debug(可见变焦命令执行成功)exceptsubprocess.CalledProcessErrorase:logger.error(f可见变焦命令执行失败:{e})

相关新闻