如何在linux下,实现ov5640之类的cmos摄像头的驱动?

使用5.1系统的kernel,rk3288-reload开发板,在linux下开发

使用内核自带的摄像头驱动,写了一个测试程序,但是把申请的缓冲区放入队列时失败了,查找了原因,是在:

  1. for (i = 0; i < NB_BUFFER; i++) {
  2.  memset(&tV4l2Buf, 0, sizeof(struct v4l2_buffer));
    
  3.  tV4l2Buf.index = i;
    
  4.  tV4l2Buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    
  5.  tV4l2Buf.memory = V4L2_MEMORY_MMAP;
    
  6.  tV4l2Buf.flags = 0;
    
  7.  iRet = ioctl(v4l2_fd, VIDIOC_QUERYBUF, &tV4l2Buf);
    
  8.  if (iRet < 0) {
    
  9.      DWrite("Unable to query buffer.\n");
    
  10.     goto end;
    
  11. }
    
  12. printf("length: 0x%x offset: 0x%x\n", tV4l2Buf.length, tV4l2Buf.m.offset);
    
  13. pucVideoBuf[i] = (unsigned char *)mmap(0, /* start anywhere */
    
  14.           tV4l2Buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, v4l2_fd,
    
  15.           tV4l2Buf.m.offset);
    
  16. if (pucVideoBuf[i] == MAP_FAILED) {
    
  17.     DWrite("Unable to map buffer\n");
    
  18.     goto end;
    
  19. }
    
  20. printf("length: 0x%x offset: 0x%x\n", tV4l2Buf.length, tV4l2Buf.m.offset);
    
  21. 打印出来的结果是:
  22. length: 0xeb000 offset: 0x0
  23. length: 0xeb000 offset: 0xeb000
  24. length: 0xeb000 offset: 0x1d6000
  25. length: 0xeb000 offset: 0x2c1000
    随后通过映射的地址加入缓冲队列 调用
    ioctl(v4l2_fd, VIDIOC_QBUF, &tV4l2Buf);
    返回-1失败提示通过 fprintf(stderr, “%s error %d, %s\n”, s, errno, strerror(errno));
    打印 error 22, Invalid argument”

问题解决了吗