# BSP內核的攝像頭使用
~~~
Device Drivers ->
<*> Multimedia support --->
<*> sunxi video encoder and decoder support //視頻編碼器,包括h264/mpeg4/mpeg2/vc1/rmvb. 以模塊形式編譯,cedar_ve.ko
~~~
~~~
[*] Video capture adapters --->
[*] V4L platform devices --->
~~~
~~~
--- V4L platform devices
< > Support for timberdale Video In/LogiWIN
<*> SoC camera support
< > imx074 support
< > mt9m001 support
< > mt9m111, mt9m112 and mt9m131 support
< > mt9t031 support
< > mt9t112 support
< > mt9v022 support
< > rj54n1cb0c support
< > tw9910 support
< > platform camera support
<M> ov2640 camera support
<M> ov5642 camera support
< > ov6650 sensor support
< > ov772x camera support
< > ov9640 camera support
< > ov9740 camera support
< > SuperH Mobile MIPI CSI-2 Interface driver
< > SuperH Mobile CEU Interface driver
<*> sunxi video front end (camera and etc)driver
<*> v4l2 driver for SUNXI
Sensor CSI --->
~~~
~~~
< > ov2710_mipi
< > ov4689
< > ov4689 60fps
< > ar0330 mipi
< > ov4689 sdv
< > gc1004_mipi
<M> h22_mipi
< > nt99231_mipi
~~~
查看編譯后的ko:
~~~
//觸摸屏
aw5306_ts.ko
gt818_ts.ko
gt82x.ko
gt911_ts.ko
ft5x_ts.ko
gslX680.ko
gslX680new.ko
icn83xx_ts.ko
gt9xx_ts.ko
gt9xxf_ts.ko
tu_ts.ko
//雜項
da380.ko //加速度傳感器
fatfs.ko //文件系統
scsi_wait_scan.ko
sw-device.ko //Linux kernel modules for Detection i2c device.
uvcvideo.ko //UVC攝像頭
//普通攝像頭驅動 media/video/
ov2640.ko
ov5642.ko
//V4L2
videobuf-core.ko
videobuf-dma-contig.ko
videobuf2-core.ko
videobuf2-memops.ko
videobuf2-vmalloc.ko
//VFE
vfe_v4l2.ko //media/video/sunxi-vfe
vfe_os.ko
vfe_subdev.ko
cci.ko //攝像頭控制接口,sunxi-vfe/csi_cci
h22_mipi.ko //media/video/sunxi-vfe/device/h22_mipi.ko
//cedar 視頻編碼
cedar_ve.ko //media/cedar-ve/cedar_ve.ko
~~~
實際可以使用的是media/video/sunxi-vfe/下的攝像頭驅動
~~~
platform_cfg.h
bsp_common.c
config.c
config.h
vfe.c
vfe.h
vfe_os.c
vfe_os.h
vfe_os.ko
vfe_subdev.c
vfe_subdev.h
vfe_subdev.ko
vfe_v4l2.ko
//調焦器
actuator
//攝像頭控制器接口驅動
csi
csi_cci
mipi_csi
//閃光燈
flash_light
//ISP相關
isp_cfg
lib //isp庫
platform //不同主控芯片的配置
//測試,功能
test
utility
//支持的傳感器
device
~~~
支持的傳感器
~~~
Makefile gc0312.c gc5004.c hi257.c nt99252.c ov5640.c s5k3h7.c sp2518.c
ar0330.c gc0328.c gc5004_mipi.c hm5040.c ov12830.c ov5640_mipi.c s5k4e1.c sp2519.c
ar0330_mipi.c gc0328c.c gs5604.c hm5065.c ov13850.c ov5647.c s5k4e1_mipi.c sp5408.c
bf3a03.c gc0329.c gt2005.c hm8030.c ov16825.c ov5647_mipi.c s5k4ec.c sp5409.c
built-in.o gc1004_mipi.c h22_mipi.c hm8131.c ov2640.c ov5648.c s5k4ec_mipi.c t4k05.c
camera.h gc2035.c h22_mipi.ko imx179.c ov2686.c ov5650.c s5k5e2ya.c t8et5.c
camera_cfg.h gc2145.c h22_mipi.mod.c imx214.c ov2710.c ov7736.c s5k5e2yx.c tc358743.c
gc0307.c gc2155.c h22_mipi.mod.o imx219.c ov2710_mipi.c ov8825.c siv121d.c
gc0308.c gc2235.c h22_mipi.o modules.builtin ov4689.c ov8850.c sp0718.c
gc0309.c gc2355.c h42_mipi.c modules.order ov4689_60fps.c ov8858.c sp0838.c
gc0311.c gc2355_mipi.c hi253.c nt99231_mipi.c ov4689_sdv.c ov8858_4lane.c sp2508.c
~~~
可見zero配套的ov2640和ov5647都在其中。
但是他們不在menuconfig中,所以在上層的Kconfig中加入:
~~~
config OV2640
tristate "ov2640"
default n
config OV5647_MIPI
tristate "ov5647_mipi"
default n
~~~
在本層的Makefile中加入:
~~~
obj-$(CONFIG_OV2640) += ov2640.o
obj-$(CONFIG_OV5647_MIPI) += ov5647_mipi.o
~~~
重新在menuconfig中勾選,編譯,即可得到:
~~~
LD [M] drivers/media/video/sunxi-vfe/device/ov2640.ko
LD [M] drivers/media/video/sunxi-vfe/device/ov5647_mipi.ko
~~~
將ko文件放入系統中,手動加載,然后使用fswebcam嘗試拍照:
~~~
root@LicheePi:~# fswebcam -d /dev/video0 --no-banner -r 320x240 capture.jpg
[ 255.199106] [VFE]vfe_open
--- Opening /dev/video0...
[ 255.202406] [VFE]..........................vfe clk open!.......................
Trying source module v4l2...[ 255.213786] [VFE]vfe_open ok
[ 255.219628] [VFE_ERR]input index(0) > dev->dev_qty(1)-1 invalid!, device_valid_flag[0] = 0
/dev/video0 opened.
255.229491] [VFE]vfe_close
mNo input was specified, using t[ 255.235232] [VFE]vfe select input flag = 0, s_input have not be used .
he first.
Unable to qu[ 255.245365] [VFE]..........................vfe clk close!.......................
ery input 0.
VIDIOC_EN[ 255.256556] [VFE]vfe_close end
UMINPUT: Invalid argument
~~~
跟蹤相關信息,是在vfe.c,
~~~
static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *inp)
~~~
中:
~~~
2807 if (0 == dev->device_valid_flag[inp->index]) {
2808 vfe_err("input index(%d) > dev->dev_qty(%d)-1 invalid!, device_valid_flag[%d] = %d\n", inp->index, dev->dev_ qty,inp->index, dev->device_valid_flag[inp->index]);
2809 return -EINVAL;
2810 }
~~~
即枚舉攝像頭時,發現device_valid_flag標志位不對,該標志位是在:
~~~
static void probe_work_handle(struct work_struct *work)
if(vfe_sensor_register_check(dev,&dev->v4l2_dev,dev->ccm_cfg[input_num],&dev->dev_sensor[input_num],input_nu m) == NULL)
5126 {
5127 vfe_err("vfe sensor register check error at input_num = %d\n",input_num);
5128 dev->device_valid_flag[input_num] = 0;
5129 //goto snesor_register_end;
5130 }
5131 else{
5132 dev->device_valid_flag[input_num] = 1;
5133 }
~~~
這個函數是在vfe_probe中調用,也即初始化時檢測的。
vfe驅動加載過程:
csi_cci/cci_platform_drv.c 加載cci.ko
vfe.c vfe_os.ko加載
vfe_subdev.ko
vfe_v4l2.ko //media/video/sunxi-vfe
查看開機啟動信息:
~~~
//cci.ko加載,即攝像頭控制器初始化
[ 0.808628] [VFE]cci probe start cci_sel = 0!
[ 0.813793] [VFE]cci probe end cci_sel = 0!
[ 0.818593] [VFE]cci_init end
//VFE驅加載
[ 0.822038] [VFE]Welcome to Video Front End driver
[ 0.827986] [VFE]pdev->id = 0
[ 0.831435] [VFE]dev->mipi_sel = 0
[ 0.835324] [VFE]dev->vip_sel = 0
[ 0.839114] [VFE]dev->isp_sel = 0
[ 0.849164] [VFE_WARN]vfe vpu clock is null
[ 0.849164] [VFE_WARN]vfe vpu clock is null
[ 0.860599] [VFE]pdev->id = 1
[ 0.864021] [VFE]dev->mipi_sel = 1
[ 0.868014] [VFE]dev->vip_sel = 1
[ 0.871864] [VFE]dev->isp_sel = 0
[ 0.875672] [VFE]probe_work_handle start!
[ 0.880358] [VFE]..........................vfe clk open!.......................
[ 0.880358] [VFE]..........................vfe clk open!.......................
[ 0.889010] [VFE]v4l2 subdev register input_num = 0
[ 0.894683] [VFE_WARN]vfe vpu clock is null
[ 0.894683] [VFE_WARN]vfe vpu clock is null
[ 0.899688] [VFE_ERR]vip1 request pinctrl handle for device [csi1] failed!
[ 0.907603] [VFE_ERR]get regulator csi_avdd error!
[ 0.913056] [VFE_ERR]vfe_device_regulator_get error at input_num = 0
[ 0.913056] [VFE_ERR]vfe_device_regulator_get error at input_num = 0
[ 0.920482] [VFE]vfe_init end
[ 0.920482] [VFE]vfe_init end
//V4L2設備注冊,生成video0
[ 0.933586] [VFE]V4L2 device registered as video0
[ 0.938969] [VFE]..........................vfe clk close!.......................
[ 0.938969] [VFE]..........................vfe clk close!.......................
[ 0.956440] [VFE]probe_work_handle end!
[ 0.960938] [VFE]probe_work_handle start!
[ 0.965515] [VFE]..........................vfe clk open!.......................
[ 0.965515] [VFE]..........................vfe clk open!.......................
[ 0.991682] [VFE]v4l2 subdev register input_num = 0
[ 0.997227] [VFE]vfe sensor detect start! input_num = 0
[ 0.997227] [VFE]vfe sensor detect start! input_num = 0
[ 1.003274] [VFE]Find sensor name is "ov2640", i2c address is 60, type is "YUV" !
[ 1.011824] [VFE]Sub device register "ov2640" i2c_addr = 0x60 start!
[ 1.018998] [VFE_ERR]Error registering v4l2 subdevice No such device!
[ 1.026388] [VFE_ERR]vfe sensor register check error at input_num = 0
[ 1.026388] [VFE_ERR]vfe sensor register check error at input_num = 0
[ 1.079242] [VFE]V4L2 device registered as video1
[ 1.084960] [VFE]..........................vfe clk close!.......................
[ 1.084960] [VFE]..........................vfe clk close!.......................
[ 1.116779] [VFE]probe_work_handle end!
[ 5.012110] [VFE]vfe_open
[ 5.012110] [VFE]vfe_open
[ 5.043465] [VFE]vfe_open
[ 5.043465] [VFE]vfe_open
[ 5.058511] [VFE]..........................vfe clk open!.......................
[ 5.058511] [VFE]..........................vfe clk open!.......................
[ 5.082179] [VFE]..........................vfe clk open!.......................
[ 5.082179] [VFE]..........................vfe clk open!.......................
[ 5.112320] [VFE]vfe_open ok
[ 5.112320] [VFE]vfe_open ok
[ 5.115853] [VFE]vfe_close
[ 5.115853] [VFE]vfe_close
[ 5.118958] [VFE]vfe select input flag = 0, s_input have not be used .
[ 5.118958] [VFE]vfe select input flag = 0, s_input have not be used .
[ 5.126480] [VFE]..........................vfe clk close!.......................
[ 5.126480] [VFE]..........................vfe clk close!.......................
[ 5.144821] [VFE]vfe_open ok
[ 5.144821] [VFE]vfe_open ok
[ 5.148348] [VFE]vfe_close
[ 5.148348] [VFE]vfe_close
[ 5.151598] [VFE]vfe select input flag = 0, s_input have not be used .
[ 5.151598] [VFE]vfe select input flag = 0, s_input have not be used .
[ 5.158972] [VFE]..........................vfe clk close!.......................
[ 5.158972] [VFE]..........................vfe clk close!.......................
[ 5.224773] [VFE]vfe_close end
[ 5.224773] [VFE]vfe_close end
[ 5.282919] [VFE]vfe_close end
[ 5.282919] [VFE]vfe_close end
~~~
vfe_sensor_register_check
~~~
static struct v4l2_subdev *vfe_sensor_register_check(struct vfe_dev *dev,struct v4l2_device *v4l2_dev,struct ccm_config *ccm_cfg,
struct i2c_board_info *sensor_i2c_board,int input_num )
{
int sensor_cnt,ret, sensor_num;
struct sensor_item sensor_info;
if(dev->vip_define_sensor_list == 1)
{
sensor_num = ccm_cfg->sensor_cfg_ini->detect_sensor_num;
if(ccm_cfg->sensor_cfg_ini->detect_sensor_num == 0) {
sensor_num = 1;
}
} else {
sensor_num = 1;
}
for(sensor_cnt=0; sensor_cnt<sensor_num; sensor_cnt++)
{
if(dev->vip_define_sensor_list == 1)
{
if(ccm_cfg->sensor_cfg_ini->detect_sensor_num > 0)
cpy_ccm_sub_device_cfg(ccm_cfg, sensor_cnt);
}
if(get_sensor_info(ccm_cfg->ccm, &sensor_info) == 0)
{
if(ccm_cfg->i2c_addr != sensor_info.i2c_addr)
{
vfe_warn("Sensor info \"%s\" i2c_addr is different from sys_config!\n", sensor_info.sensor_name );
//vfe_warn("Sensor info i2c_addr = %d, sys_config i2c_addr = %d!\n", sensor_info.i2c_addr, ccm_cfg->i2c_addr);
//ccm_cfg->i2c_addr = sensor_info.i2c_addr;
}
if(ccm_cfg->is_bayer_raw != sensor_info.sensor_type)
{
vfe_warn("Camer detect \"%s\" fmt is different from sys_config!\n", sensor_info_type[sensor_info.sensor_type]);
vfe_warn("Apply detect fmt = %d replace sys_config fmt = %d!\n", sensor_info.sensor_type, ccm_cfg->is_bayer_raw);
ccm_cfg->is_bayer_raw = sensor_info.sensor_type;
}
if(sensor_info.sensor_type == SENSOR_RAW)
{
ccm_cfg->is_isp_used = 1;
}
else
{
ccm_cfg->act_used = 0;
}
vfe_print("Find sensor name is \"%s\", i2c address is %x, type is \"%s\" !\n",sensor_info.sensor_name,sensor_info.i2c_addr,
sensor_info_type[sensor_info.sensor_type]);
}
sensor_i2c_board->addr = (unsigned short)(ccm_cfg->i2c_addr>>1);
strcpy(sensor_i2c_board->type,ccm_cfg->ccm);
vfe_print("Sub device register \"%s\" i2c_addr = 0x%x start!\n",sensor_i2c_board->type, ccm_cfg->i2c_addr);
ret = vfe_sensor_subdev_register_check(dev,v4l2_dev,ccm_cfg,sensor_i2c_board);
if( ret == -1)
{
vfe_sensor_subdev_unregister(v4l2_dev,ccm_cfg,sensor_i2c_board);
vfe_print("Sub device register \"%s\" failed!\n",sensor_i2c_board->type);
ccm_cfg->sd =NULL;
continue;
}
else if(ret == ENODEV ||ret == EFAULT)
{
continue;
}
else if(ret == 0)
{
vfe_print("Sub device register \"%s\" is OK!\n",sensor_i2c_board->type);
break;
}
}
return ccm_cfg->sd;
}
~~~
- 前言
- 荔枝派TODO任務領取
- linux使用小貼士
- 入門篇
- 板卡介紹
- 開箱指南
- 燒錄啟動系統
- 聯網方法
- 鏡像使用
- 鏡像說明
- buildroot系統使用
- debian系統使用
- 外設操作
- 外設操作概覽
- 低速外設
- GPIO
- GPIO模擬低速接口
- UART
- PWM
- I2C
- SPI
- 高速接口
- SDIO
- USB
- EtherNet
- DVP CSI
- MIPI CSI
- 模擬外設
- CODEC
- LRADC
- 常見設備驅動
- USB攝像頭
- USB 3G/4G 網卡
- 舵機
- 開發篇
- UBOOT適配
- UBOOT編譯
- UBOOT配置
- UBOOT配置屏幕分辨率
- UBOOT配置SPI啟動
- Linux內核開發
- Linux內核編譯
- BSP Linux內核編譯.md
- Linux內核選項
- 外設驅動與設備樹
- RTL8723BS驅動
- 根文件系統定制
- buildroot定制系統
- buildroot添加軟件包
- openwrt定制系統
- emdebian定制系統
- camdriod開發
- camdriod編譯
- 主線Uboot引導Camdriod
- 系統鏡像打包
- XBOOT適配
- 荔枝運行XBOOT
- 應用篇
- 游戲機-基于EmulationStation
- 游戲機-gnuboy
- 語音識別-科大訊飛云
- GUI-QT5
- 語音識別-離線關鍵詞識別
- 路由器-Lichee Zero
- 投稿文章
- 荔枝派Zero開箱指南
- Zero i2c oled使用指南
- zero SPI LCD使用指南
- Zero u-boot編譯和使用指南
- TF WiFi使用方法
- Zero Ethernet使用指南
- Zero 移植Qt5.4.1
- ZeroSpiNorFlash啟動系統制作指南
- Visio-uboot-sunxi流程
- lichee 編譯踩坑記錄(ilichee ZERO)
- lichee_zero_外設GPIO接口
- TF WIFI 小白編
- 從零開始LicheePi Zero的開發
- 認識Zero的硬件
- 搭建Zero的開發環境
- 主線Uboot
- 主線kernel
- BSP kernel
- BSP內核啟動
- bsp內核的攝像頭使用
- BSP內核中的保留內存
- uboot啟動BSP內核常見錯誤
- BSP內核 FBTFT移植
- BSP內核啟動錯誤及警告解決
- buildroot 根文件系統
- emdebian 根文件系統
- SPI Flash 系統編譯
- sunxi-fel增加對16M 以上flash的支持
- overlayfs的使用
- jffs2系統掛載不上的常見原因
- JFFS2 文件系統簡介
- uboot對spi flash的識別
- bsp內核的SPI flash啟動
- Docker開發環境
- Docker 命令速查
- 基礎ubuntu系統配置
- docker離線鏡像
- Zero系統燒錄
- dd鏡像燒錄
- 分區鏡像燒錄
- SPI Flash系統燒錄
- 一鍵鏡像燒錄
- Zero外設把玩
- I2C操作
- PWM輸出
- CODEC的使用
- 以太網使用指南
- GPIO操作
- 文件IO方式
- C語言接口(mmap)
- Python操作GPIO
- pinctrl-sunxi介紹
- UART操作
- 點屏
- 點屏之RGB屏
- 點屏之SPI屏 ili9341
- 點屏之SPI OLED
- 點屏之I2C OLED
- 點屏之SPI屏 ili9488
- 點屏之MCU屏
- 點屏之觸摸屏驅動
- 點屏之simple-framebuffer
- 點屏之屏幕時序
- 時鐘控制器CCM
- 攝像頭
- BSP DVP攝像頭
- BSP MIPI 攝像頭
- 主線DVP攝像頭
- 主線 MIPI攝像頭
- SPI 操作
- 應用層開發
- 開機自啟動
- Segment Fault調試
- Zero通過OTG共享PC網絡
- USB攝像頭使用
- 基于QT的GUI開發
- 移植tslib
- 移植QT5.9.1
- 移植QT4.8.7
- QtCreator使用
- Qt5.x移植到Qt4.8
- Qt字體相關
- Qt移植總結
- Qt裁剪
- Qt去除鼠標指針顯示
- zero_imager使用
- 驅動開發
- 設備樹簡介
- GPU/DRM 顯示驅動
- sys下設備樹查看
- atmel觸摸屏驅動分析
- atmel觸摸屏中斷改輪詢
- uboot下gpio操作
- helloworld驅動編譯演示
- FBTFT分析
- 內核模塊靜態加載的順序
- SPI驅動分析
- SPI 驅動編寫
- Uboot開發
- 開機logo
- 看門狗的使用
- 關于系統reboot
- 內核printk等級設置