Created
March 14, 2017 04:58
-
-
Save stanier/c71c0b2f7d29d52399b660eb1d0f869a to your computer and use it in GitHub Desktop.
IOCTL problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ioctl | |
import "golang.org/x/sys/unix" | |
const ( | |
typeBits = 8 | |
numberBits = 8 | |
sizeBits = 14 | |
directionBits = 2 | |
typeMask = (1 << typeBits) - 1 | |
numberMask = (1 << numberBits) - 1 | |
sizeMask = (1 << sizeBits) - 1 | |
directionMask = (1 << directionBits) - 1 | |
directionNone = 0 | |
directionWrite = 1 | |
directionRead = 2 | |
numberShift = 0 | |
typeShift = numberShift + numberBits | |
sizeShift = typeShift + typeBits | |
directionShift = sizeShift + sizeBits | |
) | |
func ioc(dir, t, nr, size uintptr) uintptr { | |
return (dir << directionShift) | (t << typeShift) | (nr << numberShift) | (size << sizeShift) | |
} | |
// Io used for a simple ioctl that sends nothing but the type and number, and receives back nothing but an (integer) retval. | |
func Io(t, nr uintptr) uintptr { | |
return ioc(directionNone, t, nr, 0) | |
} | |
// IoR used for an ioctl that reads data from the device driver. The driver will be allowed to return sizeof(data_type) bytes to the user. | |
func IoR(t, nr, size uintptr) uintptr { | |
return ioc(directionRead, t, nr, size) | |
} | |
// IoW used for an ioctl that writes data to the device driver. | |
func IoW(t, nr, size uintptr) uintptr { | |
return ioc(directionWrite, t, nr, size) | |
} | |
// IoRW a combination of IoR and IoW. That is, data is both written to the driver and then read back from the driver by the client. | |
func IoRW(t, nr, size uintptr) uintptr { | |
return ioc(directionRead|directionWrite, t, nr, size) | |
} | |
// Ioctl simplified ioct call | |
func Ioctl(fd, op, arg uintptr) error { | |
_, _, ep := unix.Syscall(unix.SYS_IOCTL, fd, op, arg) | |
if ep != 0 { | |
return ep | |
} | |
return nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"unsafe" | |
"./ioctl" | |
) | |
const ( | |
V4L2_CTRL_CLASS_USER uint32 = 0x980000 | |
V4L2_CID_BASE uint32 = (V4L2_CTRL_CLASS_USER | 0x900) | |
V4L2_CTRL_CLASS_CAMERA uint32 = 0x9a0000 | |
V4L2_CID_CAMERA_CLASS_BASE uint32 = (V4L2_CTRL_CLASS_CAMERA | 0x900) | |
V4L2_CID_CAMERA_CLASS uint32 = (V4L2_CTRL_CLASS_CAMERA | 1) | |
) | |
const ( | |
V4L2_CID_EXPOSURE uint32 = V4L2_CID_BASE + 17 | |
V4L2_CID_EXPOSURE_AUTO uint32 = V4L2_CID_CAMERA_CLASS_BASE + 1 | |
V4L2_CID_EXPOSURE_ABSOLUTE uint32 = V4L2_CID_CAMERA_CLASS_BASE + 2 | |
V4L2_CID_EXPOSURE_AUTO_PRIORITY uint32 = V4L2_CID_CAMERA_CLASS_BASE + 3 | |
) | |
const ( | |
V4L2_EXPOSURE_AUTO int32 = iota | |
V4L2_EXPOSURE_MANUAL int32 = iota | |
V4L2_EXPOSURE_SHUTTER_PRIORITY int32 = iota | |
V4L2_EXPOSURE_APERTURE_PRIORITY int32 = iota | |
) | |
var ( | |
VIDIOC_S_EXT_CTRLS = ioctl.IoRW(uintptr('V'), 72, unsafe.Sizeof(v4l2_ext_controls{})) | |
VIDIOC_S_CTRL = ioctl.IoRW(uintptr('V'), 28, unsafe.Sizeof(v4l2_control{})) | |
) | |
func setExposureA(fd uintptr, exposure_value *int32) error { | |
exposure := &v4l2_control{ | |
id: V4L2_CID_EXPOSURE, | |
value: *exposure_value, | |
} | |
err := ioctl.Ioctl(fd, VIDIOC_S_CTRL, uintptr(unsafe.Pointer(exposure))) | |
controls := &v4l2_ext_controls{ | |
ctrl_class: V4L2_CTRL_CLASS_CAMERA, | |
count: uint32(1), | |
//error_idx: 0, | |
reserved: [2]uint32{uint32(0), uint32(0)}, | |
controls: &[1]v4l2_ext_control{ | |
v4l2_ext_control{ | |
id: V4L2_CID_EXPOSURE_AUTO, | |
size: uint32(unsafe.Sizeof(uintptr(*exposure_value))), | |
reserved2: [1]uint32{0}, | |
value: *exposure_value, | |
}, | |
}, | |
} | |
err := ioctl.Ioctl(fd, VIDIOC_S_EXT_CTRLS, uintptr(unsafe.Pointer(controls))) | |
if err != nil { | |
return err | |
} | |
return nil | |
} | |
func setExposureB(fd uintptr, exposure_value *int32) error { | |
control := &v4l2_control{ | |
id: V4L2_CID_EXPOSURE, | |
value: *exposure_value, | |
} | |
err := ioctl.Ioctl(fd, VIDIOC_S_CTRL, uintptr(unsafe.Pointer(control))) | |
if err != nil { | |
return err | |
} | |
return nil | |
} | |
func main() { | |
if err = cam.SetExposure(0); err != nil { | |
panic(err.Error()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment