![image-20221123145359081](https://file.elecfans.com//web2/M00/96/3D/pYYBAGQFUTyATUM4AAgTVkkhR6k730.png)
![image-20221123145359081](https://file.elecfans.com//web2/M00/96/3D/pYYBAGQFUT6AKLV_ABXUYg5dy40683.png)
![image-20221123145359081](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUT-AMfi1ABUT7vzzsko821.png)
![image-20221123145359081](https://file.elecfans.com//web2/M00/96/3D/pYYBAGQFUUCAI30oAAx3xQrf2rw561.png)
![image-20221123145359081](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUUKAD4sDAA5O152ocNw326.png)
Tina Linux Camera開發(fā)指南
1 概述
編寫目的:介紹camera 模塊在sunxi 平臺(tái)上的開發(fā)流程。
適用范圍:本文檔目前適用于tina3.0 以上具備camera 的硬件平臺(tái)。
2 模塊介紹
2.1 模塊功能介紹
用于接收并行或者mipi 接口的sensor 信號(hào)或者是bt656 格式的信號(hào)。
2.2 硬件介紹
目前Tina 系統(tǒng)的各平臺(tái)camera 硬件接口、linux 內(nèi)核版本以及camera 驅(qū)動(dòng)框架如下表所示:
?
表2-1: 平臺(tái)CSI 框架
?
平臺(tái) | 支持接口 | 是否具備ISP模塊 | linux 內(nèi)核版本 | camera 驅(qū)動(dòng)框架 |
---|---|---|---|---|
F35 | 并口csi、mipi | 否 | 3.4 | VFE |
R16 | 并口csi | 否 | 3.4 | VFE |
R18 | 并口csi | 否 | 4.4 | VFE |
R30 | 并口csi | 否 | 4.4 | VFE |
R40 | 并口csi | 否 | 3.10 | VFE |
R311 | mipi csi | 是 | 4.9 | VIN |
MR133 | mipi csi | 是 | 4.9 | VIN |
R818 | mipi csi | 是 | 4.9 | VIN |
MR813 | mipi csi | 是 | 4.9 | VIN |
R528 | 并口csi | 否 | 5.4 | VIN |
V536 | 并口csi、mipi | 是 | 4.9 | VIN |
V533 | 并口csi、mipi | 是 | 4.9 | VIN |
V831 | 并口csi、mipi | 是 | 4.9 | VIN |
V833 | 并口csi、mipi | 是 | 4.9 | VIN |
V851 | 并口csi、mipi | 是 | 4.9 | VIN |
V853 | 并口csi、mipi | 是 | 4.9 | VIN |
注意:
如果平臺(tái)沒有ISP 模塊,那么將不支持RAW sensor(即sensor 只輸出采集到的原始數(shù)據(jù)),文檔中提到的RAW 等相關(guān)信息不用理會(huì);
如果平臺(tái)沒有支持mipi 接口,文檔中提到的mipi 相關(guān)信息忽略;
不同平臺(tái)可能將使用不同的camera 驅(qū)動(dòng)框架,這點(diǎn)注意區(qū)分;
2.3 源碼結(jié)構(gòu)介紹
2.3.1 linux3.4 VFE 框架
驅(qū)動(dòng)路徑位于linux-3.4/drivers/media/video/sunxi-vfe 下。
sunxi-vfe:.
│ bsp_common.c ;底層bsp共用的函數(shù)
│ bsp_common.h ;底層bsp共用函數(shù)頭文件
│ config.c ;讀取sys_config.fex的參數(shù)配置和isp參數(shù)
│ config.h ;讀取sys_config.fex和isp參數(shù)函數(shù)的頭文件
│ Kconfig
│ Makefile
│ platform_cfg.h ;區(qū)分各個(gè)平臺(tái)的頭文件
│ vfe.c ;v4l2驅(qū)動(dòng)實(shí)現(xiàn)主體(包含視頻接口和ISP部分)
│ vfe.h ;v4l2驅(qū)動(dòng)頭文件
│ vfe_os.c ;系統(tǒng)資源函數(shù)實(shí)現(xiàn)(pin,clock,memory)
│ vfe_os.h ;系統(tǒng)資源函數(shù)頭文件
│ vfe_subdev.c ;sensor調(diào)用vfe資源函數(shù)
│ vfe_subdev.h ;sensor 調(diào)用vfe資源函數(shù)頭文件
│
├─actuator
│ actuator.c ;vcm driver的一般行為
│ actuator.h ;vcm driver的頭文件
│ dw9714_act.c ;具體vcm driver型號(hào)實(shí)現(xiàn)
│ Makefile
│
├─csi
│ bsp_csi.c ;底層csi bsp函數(shù)
│ bsp_csi.h ;底層csi bsp函數(shù)頭文件
│ csi_reg.c ;csi硬件底層實(shí)現(xiàn)
│ csi_reg.h ;csi硬件底層實(shí)現(xiàn)頭文件
│ csi_reg_i.h ;csi 寄存器資源頭文件
│
├─device
│ camera.h ;camera公用結(jié)構(gòu)體頭文件
│ camera_cfg.h ;camera ioctl擴(kuò)展命令頭文件
│ Makefile
│ ov5640.c ;具體的sensor驅(qū)動(dòng)
│
├─flash_light
│ flash.h ;led補(bǔ)光燈驅(qū)動(dòng)頭文件
│ flash_io.c ;led補(bǔ)光燈io控制實(shí)現(xiàn)
│ Makefile
│
├─lib
│ bsp_isp.h ;底層isp bsp函數(shù)頭文件
│ bsp_isp_algo.h ;底層isp 算法bsp函數(shù)頭文件
│ bsp_isp_comm.h ;底層isp共用函數(shù)頭文件
│ isp_module_cfg.h ;isp里面各模塊功能配置的頭文件
│ libisp ;isp的函數(shù)庫(kù)
│ lib_mipicsi2_v1 ;A31mipi庫(kù)
│ lib_mipicsi2_v2 ;A80/A83mipi庫(kù)
├─csi_cci
│ cci_helper.c ;cci 與設(shè)備相關(guān)初始化、注冊(cè)以及通信等相關(guān)函數(shù)集實(shí)現(xiàn)
│ cci_helper.h ;cci 與設(shè)備相關(guān)初始化、注冊(cè)以及通信等相關(guān)函數(shù)集實(shí)現(xiàn)頭文件
│ bsp_cci.c ;cci 操作函數(shù)集實(shí)現(xiàn)
│ bsp_cci.h ;cci 操作函數(shù)集頭文件
│ csi_cci_reg.c ;cci 底層實(shí)現(xiàn)
│ csi_cci_reg.h ;cci 底層實(shí)現(xiàn)頭文件
│ csi_cci_reg_i.h ;cci寄存器資源頭文件
│
├─mipi_csi
│ bsp_mipi_csi.c ;底層mipi bsp函數(shù)
│ bsp_mipi_csi.h ;底層mipi bsp函數(shù)頭文件
│
└─utility
cfg_op.c ;讀取ini文件的實(shí)現(xiàn)函數(shù)
cfg_op.h ;讀取ini文件函數(shù)對(duì)應(yīng)的頭文件
2.3.2 linux3.10 VFE 框架
驅(qū)動(dòng)路徑位于linux-3.10/drivers/media/platform/sunxi-vfe 下。
sunxi-vfe:.
│ bsp_common.c ;底層bsp共用的函數(shù)
│ bsp_common.h ;底層bsp共用函數(shù)頭文件
│ config.c ;讀取sys_config.fex的參數(shù)配置和isp參數(shù)
│ config.h ;讀取sys_config.fex和isp參數(shù)函數(shù)的頭文件
│ Kconfig
│ Makefile
│ platform_cfg.h ;區(qū)分各個(gè)平臺(tái)的頭文件
│ vfe.c ;v4l2驅(qū)動(dòng)實(shí)現(xiàn)主體(包含視頻接口和ISP部分)
│ vfe.h ;v4l2驅(qū)動(dòng)頭文件
│ vfe_os.c ;系統(tǒng)資源函數(shù)實(shí)現(xiàn)(pin,clock,memory)
│ vfe_os.h ;系統(tǒng)資源函數(shù)頭文件
│ vfe_subdev.c ;sensor調(diào)用vfe資源函數(shù)
│ vfe_subdev.h ;sensor 調(diào)用vfe資源函數(shù)頭文件
│
├─actuator
│ actuator.c ;vcm driver的一般行為
│ actuator.h ;vcm driver的頭文件
│ dw9714_act.c ;具體vcm driver型號(hào)實(shí)現(xiàn)
│ Makefile
│
├─csi
│ bsp_csi.c ;底層csi bsp函數(shù)
│ bsp_csi.h ;底層csi bsp函數(shù)頭文件
│ csi_reg.c ;csi硬件底層實(shí)現(xiàn)
│ csi_reg.h ;csi硬件底層實(shí)現(xiàn)頭文件
│ csi_reg_i.h ;csi 寄存器資源頭文件
│
├─device
│ camera.h ;camera公用結(jié)構(gòu)體頭文件
│ camera_cfg.h ;camera ioctl擴(kuò)展命令頭文件
│ Makefile
│ ov5640.c ;具體的sensor驅(qū)動(dòng)
│
├─flash_light
│ flash.h ;led補(bǔ)光燈驅(qū)動(dòng)頭文件
│ flash_io.c ;led補(bǔ)光燈io控制實(shí)現(xiàn)
│ Makefile
│
├─lib
│ bsp_isp.h ;底層isp bsp函數(shù)頭文件
│ bsp_isp_algo.h ;底層isp 算法bsp函數(shù)頭文件
│ bsp_isp_comm.h ;底層isp共用函數(shù)頭文件
│ isp_module_cfg.h ;isp里面各模塊功能配置的頭文件
│ libisp ;isp的函數(shù)庫(kù)
│ lib_mipicsi2_v1 ;A31mipi庫(kù)
│ lib_mipicsi2_v2 ;A80/A83mipi庫(kù)
├─csi_cci
│ cci_helper.c ;cci 與設(shè)備相關(guān)初始化、注冊(cè)以及通信等相關(guān)函數(shù)集實(shí)現(xiàn)
│ cci_helper.h ;cci 與設(shè)備相關(guān)初始化、注冊(cè)以及通信等相關(guān)函數(shù)集實(shí)現(xiàn)頭文件
│ bsp_cci.c ;cci 操作函數(shù)集實(shí)現(xiàn)
│ bsp_cci.h ;cci 操作函數(shù)集頭文件
│ csi_cci_reg.c ;cci 底層實(shí)現(xiàn)
│ csi_cci_reg.h ;cci 底層實(shí)現(xiàn)頭文件
│ csi_cci_reg_i.h ;cci寄存器資源頭文件
│
├─mipi_csi
│ bsp_mipi_csi.c ;底層mipi bsp函數(shù)
│ bsp_mipi_csi.h ;底層mipi bsp函數(shù)頭文件
│
└─utility
cfg_op.c ;讀取ini文件的實(shí)現(xiàn)函數(shù)
cfg_op.h ;讀取ini文件函數(shù)對(duì)應(yīng)的頭文件
2.3.3 linux4.4 VFE 框架
驅(qū)動(dòng)路徑位于linux-4.4/drivers/media/platform/sunxi-vfe 下。
sunxi-vfe:.
│ bsp_common.c ;底層bsp共用的函數(shù)
│ bsp_common.h ;底層bsp共用函數(shù)頭文件
│ config.c ;讀取sys_config.fex的參數(shù)配置和isp參數(shù)
│ config.h ;讀取sys_config.fex和isp參數(shù)函數(shù)的頭文件
│ Kconfig
│ Makefile
│ platform_cfg.h ;區(qū)分各個(gè)平臺(tái)的頭文件
│ vfe.c ;v4l2驅(qū)動(dòng)實(shí)現(xiàn)主體(包含視頻接口和ISP部分)
│ vfe.h ;v4l2驅(qū)動(dòng)頭文件
│ vfe_os.c ;系統(tǒng)資源函數(shù)實(shí)現(xiàn)(pin,clock,memory)
│ vfe_os.h ;系統(tǒng)資源函數(shù)頭文件
│ vfe_subdev.c ;sensor調(diào)用vfe資源函數(shù)
│ vfe_subdev.h ;sensor 調(diào)用vfe資源函數(shù)頭文件
│
├─actuator
│ actuator.c ;vcm driver的一般行為
│ actuator.h ;vcm driver的頭文件
│ dw9714_act.c ;具體vcm driver型號(hào)實(shí)現(xiàn)
│ Makefile
│
├─csi
│ bsp_csi.c ;底層csi bsp函數(shù)
│ bsp_csi.h ;底層csi bsp函數(shù)頭文件
│ csi_reg.c ;csi硬件底層實(shí)現(xiàn)
│ csi_reg.h ;csi硬件底層實(shí)現(xiàn)頭文件
│ csi_reg_i.h ;csi 寄存器資源頭文件
│
├─device
│ camera.h ;camera公用結(jié)構(gòu)體頭文件
│ camera_cfg.h ;camera ioctl擴(kuò)展命令頭文件
│ Makefile
│ ov5640.c ;具體的sensor驅(qū)動(dòng)
│
├─flash_light
│ flash.h ;led補(bǔ)光燈驅(qū)動(dòng)頭文件
│ flash_io.c ;led補(bǔ)光燈io控制實(shí)現(xiàn)
│ Makefile
│
├─lib
│ bsp_isp.h ;底層isp bsp函數(shù)頭文件
│ bsp_isp_algo.h ;底層isp 算法bsp函數(shù)頭文件
│ bsp_isp_comm.h ;底層isp共用函數(shù)頭文件
│ isp_module_cfg.h ;isp里面各模塊功能配置的頭文件
│ libisp ;isp的函數(shù)庫(kù)
│ lib_mipicsi2_v1 ;A31mipi庫(kù)
│ lib_mipicsi2_v2 ;A80/A83mipi庫(kù)
├─csi_cci
│ cci_helper.c ;cci 與設(shè)備相關(guān)初始化、注冊(cè)以及通信等相關(guān)函數(shù)集實(shí)現(xiàn)
│ cci_helper.h ;cci 與設(shè)備相關(guān)初始化、注冊(cè)以及通信等相關(guān)函數(shù)集實(shí)現(xiàn)頭文件
│ bsp_cci.c ;cci 操作函數(shù)集實(shí)現(xiàn)
│ bsp_cci.h ;cci 操作函數(shù)集頭文件
│ csi_cci_reg.c ;cci 底層實(shí)現(xiàn)
│ csi_cci_reg.h ;cci 底層實(shí)現(xiàn)頭文件
│ csi_cci_reg_i.h ;cci寄存器資源頭文件
│
├─mipi_csi
│ bsp_mipi_csi.c ;底層mipi bsp函數(shù)
│ bsp_mipi_csi.h ;底層mipi bsp函數(shù)頭文件
│
└─utility
cfg_op.c ;讀取ini文件的實(shí)現(xiàn)函數(shù)
cfg_op.h ;讀取ini文件函數(shù)對(duì)應(yīng)的頭文件
2.3.4 linux4.4 VIN 框架
驅(qū)動(dòng)路徑位于linux-4.4/drivers/media/platform/sunxi-vin 下。
sunxi-vin:
│ vin.c ;v4l2驅(qū)動(dòng)實(shí)現(xiàn)主體(包含視頻接口和ISP部分)
│ vin.h ;v4l2驅(qū)動(dòng)頭文件
│ top_reg.c ;vin對(duì)各v4l2 subdev管理接口實(shí)現(xiàn)主體
│ top_reg.h ;管理接口頭文件
│ top_reg_i.h ;vin模塊接口層部分結(jié)構(gòu)體
│
├─modules
│ ├─actuator
│ │ actuator.c ;vcm driver的一般行為
│ │ actuator.h ;vcm driver的頭文件
│ │ dw9714_act.c ;具體vcm driver型號(hào)實(shí)現(xiàn)
│ │ Makefile
│ ├─flash
│ │ flash.h ;led補(bǔ)光燈驅(qū)動(dòng)頭文件
│ │ flash_io.c ;led補(bǔ)光燈io控制實(shí)現(xiàn)
│ ├─sensor
│ │ camera.h ;camera公用結(jié)構(gòu)體頭文件
│ │ camera_cfg.h ;camera ioctl擴(kuò)展命令頭文件
│ │ sensor_helper.c ;sensor公用操作接口函數(shù)文件
│ │ sensor_helper.h ;sensor公用操作接口函數(shù)頭文件
│ │ Makefile
│ │ ov5640.c ;具體的sensor驅(qū)動(dòng)
│
├─platform
│ platform_cfg.h ;平臺(tái)相關(guān)的配置接口
│
├─utility
│ bsp_common.h ;底層公用的格式配置函數(shù)頭文件
│ bsp_common.c ;底層公用的格式配置函數(shù)文件
│ cfg_op.h ;解析配置文件接口頭文件
│ cfg_op.c ;解析配置文件接口函數(shù)實(shí)現(xiàn)主體
│ config.h ;解析設(shè)備樹的函數(shù)頭文件
│ config.c ;解析設(shè)備樹的接口函數(shù)主體
│ sensor_info.h ;sensor列表信息頭文件
│ sensor_info.c ;獲取sensor列表信息函數(shù)主體
│ vin_io.h ;vin框架io操作接口頭文件
│ vin_io.c ;vin框架io操作接口文件
│ vin_os.h ;vin框架系統(tǒng)操作接口頭文件
│ vin_os.c ;vin框架系統(tǒng)操作接口文件
│ vin_supply.h ;vin框架設(shè)置時(shí)鐘頻率等接口頭文件
│ vin_supply.c ;vin框架設(shè)置時(shí)鐘頻率等接口函數(shù)主體
│
├─vin-cci
│ cci_helper.c ;cci 與設(shè)備相關(guān)初始化、注冊(cè)以及通信等相關(guān)函數(shù)集實(shí)現(xiàn)
│ cci_helper.h ;cci 與設(shè)備相關(guān)初始化、注冊(cè)以及通信等相關(guān)函數(shù)集實(shí)現(xiàn)頭文件
│ bsp_cci.c ;cci 操作函數(shù)集實(shí)現(xiàn)
│ bsp_cci.h ;cci 操作函數(shù)集頭文件
│ csi_cci_reg.c ;cci 底層實(shí)現(xiàn)
│ csi_cci_reg.h ;cci 底層實(shí)現(xiàn)頭文件
│ csi_cci_reg_i.h ;cci寄存器資源頭文件
│ sunxi_cci.c ;cci 接口封裝實(shí)現(xiàn)
│ sunxi_cci.h ;cci 接口封裝頭文件
│
├─vin-csi
│ bsp_csi.c ;csi 操作函數(shù)集實(shí)現(xiàn)
│ bsp_csi.h ;csi 操作函數(shù)集頭文件
│ csi_reg.c ;csi 底層實(shí)現(xiàn)
│ csi_reg.h ;csi 底層實(shí)現(xiàn)頭文件
│ csi_reg_i.h ;csi寄存器資源頭文件
│ parser_reg.c ;csi 底層實(shí)現(xiàn)
│ parser_reg.h ;csi 底層實(shí)現(xiàn)頭文件
│ parser_reg_i.h ;csi寄存器資源頭文件
│ sunxi_csi.c ;csi 接口封裝實(shí)現(xiàn)
│ sunxi_csi.h ;csi 接口封裝頭文件
│
├─vin-isp
│ bsp_isp.c ;isp操作函數(shù)集實(shí)現(xiàn)
│ bsp_isp.h ;isp操作函數(shù)集頭文件
│ bsp_isp_comm.h ;isp結(jié)構(gòu)體定義
│ isp_default_tbl.h ;isp默認(rèn)配置列表
│ isp_platform_drv.h ;isp平臺(tái)操作集頭文件
│ isp_platform_drv.c ;isp平臺(tái)操作集實(shí)現(xiàn)
│ sunxi_isp.h ;sunxi平臺(tái)isp操作集頭文件
│ sunxi_isp.c ;sunxi平臺(tái)isp操作集實(shí)現(xiàn)
│
├─vin-mipi
│ bsp_mipi_csi.c ;底層mipi bsp函數(shù)
│ bsp_mipi_csi.h ;底層mipi bsp函數(shù)頭文件
│ bsp_mipi_csi_v1.c ;sunxi平臺(tái)底層mipi bsp接口函數(shù)
│ sunxi_mipi.c ;sunxi平臺(tái)mipi實(shí)現(xiàn)
│ bsp_mipi_csi.h ;sunxi平臺(tái)mipi實(shí)現(xiàn)頭文件
│ combo_common.c ;combo common頭文件
│ protocol.h ;protocol頭文件
├─vin-stat
│ vin_h3a.c ;vin 3a操作函數(shù)
│ vin_h3a.h ;vin 3a操作函數(shù)頭文件
│ vin_ispstat.c ;sunxi isp stat操作函數(shù)
│ vin_ispstat.h ;sunxi isp stat操作函數(shù)頭文件
│
├─vin-video
│ dma_reg.c ;csi模塊dma操作函數(shù)
│ dma_reg.h ;csi模塊dma操作函數(shù)頭文件
│ dma_reg_i.h ;csi dma寄存器資源頭文件
│ vin_core.c ;vin video核心函數(shù)
│ vin_core.h ;vin video核心函數(shù)頭文件
│ vin_video.c ;vin video設(shè)備接口函數(shù)
│ vin_video.h ;vin video設(shè)備接口函數(shù)頭文件
├─vin-vipp
│ sunxi_scaler.c ;scaler 子設(shè)備操作函數(shù)集
│ sunxi_scaler.h ;caler 子設(shè)備操作函數(shù)頭文件
│ vipp_reg.c ;vipp操作函數(shù)集
│ vipp_reg.h ;vipp操作函數(shù)集頭文件
│ vipp_reg_i.h ;vipp操作函數(shù)集資源頭文件
2.3.5 linux4.9 VIN 框架
驅(qū)動(dòng)路徑位于linux-4.9/drivers/media/platform/sunxi-vin 下。
sunxi-vin:
│ vin.c ;v4l2驅(qū)動(dòng)實(shí)現(xiàn)主體(包含視頻接口和ISP部分)
│ vin.h ;v4l2驅(qū)動(dòng)頭文件
│ top_reg.c ;vin對(duì)各v4l2 subdev管理接口實(shí)現(xiàn)主體
│ top_reg.h ;管理接口頭文件
│ top_reg_i.h ;vin模塊接口層部分結(jié)構(gòu)體
├── modules
│ ├── actuator ;vcm driver
│ │ ├── actuator.c
│ │ ├── actuator.h
│ │ ├── dw9714_act.c
│ │ ├── Makefile
│ ├── flash ;閃光燈driver
│ │ ├── flash.c
│ │ └── flash.h
│ └── sensor ;sensor driver
│ ├── ar0144_mipi.c
│ ├── camera_cfg.h ;camera ioctl擴(kuò)展命令頭文件
│ ├── camera.h ;camera公用結(jié)構(gòu)體頭文件
│ ├── Makefile
│ ├── ov2775_mipi.c
│ ├── ov5640.c
│ ├── sensor-compat-ioctl32.c
│ ├── sensor_helper.c ;sensor公用操作接口函數(shù)文件
│ ├── sensor_helper.h
├── platform ;平臺(tái)相關(guān)的配置接口
├── utility
│ ├── bsp_common.c
│ ├── bsp_common.h
│ ├── cfg_op.c
│ ├── cfg_op.h
│ ├── config.c
│ ├── config.h
│ ├── sensor_info.c
│ ├── sensor_info.h
│ ├── vin_io.h
│ ├── vin_os.c
│ ├── vin_os.h
│ ├── vin_supply.c
│ └── vin_supply.h
├── vin-cci
│ ├── sunxi_cci.c
│ └── sunxi_cci.h
├── vin-csi
│ ├── parser_reg.c
│ ├── parser_reg.h
│ ├── parser_reg_i.h
│ ├── sunxi_csi.c
│ └── sunxi_csi.h
├── vin-isp
│ ├── sunxi_isp.c
│ └── sunxi_isp.h
├── vin-mipi
│ ├── sunxi_mipi.c
│ └── sunxi_mipi.h
├── vin-stat
│ ├── vin_h3a.c
│ ├── vin_h3a.h
│ ├── vin_ispstat.c
│ └── vin_ispstat.h
├── vin_test
├── vin-video
│ ├── vin_core.c
│ ├── vin_core.h
│ ├── vin_video.c
│ └── vin_video.h
└── vin-vipp
├── sunxi_scaler.c
├── sunxi_scaler.h
├── vipp_reg.c
├── vipp_reg.h
└── vipp_reg_i.h
2.3.6 linux5.4 VIN 框架
驅(qū)動(dòng)路徑位于linux-5.4/drivers/media/platform/sunxi-vin 下。
sunxi-vin:
├── Kconfig
├── Makefile
├── modules
│ ├── actuator ;vcm driver
│ │ ├── actuator.c
│ │ ├── actuator.h
│ │ ├── dw9714_act.c
│ │ ├── Makefile
│ ├── flash ;flash driver
│ │ ├── flash.c
│ │ └── flash.h
│ ├── sensor ;cmos sensor driver
│ │ ├── camera_cfg.h
│ │ ├── camera.h
│ │ ├── gc0310_mipi.c
│ │ ├── Makefile
│ │ ├── ov2710_mipi.c
│ │ ├── ov5640.c
│ │ ├── sensor-compat-ioctl32.c
│ │ ├── sensor_helper.c
│ │ ├── sensor_helper.h
│ ├── sensor-list
│ │ ├── sensor_list.c
│ │ └── sensor_list.h
│ └── sensor_power ;sensor上下電接口函數(shù)
│ ├── Makefile
│ ├── sensor_power.c
│ └── sensor_power.h
├── platform
├── top_reg.c
├── top_reg.h
├── top_reg_i.h
├── utility ;驅(qū)動(dòng)通用接口
│ ├── bsp_common.c
│ ├── bsp_common.h
│ ├── cfg_op.c
│ ├── cfg_op.h
│ ├── config.c
│ ├── config.h
│ ├── vin_io.h
│ ├── vin_os.c
│ ├── vin_os.h
│ ├── vin_supply.c
│ └── vin_supply.h
├── vin.c ;sunxi-vin驅(qū)動(dòng)注冊(cè)入口
├── vin-cci ;i2c操作相關(guān)接口
│ ├── bsp_cci.c
│ ├── bsp_cci.h
│ ├── cci_helper.c
│ ├── cci_helper.h
│ ├── Kconfig
│ ├── sunxi_cci.c
│ └── sunxi_cci.h
├── vin-csi ;csi操作相關(guān)接口
│ ├── sunxi_csi.c
│ └── sunxi_csi.h
├── vin.h
├── vin-isp ;isp驅(qū)動(dòng)
│ ├── sunxi_isp.c
│ └── sunxi_isp.h
├── vin-mipi ;mipi驅(qū)動(dòng)
│ ├── sunxi_mipi.c
│ └── sunxi_mipi.h
├── vin-stat
│ ├── vin_h3a.c
│ └── vin_h3a.h
├── vin-tdm
│ ├── vin_tdm.c
│ └── vin_tdm.h
├── vin-video ;video節(jié)點(diǎn)相關(guān)的接口定義
│ ├── vin_core.c
│ ├── vin_core.h
│ ├── vin_video.c
│ └── vin_video.h
└── vin-vipp
├── sunxi_scaler.c
├── sunxi_scaler.h
3 模塊開發(fā)
3.1 模塊體系結(jié)構(gòu)描述
3.1.1 VFE 框架
? 使用過(guò)程中可簡(jiǎn)單的看成是vfe 模塊+ device 模塊+af driver + flash 控制模塊的方式;
? vfe.c 是驅(qū)動(dòng)的主要功能實(shí)現(xiàn),包括注冊(cè)/注銷、參數(shù)讀取、與v4l2 上層接口、與各device 的下層接口、中斷處理、buffer 申請(qǐng)切換等;
? device 文件夾里面是各個(gè)sensor 的器件層實(shí)現(xiàn),一般包括上下電、初始化,各分辨率切換,yuv sensor 包括絕大部分的v4l2 定義的ioctrl 命令的實(shí)現(xiàn);而raw
sensor 的話大部分 ioctrl 命令在vfe 層調(diào)用isp 的庫(kù)實(shí)現(xiàn),少數(shù)如曝光/增益調(diào)節(jié)會(huì)透過(guò)vfe 層到實(shí)際器件層;
? actuator 文件夾內(nèi)是各種vcm 的驅(qū)動(dòng);
? flash_light 文件夾內(nèi)是閃光燈控制接口實(shí)現(xiàn);
? csi 和mipi_csi 為對(duì)csi 接口和mipi 接口的控制文件;
? lib 文件夾為isp 的庫(kù)文件;
? linux-3.0 前的版本相當(dāng)于vivi.c+csi bsp 層
? linux-3.4 版本支持isp 驅(qū)動(dòng)和雙CSI
? linux-3.10 版本將mipi/csi/isp 模塊化(由vfe.c 直接調(diào)用=>v4l2_subdev_ops), 支持device tree
![image-20221122095738625](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUUKATSDgAADF9fiPsYU443.png)
?
圖3-1: VFE
?
3.1.2 VIN 框架
? 使用過(guò)程中可簡(jiǎn)單的看成是vin 模塊+ device 模塊+af driver + flash 控制模塊的方式;
? vin.c 是驅(qū)動(dòng)的主要功能實(shí)現(xiàn),包括注冊(cè)/注銷、參數(shù)讀取、與v4l2 上層接口、與各device 的下層接口、中斷處理、buffer 申請(qǐng)切換等;
? modules/sensor 文件夾里面是各個(gè)sensor 的器件層實(shí)現(xiàn),一般包括上下電、初始化,各分辨率切換,yuv sensor 包括絕大部分的v4l2 定義的ioctrl 命令的實(shí)
現(xiàn);而raw sensor 的話大部分ioctrl 命令在vin 層調(diào)用isp 庫(kù)實(shí)現(xiàn),少數(shù)如曝光/增益調(diào)節(jié)會(huì)透過(guò)vin 層到實(shí)際器件層;
? modules/actuator 文件夾內(nèi)是各種vcm 的驅(qū)動(dòng);
? modules/flash 文件夾內(nèi)是閃光燈控制接口實(shí)現(xiàn);
? vin-csi 和vin-mipi 為對(duì)csi 接口和mipi 接口的控制文件;
? vin-isp 文件夾為isp 的庫(kù)操作文件;
? vin-video 文件夾內(nèi)主要是video 設(shè)備操作文件;
![image-20221122113602939](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUUOASlt7AABkD50jrco436.png)
?
圖3-2: VIN
?
3.1.3 Camera 通路框架
? VIN 支持靈活配置單/雙路輸入雙ISP 多通路輸出的規(guī)格
? 引入media 框架實(shí)現(xiàn)pipeline 管理
? 將libisp 移植到用戶空間解決GPL 問(wèn)題
? 將統(tǒng)計(jì)buffer 獨(dú)立為v4l2 subdev
? 將的scaler(vipp)模塊獨(dú)立為v4l2 subdev
? 將video buffer 修改為mplane 方式,使用戶層取圖更方便
? 采用v4l2-event 實(shí)現(xiàn)事件管理
? 采用v4l2-controls 新特性
![image-20221122113645959](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUUOAQlbvAABc5jZvEZM421.png)
?
圖3-3: camera Input
?
3.2 驅(qū)動(dòng)模塊實(shí)現(xiàn)
3.2.1 硬件部分
檢查硬件電源,gpio 是否和原理圖一致并且正確連接;檢查sys_config.fex 或者board.dts 是否正確配置,包括使用的電源名稱和電壓,詳見CSI 板級(jí)配置章節(jié)說(shuō)
明;如果是電源選擇有多個(gè)源頭的請(qǐng)確認(rèn)板子上的連接正確,比如0ohm 電阻是否正確的焊接為0ohm,NC 的電阻是否有正確斷開等等。帶補(bǔ)光燈的也需要檢查
燈和driver IC 和控制io 是否連好。
3.2.2 內(nèi)核device 模塊驅(qū)動(dòng)
一般調(diào)試新模組的話建議以sdk 中的某個(gè)現(xiàn)成的驅(qū)動(dòng)為基礎(chǔ)修改:YUV 的并口模組以R40 平臺(tái)(linux3.10) 的ov5640.c 為參考。
下面以ov5640.c 為例說(shuō)明調(diào)試新模組需要注意的兩點(diǎn):
添加Makefile
[linux-3.10/drivers/media/platform/sunxi-vfe/device/Makefile]
添加
obj-m + = ov5640.o (詳見1)
詳注:
1.具體取決于使用的模組,如果是新模組則將驅(qū)動(dòng)代碼放置在該device目錄下。
配置模組參數(shù)
配置參數(shù)在linux-3.10/drivers/media/platform/sunxi-vfe/device/ov5640.c 中,只需注意下面兩個(gè)參數(shù)。
#define SENSOR_NAME "ov5640" (詳見1)
#define I2C_ADDR 0x78 (詳見2)
詳注:
1.該參數(shù)為模組名,必須和sys_config.fex的csi0_dev0_mname或者board.dts的sensor0_mname保持一致。
2.I2C_ADDR可參考相應(yīng)模組的datasheet,sys_config.fex的csi0_dev0_twi_addr與此值保持一致。
3.2.2.1 驅(qū)動(dòng)宏定義
#define MCLK (24*1000*1000)
sensor 輸入時(shí)鐘頻率,可查看模組廠提供的sensor datasheet,datasheet 中會(huì)有類似inputclock frequency: 6~27 MHz 信息,這個(gè)信息說(shuō)明可提供給sensor 的
MCLK 可以在6 M 到27 M之間。其中MCLK 和使用的寄存器配置強(qiáng)相關(guān),在模組廠提供寄存器配置時(shí),可直接詢問(wèn)當(dāng)前配置使用的MCLK 頻率是多少。
#define VREF_POL V4L2_MBUS_VSYNC_ACTIVE_LOW #define HREF_POL V4L2_MBUS_HSYNC_ACTIVE_HIGH #define CLK_POL V4L2_MBUS_PCLK_SAMPLE_RISING
并口sensor 必須填寫,MIPI sensor 無(wú)需填寫,可在sensor 規(guī)格書找到,如下
![image-20221122115215017](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUUSAbZdgAABDLbMUgy4834.png)
?
圖3-4: timing
?
從上述的圖像可得到以下信息:
VSYNC 在低電平的時(shí)候,data pin 輸出有效數(shù)據(jù),所以VREF_POL 設(shè)置為V4L2_MBUS_VSYNC_ACTIVE_即低電平有效;
HREF 在高電平的時(shí)候,data pin 輸出有效數(shù)據(jù),所以HREF_POL 設(shè)置為V4L2_MBUS_HSYNC_ACTIVE_即高電平有效;
CLK_POL 則是表明SOC 是在sensor 輸出的pclk 上升沿采集data pin 的數(shù)據(jù)還是下降沿采集數(shù)據(jù),如果sensor 在pclk 上升沿改變data pin 的數(shù)據(jù),那么SOC
應(yīng)該在下降沿采集,CLK_POL 設(shè)置為V4L2_MBUS_PCLK_SAMPLE_FALLING;如果sensor在pclk 下降沿改變data pin 的數(shù)據(jù),那么SOC 應(yīng)該在上降沿采集,
CLK_POL 設(shè)置為V4L2_MBUS_PCLK_SAMPLE_RISING。
#define V4L2_IDENT_SENSOR 0x2770
一般填寫sensor ID,用于sensor 檢測(cè)。sensor ID 可在sensor 規(guī)格書的找到,如下
![image-20221122115536252](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUUSANMuoAAAb2G5LVS8547.png)
?
圖3-5: sensorid
?
#define I2C_ADDR 0x6c
sensor I2C 通訊地址,可在sensor 規(guī)格書找到,如下
![image-20221122115814628](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUUWAVJakAABD46zSyKs483.png)
?
圖3-6: sccbid
?
#define SENSOR_NAME OV5640
定義驅(qū)動(dòng)名字,與系統(tǒng)其他文件填寫的名字要一致,比如需要和sys_config.fex 中的sensorname 一致。
3.2.2.2 初始化代碼
static struct regval_list sensor_default_regs[] = {}; /* 填寫寄存器代碼的公共部分*/ static struct regval_list sensor_XXX_regs[] = {}; /* 填寫各模式的寄存器代碼,不同的模式可以是分辨率、幀率等*/
上述部分的寄存器配置,公共部分可以忽略,直接在模式代碼中配置sensor 即可,相應(yīng)的寄存器配置,可讓模組廠提供。
3.2.2.3 曝光增益接口函數(shù)
static int sensor_s_exp(struct v4l2_subdev *sd, unsigned int exp_val) /* 曝光函數(shù)*/ static int sensor_s_gain(struct v4l2_subdev *sd, unsigned int gain_val) /* 增益函數(shù)*/
AE 是同時(shí)控制曝光時(shí)間和增益的,所以需要在上面的函數(shù)中分別同時(shí)sensor 曝光和增益的寄存器。
![image-20221122174724278](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUUWAeifwAACXfwTJeXg255.png)
?
圖3-7: expgain
?
根據(jù)規(guī)格書中的寄存器說(shuō)明,在相應(yīng)的函數(shù)配置即可。若設(shè)置exp/gain 無(wú)效,可能的原因有:
? sensor 寄存器打開了AE;
? 設(shè)置值超出了有效范圍
具體可根據(jù)模組廠提供的配置設(shè)置,如若檢查之后設(shè)置仍失效,可與模組廠溝通,確認(rèn)配置是否正確。
3.2.2.4 上下電控制函數(shù)
static int sensor_power(struct v4l2_subdev *sd, int on)
控制sensor 上電、下電及進(jìn)出待機(jī)狀態(tài),操作步驟須與規(guī)格書描述相同,注意power down 和reset pin 的電平變化。
![image-20221122174813656](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUUaASjkZAAFOHZ8F2LY977.png)
?
圖3-8: powerup
?
驅(qū)動(dòng)中,按照規(guī)格書的上電時(shí)序進(jìn)行配置,而如果上電之后測(cè)量硬件并沒有相應(yīng)的電壓,這時(shí)候 檢查硬件和軟件配置是否一致。關(guān)于csi 電源的配置,操作流程可如下:
先通過(guò)原理圖確認(rèn)sensor 模組的各路電源是連接到axp 的哪個(gè)ldo;
查看sys_config.fex 的regulator 配置,在相應(yīng)的ldo 后增加相應(yīng)的字段,比如“csi-vdd”等;
在sys_config.fex 的csi 部分,sensor 部分的電源后的字段再填寫與上述一樣的字段即可;
根據(jù)sensor 規(guī)格書的要求,填寫相應(yīng)的電壓即可;
以上圖為例,確認(rèn)sensor 驅(qū)動(dòng)中的上電時(shí)序。
static int sensor_power(struct v4l2_subdev *sd, int on) { int ret; ret = 0; switch (on) { /* STBY_ON 和STBY_OFF 基本不使用,可忽略這兩個(gè)選項(xiàng)的配置*/ case STBY_ON: ... break; case STBY_OFF: ... break; /* 上電操作*/ case PWR_ON: sensor_print("PWR_ON!n"); cci_lock(sd); /* 將PWDN、RESET 引腳設(shè)置為輸出*/ vin_gpio_set_status(sd, PWDN, 1); vin_gpio_set_status(sd, RESET, 1); /* 按照上圖知道,上電前PWDN、RESET 信號(hào)為低,所以將其設(shè)置為低電平*/ vin_gpio_write(sd, PWDN, CSI_GPIO_LOW); vin_gpio_write(sd, RESET, CSI_GPIO_LOW); /* 延時(shí)*/ usleep_range(1000, 1200); /* CAMERAVDD 為SOC 中的供電電源,部分板子可以忽略該電源, * 因?yàn)橛行┌遄訒?huì)通過(guò)一個(gè)vcc-pe 給上拉電阻等供電,所以需要 * 使能該路電,有些是直接和iovdd 共用了,所以有部分會(huì)忽略該 * 路電源配置. */ vin_set_pmu_channel(sd, CAMERAVDD, ON); /* 將PWDN 設(shè)置為高電平*/ vin_gpio_write(sd, PWDN, CSI_GPIO_HIGH); /*AF上電*/ vin_set_pmu_channel(sd, AFVDD, ON); /* AVDD 上電*/ vin_set_pmu_channel(sd, AVDD, ON); /* 延時(shí),延時(shí)時(shí)長(zhǎng)為T1,T1 的大小在datasheet 的上電時(shí)序圖下面有標(biāo)注*/ usleep_range(1000, 1200); /* DOVDD 上電*/ vin_set_pmu_channel(sd, IOVDD, ON); /* 延時(shí),按照上電時(shí)序中的標(biāo)注的T2 時(shí)間延時(shí)*/ usleep_range(1000, 1200); /* DVDD 上電*/ vin_set_pmu_channel(sd, DVDD, ON); /* 延時(shí),按照上電時(shí)序中的標(biāo)注的T3 時(shí)間延時(shí)*/ usleep_range(1000, 1200); /* 將PWDN 設(shè)置為低電平*/ vin_gpio_write(sd, PWDN, CSI_GPIO_LOW); /* 設(shè)置MCLK 頻率并使能*/ vin_set_mclk_freq(sd, MCLK); vin_set_mclk(sd, ON); /* 延時(shí),按照上電時(shí)序中的標(biāo)注的T4 時(shí)間延時(shí)*/ usleep_range(1000, 1200); /* 將RESET 設(shè)置為高電平*/ vin_gpio_write(sd, RESET, CSI_GPIO_HIGH); /* 延時(shí),按照上電時(shí)序中的標(biāo)注的T6 時(shí)間延時(shí)*/ usleep_range(10000, 12000); cci_unlock(sd); break; /* 掉電操作*/ case PWR_OFF: sensor_print("PWR_OFF!n"); cci_lock(sd); /* 具體的掉電操作同樣的按照datasheet 的power off 操作即可*/ vin_gpio_write(sd, PWDN, CSI_GPIO_HIGH); vin_gpio_write(sd, RESET, CSI_GPIO_LOW); vin_set_mclk(sd, OFF); vin_set_pmu_channel(sd, AFVDD, OFF); vin_set_pmu_channel(sd, AVDD, OFF); vin_set_pmu_channel(sd, DVDD, OFF); vin_set_pmu_channel(sd, IOVDD, OFF); vin_set_pmu_channel(sd, CAMERAVDD, OFF); vin_gpio_set_status(sd, PWDN, 0); cci_unlock(sd); break; default: return -EINVAL; } return 0; }
3.2.2.5 檢測(cè)函數(shù)
static int sensor_detect(struct v4l2_subdev *sd)
在開機(jī)加載驅(qū)動(dòng)的時(shí)候,將會(huì)檢測(cè)sensor ID,用于測(cè)試I2C 通訊是否正常和sensor 識(shí)別。
#define V4L2_IDENT_SENSOR 0x7750 sensor_read(sd, 0x300A, &rdval); if (rdval != (V4L2_IDENT_SENSOR >> 8)) return -ENODEV; sensor_read(sd, 0x300B, &rdval); if (rdval != (V4L2_IDENT_SENSOR & 0xff)) return -ENODEV;
![image-20221122175111168](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUUeAReOOAAAzyzFhiw4192.png)
?
圖3-9: sensordetect
?
3.2.2.6 SENSOR 相關(guān)的IOCTL
static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
用于應(yīng)用層獲取曝光增益,及進(jìn)行與sensor 相關(guān)模塊的驅(qū)動(dòng)控制,如對(duì)焦,閃光等
case VIDIOC_VIN_SENSOR_EXP_GAIN:/*設(shè)置sensor的曝光增益*/ ret = sensor_s_exp_gain(sd, (struct sensor_exp_gain *)arg); break; case VIDIOC_VIN_SENSOR_CFG_REQ:/*獲取sensor驅(qū)動(dòng)的基礎(chǔ)配置信息*/ sensor_cfg_req(sd, (struct sensor_config *)arg); break; case VIDIOC_VIN_ACT_SET_CODE:/*設(shè)置對(duì)焦馬達(dá)配置參數(shù),在配置AF模塊時(shí),需要此ioctl*/ actuator_set_code(sd, (struct actuator_ctrl *)arg);
3.2.2.7 與CSI 的接口
static struct sensor_format_struct sensor_formats[] = {}; RAW sensor: .desc = "Raw RGB Bayer", .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, .regs = sensor_fmt_raw, .regs_size = ARRAY_SIZE(sensor_fmt_raw), .bpp = 1 YUV sensor: .desc = "YUYV 4:2:2", .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .regs = sensor_fmt_yuyv422_yuyv, .regs_size = ARRAY_SIZE(sensor_fmt_yuyv422_yuyv), .bpp = 2
其中,mbus_code 中BGGR 可以根據(jù)sensor raw data 輸出順序修改為GBRG/RGGB/-GRBG。若填錯(cuò), 會(huì)導(dǎo)致色彩偏紫紅和出現(xiàn)網(wǎng)格狀紋理。10_1X10 表示10 bit
并口輸出, 若是12 bit MIPI 輸出, 則改為12_12X1。其他情況類推。對(duì)于DVP YUV sensor, 需根據(jù)yuv 輸出順序選擇yuyv/vyuy/uyvy/yvyu 其中一種。
static int sensor_g_mbus_config(struct v4l2_subdev *sd,struct v4l2_mbus_config *cfg) DVP sensor: cfg->type = V4L2_MBUS_PARALLEL; cfg->flags = V4L2_MBUS_MASTER | VREF_POL | HREF_POL | CLK_POL; MIPI sensor: cfg->type = V4L2_MBUS_CSI2; cfg->flags = 0 | V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0;
其中,MIPI sensor 須根據(jù)實(shí)際使用的lane 數(shù),修改V4L2_MBUS_CSI2_X_LANE 中的X值。如果使用LVDS 接口,需要將cfg->type 配置為V4L2_MBUS_SUBLVDS。
3.2.2.8 分辨率配置
static struct sensor_win_size sensor_win_sizes[] = { { .width = VGA_WIDTH, .height = VGA_HEIGHT, .hoffset = 0, .voffset = 0, .hts = 928, .vts = 1720, .pclk = 48 * 1000 * 1000, .mipi_bps = 480 * 1000 * 1000, .fps_fixed = 30, .bin_factor = 1, .intg_min = 1 << 4, ? ?.intg_max = (1720) << 4, ? ?.gain_min = 1 << 4, ? ?.gain_max = 16 << 4, ? ?.regs = sensor_VGA_regs, ? ?.regs_size = ARRAY_SIZE(sensor_VGA_regs), ? ?.set_size = NULL, }, { ? ?/* 定義圖像輸出的大小*/ ? ?.width = VGA_WIDTH, ? ?.height = VGA_HEIGHT, ? ?/* 定義輸入ISP 的偏移量,用于截取所需的Size,丟棄不需要的部分圖像*/ ? ?.hoffset = 0, ? ?.voffset = 0, ? ?/* ? ?定義行長(zhǎng)(以pclk 為單位)、幀長(zhǎng)(以hts 為單位) 和像素時(shí)鐘頻率。hts 又稱line_length_pck,vts 又稱frame_length_lines,與寄存器的值要一致。pclk(pixel clock)的值由PLL 寄存器計(jì)算得出。 ? ?*/ ? ?.hts = 928, ? ?.vts = 1720, ? ?.pclk = 48 * 1000 * 1000, ? ?/* 定義MIPI 數(shù)據(jù)速率,MIPI sensor 必需,其他sensor 忽略*/ ? ?/* mipi_bps = hts * vts * fps * raw bit / lane num */ ? ?.mipi_bps = 480 * 1000 * 1000, ? ?/* 定義幀率,fps * hts * vts = pclk */ ? ?.fps_fixed = 30, ? ?/* ? ?定義曝光行數(shù)最小值和最大值,增益最小值和最大值,以16 為1 倍。最值的設(shè)置應(yīng)在sensor 規(guī)格和 ? ?曝光函數(shù)限定的范圍內(nèi),若超出會(huì)導(dǎo)致畫面異常。此外,若AE table 中的最值超出這里的限制,會(huì)使得 ? ?AE table 失效。 ? ?*/ ? ?.intg_min = 1 << 4, ? ?.intg_max = (1720) << 4, ? ?.gain_min = 1 << 4, ? ?.gain_max = 16 << 4, ? ?/* (必需)說(shuō)明這部分的配置對(duì)應(yīng)哪個(gè)寄存器初始化代碼*/ ? ?.regs = sensor_VGA_regs, ? ?.regs_size = ARRAY_SIZE(sensor_VGA_regs), ? ?}, };
根據(jù)應(yīng)用的需求,在這里配置驅(qū)動(dòng)能輸出的不同尺寸幀率組合,注意,一種分辨率、幀率配置為一個(gè)數(shù)組成員,不要混淆。
3.2.3 LVDS 接口須知
除了完成以上函數(shù)的實(shí)現(xiàn),LVDS Sensor 驅(qū)動(dòng)還需要完成combo 同步校驗(yàn)函數(shù)和combo 數(shù)據(jù)線映射函數(shù)。combo 校驗(yàn)碼可以在sensor 規(guī)格書獲取,combo 數(shù)
據(jù)線映射關(guān)系需要查看原理圖設(shè)計(jì)進(jìn)行配對(duì),可參考imx274_slvds.c 完成開發(fā)。
![image-20221122180028623](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUUeAUYLbAAF2ibPkYJw869.png)
?
圖3-10: SYNC_CODE
?
static void sensor_g_combo_sync_code(struct v4l2_subdev *sd, struct combo_sync_code *sync) { int i; for (i = 0; i < 12; i++) { ? ?sync->lane_sof[i].low_bit = 0x0000ab00; sync->lane_sof[i].high_bit = 0xFFFF0000; sync->lane_sol[i].low_bit = 0x00008000; sync->lane_sol[i].high_bit = 0xFFFF0000; sync->lane_eol[i].low_bit = 0x00009d00; sync->lane_eol[i].high_bit = 0xFFFF0000; sync->lane_eof[i].low_bit = 0x0000b600; sync->lane_eof[i].high_bit = 0xFFFF0000; } } static void sensor_g_combo_lane_map(struct v4l2_subdev *sd, struct combo_lane_map *map) { struct sensor_info *info = to_state(sd); if (info->isp_wdr_mode == ISP_DOL_WDR_MODE) { map->lvds_lane0 = LVDS_MAPPING_A_D0_TO_LANE0; map->lvds_lane1 = LVDS_MAPPING_A_D1_TO_LANE1; map->lvds_lane2 = LVDS_MAPPING_B_D2_TO_LANE2; map->lvds_lane3 = LVDS_MAPPING_B_D0_TO_LANE3; map->lvds_lane4 = LVDS_MAPPING_B_D3_TO_LANE4; map->lvds_lane5 = LVDS_MAPPING_C_D2_TO_LANE5; map->lvds_lane6 = LVDS_LANE6_NO_USE; map->lvds_lane7 = LVDS_LANE7_NO_USE; map->lvds_lane8 = LVDS_LANE8_NO_USE; map->lvds_lane9 = LVDS_LANE9_NO_USE; map->lvds_lane10 = LVDS_LANE10_NO_USE; map->lvds_lane11 = LVDS_LANE11_NO_USE; } else { map->lvds_lane0 = LVDS_MAPPING_A_D1_TO_LANE0; map->lvds_lane1 = LVDS_MAPPING_B_D2_TO_LANE1; map->lvds_lane2 = LVDS_MAPPING_B_D0_TO_LANE2; map->lvds_lane3 = LVDS_MAPPING_B_D3_TO_LANE3; map->lvds_lane4 = LVDS_LANE4_NO_USE; map->lvds_lane5 = LVDS_LANE5_NO_USE; map->lvds_lane6 = LVDS_LANE6_NO_USE; map->lvds_lane7 = LVDS_LANE7_NO_USE; map->lvds_lane8 = LVDS_LANE8_NO_USE; map->lvds_lane9 = LVDS_LANE9_NO_USE; map->lvds_lane10 = LVDS_LANE10_NO_USE; map->lvds_lane11 = LVDS_LANE11_NO_USE; } }
3.2.4 內(nèi)核代碼注意事項(xiàng)
驅(qū)動(dòng)中一般禁止使用mdelay 或者msleep 實(shí)現(xiàn)延時(shí),例如使用msleep 實(shí)現(xiàn)10~20ms的延時(shí),通常會(huì)因?yàn)橄到y(tǒng)調(diào)度而變成延時(shí)更長(zhǎng)的時(shí)間,這種做法精度較差。
所以如果需要使用ms 級(jí)別延時(shí),則使用usleep_range(a, b),比如原來(lái)mdelay(1)、mdelay(10) 可改為usleep_range(1000, 2000)、usleep_range(10000,
12000)。如果是長(zhǎng)達(dá)30ms 或以上的延時(shí)可選擇使用msleep();
中斷過(guò)程中不能使用msleep 和usleep_range,除了特殊情況必須加延時(shí)之外,mdelay 一般也不可使用。
4 模塊配置
4.1 Tina 配置
Tina 中主要是修改平臺(tái)的modules.mk 配置,modules.mk 主要完成兩個(gè)方面:
1.拷貝相關(guān)的ko 模塊到小機(jī)rootfs 中
2.rootfs 啟動(dòng)時(shí),按順序自動(dòng)加載相關(guān)的ko 模塊。
由于內(nèi)核框架的不一樣,需要區(qū)分vfe 和vin 進(jìn)行相應(yīng)的配置。
4.1.1 vfe 框架
modules.mk 配置路徑(以R40 平臺(tái)的為例):
target/allwinner/r40-common/modules.mk
其中的r40-common 為R40 平臺(tái)共有的配置文件目錄,相應(yīng)的修改對(duì)應(yīng)平臺(tái)的modules.mk即可。
define KernelPackage/sunxi-vfe SUBMENU:=$(VIDEO_MENU) TITLE:=sunxi-vfe support FILES:=$(LINUX_DIR)/drivers/media/v4l2-core/videobuf2-core.ko FILES+=$(LINUX_DIR)/drivers/media/v4l2-core/videobuf2-memops.ko FILES+=$(LINUX_DIR)/drivers/media/v4l2-core/videobuf2-dma-contig.ko FILES+=$(LINUX_DIR)/drivers/media/v4l2-core/videobuf2-v4l2.ko FILES+=$(LINUX_DIR)/drivers/media/platform/sunxi-vfe/vfe_io.ko FILES+=$(LINUX_DIR)/drivers/media/platform/sunxi-vfe/device/ov5640.ko (詳見1) FILES+=$(LINUX_DIR)/drivers/media/platform/sunxi-vfe/vfe_v4l2.ko AUTOLOAD:=$(call AutoLoad,90,videobuf2-core videobuf2-memops videobuf2-dma-contig videobuf2-v4l2 vfe_io ov5640 vfe_v4l2) (詳見2) endef define KernelPackage/sunxi-vfe/description Kernel modules for sunxi-vfe support endef 詳注: 1.由具體使用的模組確定,需要確定內(nèi)核路徑中這個(gè)驅(qū)動(dòng)是否被編譯出來(lái)。 2.AUTOLOAD為小機(jī)rootfs掛載后自動(dòng)加載的機(jī)制,vfe_v4l2.ko必須在最后加載,其它ko可以按照上面的相對(duì)順序加載。必須修改相應(yīng)的sensor ko才會(huì)開啟自加載。
4.1.2 vin 框架
modules.mk 配置路徑(以R30 平臺(tái)的為例):
target/allwinner/r30-common/modules.mk
其中的r30-common 為R30 平臺(tái)共有的配置文件目錄,相應(yīng)的修改對(duì)應(yīng)平臺(tái)的modules.mk即可。
define KernelPackage/sunxi-vin SUBMENU:=$(VIDEO_MENU) TITLE:=sunxi-vin support FILES:=$(LINUX_DIR)/drivers/media/v4l2-core/videobuf2-core.ko FILES+=$(LINUX_DIR)/drivers/media/v4l2-core/videobuf2-memops.ko FILES+=$(LINUX_DIR)/drivers/media/v4l2-core/videobuf2-dma-contig.ko FILES+=$(LINUX_DIR)/drivers/media/v4l2-core/videobuf2-v4l2.ko FILES+=$(LINUX_DIR)/drivers/media/platform/sunxi-vin/vin_io.ko /*對(duì)焦馬達(dá)驅(qū)動(dòng)加載*/ FILES+=$(LINUX_DIR)/drivers/media/platform/sunxi-vin/modules/actuator/actuator.ko FILES+=$(LINUX_DIR)/drivers/media/platform/sunxi-vin/modules/actuator/dw9714_act.ko(詳見 3) FILES+=$(LINUX_DIR)/drivers/media/platform/sunxi-vin/modules/sensor/ov5640.ko (詳見1) FILES+=$(LINUX_DIR)/drivers/media/platform/sunxi-vin/vin_v4l2.ko AUTOLOAD:=$(call AutoLoad,90,videobuf2-core videobuf2-memops videobuf2-dma-contig videobuf2-v4l2 vin_io actuator dw9714_act ov5640 vin_v4l2) (詳見2) endef define KernelPackage/sunxi-vin/description Kernel modules for sunxi-vin support endef 詳注: 1.由具體使用的模組確定,需要確定內(nèi)核路徑中這個(gè)驅(qū)動(dòng)是否被編譯出來(lái)。 2.AUTOLOAD為小機(jī)rootfs掛載后自動(dòng)加載的機(jī)制,vin_v4l2.ko必須在最后加載,其它ko可以按照上面的相對(duì)順序加載。 3.對(duì)焦馬達(dá)驅(qū)動(dòng)加載順序必須在sensor驅(qū)動(dòng)加載之前,具體驅(qū)動(dòng)型號(hào)根據(jù)模組規(guī)格書進(jìn)行確認(rèn)。
V 系列平臺(tái)在完成modules.mk 配置后,還需要完成.ko 掛載腳本S00mpp 的配置,S00mpp
配置路徑(以V853 平臺(tái)為例):
target/allwinner/v853-perf1/busybox-init-base-files/etc/init.d
其中的v853-perf1 為V 系列平臺(tái)共有的配置文件目錄,相應(yīng)的修改對(duì)應(yīng)平臺(tái)的S00mpp 即可。
#!/bin/sh # # Load mpp modules.... # MODULES_DIR="/lib/modules/`uname -r`" start() { printf "Load mpp modulesn" insmod $MODULES_DIR/videobuf2-core.ko insmod $MODULES_DIR/videobuf2-memops.ko insmod $MODULES_DIR/videobuf2-dma-contig.ko insmod $MODULES_DIR/videobuf2-v4l2.ko insmod $MODULES_DIR/vin_io.ko # insmod $MODULES_DIR/sensor_power.ko insmod $MODULES_DIR/gc4663_mipi.ko insmod $MODULES_DIR/vin_v4l2.ko insmod $MODULES_DIR/sunxi_aio.ko insmod $MODULES_DIR/sunxi_eise.ko # insmod $MODULES_DIR/vipcore.ko } stop() { printf "Unload mpp modulesn" # rmmod $MODULES_DIR/vipcore.ko rmmod $MODULES_DIR/sunxi_eise.ko rmmod $MODULES_DIR/sunxi_aio.ko rmmod $MODULES_DIR/vin_v4l2.ko rmmod $MODULES_DIR/gc4663_mipi.ko # rmmod $MODULES_DIR/sensor_power.ko rmmod $MODULES_DIR/vin_io.ko rmmod $MODULES_DIR/videobuf2-v4l2.ko rmmod $MODULES_DIR/videobuf2-dma-contig.ko rmmod $MODULES_DIR/videobuf2-memops.ko rmmod $MODULES_DIR/videobuf2-core.ko } case "$1" in start) start ;; stop) stop ;; restart|reload) stop start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 esac exit $?
4.2 CSI 板級(jí)配置
Tina 平臺(tái)根據(jù)不同的平臺(tái)差異分別使用sys_config.fex 或board.dst 配置camera CSI,具體的對(duì)應(yīng)關(guān)系如下表,下面將分別介紹sys_config.fex 和board.dts 中關(guān)
于camera CSI 配置。
?
表4-1: 平臺(tái)配置方式對(duì)應(yīng)表
?
平臺(tái) | CSI 使用的配置方式 |
---|---|
F35 | sys_config.fex |
R16 | sys_config.fex |
R18 | sys_config.fex |
R30 | sys_config.fex |
R40 | sys_config.fex |
R311 | sys_config.fex |
MR133 | sys_config.fex |
R818 | board.dts |
MR813 | board.dts |
R528 | board.dts |
V536 | sys_config.fex |
V533 | board.dts |
V831 | board.dts |
V833 | board.dts |
V851 | board.dts |
V853 | board.dts |
4.2.1 sys_config.fex 平臺(tái)配置
sys_config.fex 配置camera CSI,CSI sys_config.fex 部分對(duì)應(yīng)的字段為:[csi0]。通過(guò)舉例R40 平臺(tái)說(shuō)明在實(shí)際使用中應(yīng)該如何配置:假如使用一個(gè)并口camera
模組需要配置[csi0] 的公用部分和[csi0] 的vip_dev0_(x) 部分,另外[csi0] 中vip_used 設(shè)置為1,[csi1]中vip_used 設(shè)置為0。
下面給出一個(gè)ov5640 模組的參考配置:其中[csi0] 為并口的配置。具體填寫方法請(qǐng)參照以下說(shuō)明:
/* 下面部分的CSI配置適用4.9內(nèi)核之前的平臺(tái)*/ ;-------------------------------------------------------------------------------- ;csi (COMS Sensor Interface) configuration ;csi(x)_dev(x)_used: 0:disable 1:enable ;csi(x)_dev(x)_isp_used 0:not use isp 1:use isp ;csi(x)_dev(x)_fmt: 0:yuv 1:bayer raw rgb ;csi(x)_dev(x)_stby_mode: 0:not shut down power at standby 1:shut down power at standby ;csi(x)_dev(x)_vflip: flip in vertical direction 0:disable 1:enable ;csi(x)_dev(x)_hflip: flip in horizontal direction 0:disable 1:enable ;csi(x)_dev(x)_iovdd: camera module io power handle string, pmu power supply ;csi(x)_dev(x)_iovdd_vol: camera module io power voltage, pmu power supply ;csi(x)_dev(x)_avdd: camera module analog power handle string, pmu power supply ;csi(x)_dev(x)_avdd_vol: camera module analog power voltage, pmu power supply ;csi(x)_dev(x)_dvdd: camera module core power handle string, pmu power supply ;csi(x)_dev(x)_dvdd_vol: camera module core power voltage, pmu power supply ;csi(x)_dev(x)_afvdd: camera module vcm power handle string, pmu power supply ;csi(x)_dev(x)_afvdd_vol: camera module vcm power voltage, pmu power supply ;fill voltage in uV, e.g. iovdd = 2.8V, csix_iovdd_vol = 2800000 ;fill handle string as below: ;axp22_eldo3 ;axp22_dldo4 ;axp22_eldo2 ;fill handle string "" when not using any pmu power supply ;-------------------------------------------------------------------------------- [csi0] csi0_used = 1 csi0_sensor_list = 0 csi0_pck = port:PE00<2> csi0_mck = port:PE01<2> csi0_hsync = port:PE02<2> csi0_vsync = port:PE03<2> csi0_d0 = port:PE04<2> csi0_d1 = port:PE05<2> csi0_d2 = port:PE06<2> csi0_d3 = port:PE07<2> csi0_d4 = port:PE08<2> csi0_d5 = port:PE09<2> csi0_d6 = port:PE10<2> csi0_d7 = port:PE11<2> csi0_sck = port:PE12<2> csi0_sda = port:PE13<2> [csi0/csi0_dev0] csi0_dev0_used = 1 csi0_dev0_mname = "ov5640" ;必須和sensor驅(qū)動(dòng)中的SENSOR_NAME一致 csi0_dev0_twi_addr = 0x78 ;請(qǐng)參考實(shí)際模組的8bit ID填寫 csi0_dev0_twi_id = 2 csi0_dev0_pos = "rear" csi0_dev0_isp_used = 0 ;YUV格式填0,RAW格式填1 csi0_dev0_fmt = 0 ;YUV格式填0,RAW格式填1 csi0_dev0_stby_mode = 0 csi0_dev0_vflip = 0 csi0_dev0_hflip = 0 csi0_dev0_iovdd = "csi-iovcc" ;電源請(qǐng)參考實(shí)際原理圖填寫,同時(shí)參考 sys_config.fex 的regulator 配置,確認(rèn)該字段有效 csi0_dev0_iovdd_vol = 2800000 ;電壓值參考datasheet csi0_dev0_avdd = "csi-avdd" ;電源請(qǐng)參考實(shí)際原理圖填寫,同時(shí)參考 sys_config.fex 的regulator 配置,確認(rèn)該字段有效 csi0_dev0_avdd_vol = 2800000 ;電壓值參考datasheet csi0_dev0_dvdd = "csi-dvdd" ;電源請(qǐng)參考實(shí)際原理圖填寫,同時(shí)參考 sys_config.fex 的regulator 配置,確認(rèn)該字段有效 csi0_dev0_dvdd_vol = 1500000 ;電壓值參考datasheet csi0_dev0_afvdd = "csi-afvcc" ;電源請(qǐng)參考實(shí)際原理圖填寫,同時(shí)參考 sys_config.fex 的regulator 配置,確認(rèn)該字段有效 csi0_dev0_afvdd_vol = 2800000 ;電壓值參考datasheet csi0_dev0_power_en = csi0_dev0_reset = port:PE14<1><0><1><0> ;io選取參照實(shí)際原理圖 csi0_dev0_pwdn = port:PE15<1><0><1><0> ;io選取參照實(shí)際原理圖 csi0_dev0_flash_used = 0 csi0_dev0_flash_type = 2 csi0_dev0_flash_en = csi0_dev0_flash_mode = csi0_dev0_flvdd = "" csi0_dev0_flvdd_vol = csi0_dev0_af_pwdn = csi0_dev0_act_used = 0 csi0_dev0_act_name = "ad5820_act" csi0_dev0_act_slave = 0x18 /* 下面部分的CSI配置適用4.9內(nèi)核平臺(tái)*/ ;-------------------------------------------------------------------------------- ;csi (COMS Sensor Interface) configuration ;csi(x)_dev(x)_used: 0:disable 1:enable ;csi(x)_dev(x)_isp_used 0:not use isp 1:use isp ;csi(x)_dev(x)_fmt: 0:yuv 1:bayer raw rgb ;csi(x)_dev(x)_stby_mode: 0:not shut down power at standby 1:shut down power at standby ;csi(x)_dev(x)_vflip: flip in vertical direction 0:disable 1:enable ;csi(x)_dev(x)_hflip: flip in horizontal direction 0:disable 1:enable ;csi(x)_dev(x)_iovdd: camera module io power handle string, pmu power supply ;csi(x)_dev(x)_iovdd_vol: camera module io power voltage, pmu power supply ;csi(x)_dev(x)_avdd: camera module analog power handle string, pmu power supply ;csi(x)_dev(x)_avdd_vol: camera module analog power voltage, pmu power supply ;csi(x)_dev(x)_dvdd: camera module core power handle string, pmu power supply ;csi(x)_dev(x)_dvdd_vol: camera module core power voltage, pmu power supply ;csi(x)_dev(x)_afvdd: camera module vcm power handle string, pmu power supply ;csi(x)_dev(x)_afvdd_vol: camera module vcm power voltage, pmu power supply ;fill voltage in uV, e.g. iovdd = 2.8V, csix_iovdd_vol = 2800000 ;fill handle string as below: ;axp22_eldo3 ;axp22_dldo4 ;axp22_eldo2 ;fill handle string "" when not using any pmu power supply ;-------------------------------------------------------------------------------- [vind0] vind0_used = 1 [vind0/csi_cci0] csi_cci0_used = 1 ;配置是否使用CCI,如果使用CCI,需要使能該配置并配置下面的CCI引腳 csi_cci0_sck = port:PE01<2> csi_cci0_sda = port:PE02<2> [vind0/flash0] flash0_used = 0 flash0_type = 2 flash0_en = flash0_mode = flash0_flvdd = "" flash0_flvdd_vol = [vind0/actuator0] actuator0_used = 0 actuator0_name = "ad5820_act" actuator0_slave = 0x18 actuator0_af_pwdn = actuator0_afvdd = "afvcc-csi" actuator0_afvdd_vol = 2800000 [vind0/sensor0] sensor0_used = 0 sensor0_mname = "gc8034_mipi" sensor0_twi_cci_id = 0 sensor0_twi_addr = 0x6e sensor0_pos = "rear" sensor0_isp_used = 1 sensor0_fmt = 1 sensor0_stby_mode = 0 sensor0_vflip = 0 sensor0_hflip = 0 sensor0_cameravdd = "" sensor0_cameravdd_vol = 3300000 sensor0_iovdd = "iovdd-csi" sensor0_iovdd_vol = 1800000 sensor0_avdd = "avdd-csi-f" sensor0_avdd_vol = 2800000 sensor0_dvdd = "dvdd-csi" sensor0_dvdd_vol = 1200000 sensor0_power_en = sensor0_reset = port:PE06<0><0><1><0> sensor0_pwdn = port:PE05<0><0><1><0> [vind0/sensor1] sensor1_used = 1 sensor1_mname = "gc8034_mipi" ;必須要和驅(qū)動(dòng)的SENSOR_NAME 一致 sensor1_twi_cci_id = 0 ;配置使用的TWI id,如果使用TWI,則不使用CCI sensor1_twi_addr = 0x6e ;配置sensor的i2c地址 sensor1_pos = "front" sensor1_isp_used = 1 ;配置是否使用isp sensor1_fmt = 1 sensor1_stby_mode = 0 sensor1_vflip = 0 sensor1_hflip = 0 sensor1_cameravdd = "" sensor1_cameravdd_vol = 3300000 sensor1_iovdd = "iovdd-csi" sensor1_iovdd_vol = 1800000 sensor1_avdd = "avdd-csi-f" sensor1_avdd_vol = 2800000 sensor1_dvdd = "dvdd-csi" sensor1_dvdd_vol = 1200000 sensor1_power_en = sensor1_reset = port:PE06<0><0><1><0> sensor1_pwdn = port:PE05<0><0><1><0> [vind0/vinc0] ;配置video0 的數(shù)據(jù)鏈路 vinc0_used = 1 vinc0_csi_sel = 0 vinc0_mipi_sel = 0 vinc0_isp_sel = 0 vinc0_rear_sensor_sel = 1 ;配置使用sensor1 輸出圖像數(shù)據(jù)到video0 vinc0_front_sensor_sel = 1 ;配置使用sensor1 輸出圖像數(shù)據(jù)到video0 vinc0_sensor_list = 0 [vind0/vinc1] vinc1_used = 0 vinc1_csi_sel = 0 vinc1_mipi_sel = 0 vinc1_isp_sel = 0 vinc1_rear_sensor_sel = 1 vinc1_front_sensor_sel = 1 vinc1_sensor_list = 0
關(guān)于電源的配置,根據(jù)板子的原理圖,了解需要sensor 驅(qū)動(dòng)配置哪幾路電,然后在sys_config.fex中進(jìn)行配置:比如說(shuō)sensor0 有個(gè)“CSI-IOVCC” 連接到AXP
的“LDO4”,那么,在sys_config.fex 中搜索LDO4 ,然后在其后面增加“csi-iovcc” ,這樣,在sensor 端就可以使用該標(biāo)號(hào)配置sensor0_iovdd。
regulator14 = "pmu1736_bldo2 none csi-iovdd" sensor0_iovdd = "csi-iovdd"
同時(shí)關(guān)于mr133/R311 平臺(tái),sys_config.fex 中的vinc0_rear_sensor_sel 和vinc0_front_sensor_sel
配置決定著使用哪路sensor 輸入數(shù)據(jù),該配置與硬件連接相關(guān),可參考本文檔最后的其他注意事項(xiàng)章節(jié)。
4.2.2 board.dts 平臺(tái)配置
當(dāng)前MR813/R818/R528 平臺(tái)的攝像頭配置不再使用sys_config.fex 而使用board.dts,文件存放在tina/device/config/chips/mr813(R818、R528)/configs/
< 方案> 目錄下,攝像頭相關(guān)的配置如下:
vind0:vind@0 { vind0_clk = <336000000>; vind0_isp = <327000000>; status = "okay"; actuator0:actuator@0 { device_type = "actuator0"; actuator0_name = "ad5820_act";/*必須要和驅(qū)動(dòng)的SUNXI_ACT_NAME一致*/ actuator0_slave = <0x18>;/*必須和驅(qū)動(dòng)的SUNXI_ACT_ID一致*/ actuator0_af_pwdn = <>; actuator0_afvdd = "afvcc-csi"; actuator0_afvdd_vol = <2800000>;/*af模塊的配電不在此處,在sensor配置中*/ status = "disabled";/*使能開關(guān),當(dāng)使用AF功能時(shí),status = "okay"*/ }; flash0:flash@0 { device_type = "flash0"; flash0_type = <2>; flash0_en = <>; flash0_mode = <>; flash0_flvdd = ""; flash0_flvdd_vol = <>; device_id = <0>; status = "disabled"; }; sensor0:sensor@0 { device_type = "sensor0"; sensor0_mname = "imx278_mipi"; /* 必須要和驅(qū)動(dòng)的 SENSOR_NAME 一致 */ sensor0_twi_cci_id = <2>; sensor0_twi_addr = <0x20>; sensor0_mclk_id = <0>; sensor0_pos = "rear"; sensor0_isp_used = <1>; /* R528 沒有isp,該項(xiàng)需要配置為0 */ sensor0_fmt = <1>; sensor0_stby_mode = <0>; sensor0_vflip = <0>; sensor0_hflip = <0>; /* sensor iovdd 連接的 ldo,根據(jù)硬件原理圖的連接, * 確認(rèn)是連接到 axp 哪個(gè) ldo,假設(shè) iovdd 連接到 aldo3, * 則 sensor0_iovdd-supply = ,其他同理。 */ sensor0_iovdd-supply = ; sensor0_iovdd_vol = <1800000>; sensor0_avdd-supply = ; sensor0_avdd_vol = <2800000>; sensor0_dvdd-supply = ; sensor0_afvdd-supply = ;/*根據(jù)硬件原理圖,確定配的哪路電*/ sensor0_afvdd_vol = <2800000>;/*根據(jù)硬件原理圖,確認(rèn)工作電壓*/ sensor0_dvdd_vol = <1200000>; sensor0_power_en = <>; /* 根據(jù)板子實(shí)際連接,修改 reset、pwdn 的引腳即可 */ /* GPIO 信息配置:pio 端口 組內(nèi)序號(hào) 功能分配 內(nèi)部電阻狀態(tài) 驅(qū)動(dòng)能力 輸出電平狀態(tài) */ sensor0_reset = <&pio PE 9 1 0 1 0>; sensor0_pwdn = <&pio PE 8 1 0 1 0>; status = "okay"; }; sensor1:sensor@1 { device_type = "sensor1"; sensor1_mname = "imx386_mipi"; sensor1_twi_cci_id = <3>; sensor1_twi_addr = <0x20>; sensor1_mclk_id = <1>; sensor1_pos = "front"; sensor1_isp_used = <1>; sensor1_fmt = <1>; sensor1_stby_mode = <0>; sensor1_vflip = <0>; sensor1_hflip = <0>; sensor1_iovdd-supply = ; sensor1_iovdd_vol = <1800000>; sensor1_avdd-supply = ; sensor1_avdd_vol = <2800000>; sensor1_dvdd-supply = ; sensor1_dvdd_vol = <1200000>; sensor0_power_en = <>; sensor1_reset = <&pio PE 7 1 0 1 0>; sensor1_pwdn = <&pio PE 6 1 0 1 0>; status = "okay"; }; /* 一個(gè) vinc 代表一個(gè) /dev/video 設(shè)備 */ vinc0:vinc@0 { vinc0_csi_sel = <0>; /* 代表選擇的 csi,MR813/R818 有兩個(gè) csi 接口 */ vinc0_mipi_sel = <0>; /* 代表選擇的 mipi 接口,MR813/R818 有兩個(gè) mipi 接口 */ vinc0_isp_sel = <0>; vinc0_isp_tx_ch = <0>; /* 表示 ISP 的通道數(shù),一般配置為 0 */ vinc0_tdm_rx_sel = <0>; /* 與 isp_sel 保持一致即可 */ vinc0_rear_sensor_sel = <0>; /* 該 video 可以選擇從哪個(gè) sensor 輸入圖像數(shù)據(jù) */ vinc0_front_sensor_sel = <1>; vinc0_sensor_list = <0>; status = "okay"; }; vinc1:vinc@1 { vinc1_csi_sel = <0>; vinc1_mipi_sel = <0>; /* R528沒有mipi,該項(xiàng)配置為0xff */ vinc1_isp_sel = <0>; /* R528沒有isp,該項(xiàng)配置為0 */ vinc1_isp_tx_ch = <0>; /* R528沒有isp,該項(xiàng)配置為0 */ vinc1_tdm_rx_sel = <0>; /* R528沒有isp,該項(xiàng)配置為0xff */ vinc1_rear_sensor_sel = <0>; vinc1_front_sensor_sel = <1>; vinc1_sensor_list = <0>; status = "okay"; }; vinc2:vinc@2 { vinc2_csi_sel = <1>; vinc2_mipi_sel = <1>; vinc2_isp_sel = <1>; vinc2_isp_tx_ch = <0>; vinc2_tdm_rx_sel = <1>; vinc2_rear_sensor_sel = <1>; vinc2_front_sensor_sel = <1>; vinc2_sensor_list = <0>; status = "okay"; }; vinc3:vinc@3 { vinc3_csi_sel = <1>; vinc3_mipi_sel = <1>; vinc3_isp_sel = <1>; vinc3_isp_tx_ch = <0>; vinc3_tdm_rx_sel = <1>; vinc3_rear_sensor_sel = <1>; vinc3_front_sensor_sel = <1>; vinc3_sensor_list = <0>; status = "okay"; }; }; /* 以下將配置兩路 sensor 輸入,產(chǎn)生 4 個(gè) video 節(jié)點(diǎn),內(nèi)核配置 CONFIG_SUPPORT_ISP_TDM=n,此時(shí) * 不同 sensor 輸出的節(jié)點(diǎn)不能同時(shí)使用,比如以下配置的 video0 不可以和 video2 video3 同時(shí)使用 */ vinc0:vinc@0 { vinc0_csi_sel = <0>; vinc0_mipi_sel = <0>; vinc0_isp_sel = <0>; vinc0_isp_tx_ch = <0>; vinc0_tdm_rx_sel = <0>; vinc0_rear_sensor_sel = <0>; vinc0_front_sensor_sel = <0>; vinc0_sensor_list = <0>; status = "okay"; }; vinc1:vinc@1 { vinc1_csi_sel = <0>; vinc1_mipi_sel = <0>; vinc1_isp_sel = <0>; vinc1_isp_tx_ch = <0>; vinc1_tdm_rx_sel = <0>; vinc1_rear_sensor_sel = <0>; vinc1_front_sensor_sel = <1>; vinc1_sensor_list = <0>; status = "okay"; }; vinc2:vinc@2 { vinc2_csi_sel = <1>; vinc2_mipi_sel = <1>; vinc2_isp_sel = <0>; vinc2_isp_tx_ch = <0>; vinc2_tdm_rx_sel = <0>; vinc2_rear_sensor_sel = <1>; vinc2_front_sensor_sel = <1>; vinc2_sensor_list = <0>; status = "okay"; }; vinc3:vinc@3 { vinc3_csi_sel = <1>; vinc3_mipi_sel = <1>; vinc3_isp_sel = <0>; vinc3_isp_tx_ch = <0>; vinc3_tdm_rx_sel = <0>; vinc3_rear_sensor_sel = <1>; vinc3_front_sensor_sel = <1>; vinc3_sensor_list = <0>; status = "okay"; }; /* 以下配置將可以從兩路 sensor 同時(shí)輸入,內(nèi)核配置 CONFIG_SUPPORT_ISP_TDM=y,但是有個(gè)限制, * 只能先運(yùn)行 video0,然后才可以運(yùn)行 video2,關(guān)閉的時(shí)候也是如此,先關(guān) video2,再關(guān) video0 */ vinc0:vinc@0 { vinc0_csi_sel = <0>; vinc0_mipi_sel = <0>; vinc0_isp_sel = <0>; vinc0_isp_tx_ch = <0>; vinc0_tdm_rx_sel = <0>; vinc0_rear_sensor_sel = <0>; vinc0_front_sensor_sel = <0>; vinc0_sensor_list = <0>; status = "okay"; }; vinc1:vinc@1 { vinc1_csi_sel = <0>; vinc1_mipi_sel = <0>; vinc1_isp_sel = <0>; vinc1_isp_tx_ch = <0>; vinc1_tdm_rx_sel = <0>; vinc1_rear_sensor_sel = <0>; vinc1_front_sensor_sel = <1>; vinc1_sensor_list = <0>; status = "okay"; }; vinc2:vinc@2 { vinc2_csi_sel = <1>; vinc2_mipi_sel = <1>; vinc2_isp_sel = <1>; vinc2_isp_tx_ch = <0>; vinc2_tdm_rx_sel = <1>; vinc2_rear_sensor_sel = <1>; vinc2_front_sensor_sel = <1>; vinc2_sensor_list = <0>; status = "okay"; }; vinc3:vinc@3 { vinc3_csi_sel = <1>; vinc3_mipi_sel = <1>; vinc3_isp_sel = <1>; vinc3_isp_tx_ch = <0>; vinc3_tdm_rx_sel = <1>; vinc3_rear_sensor_sel = <1>; vinc3_front_sensor_sel = <1>; vinc3_sensor_list = <0>; status = "okay"; };
修改該文件之后,需要重新編譯固件再打包,才會(huì)更新到dts。同時(shí),如果需要使用雙攝,雙攝分別使用到兩個(gè)ISP,那么內(nèi)核需要選上SUPPORT_ISP_TDM 配置。
4.3 menuconfig 配置說(shuō)明
在命令行進(jìn)入Tina 根目錄,執(zhí)行命令進(jìn)入配置主界面:
source build/envsetup.sh (詳見1) lunch 方案編號(hào)(詳見2) make menuconfig (詳見3) 詳注: 1.加載環(huán)境變量及tina提供的命令; 2.輸入編號(hào),選擇方案; 3.進(jìn)入配置主界面(對(duì)一個(gè)shell而言,前兩個(gè)命令只需要執(zhí)行一次)
make menuconfig 配置路徑:
Kernel modules └─>Video Support └─>kmod-sunxi-vfe(vfe框架的csi camera) (詳見1) └─>kmod-sunxi-vin(vin框架的csi camera) (詳見2) └─>kmod-sunxi-uvc(uvc camera) (詳見3) 詳注: 1.平臺(tái)使用vfe框架的csi camera選擇該驅(qū)動(dòng); 2.平臺(tái)使用vin框架的csi camera選擇該驅(qū)動(dòng);(該項(xiàng)與vfe框架,在同一個(gè)平臺(tái)只會(huì)出現(xiàn)其中一個(gè)) 3.usb camera選擇該驅(qū)動(dòng);
在完成sensor 驅(qū)動(dòng)編寫,modules.mk 和板級(jí)配置后,通過(guò)make menuconfig 選上相應(yīng)的驅(qū)動(dòng),camera 即可正常使用。下面以R40 平臺(tái)介紹。首先,選擇
Kernel modules 選項(xiàng)進(jìn)入下一級(jí)配置,如下圖所示:
![image-20221123105646196](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUUiAN3rGAAB3apNTwHQ848.png)
?
圖4-1: menuconfig
?
然后,選擇Video Support 選項(xiàng),進(jìn)入下一級(jí)配置,如下圖所示:
![image-20221123105728564](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUUiASbiMAAB3GXxPjAs891.png)
?
圖4-2: video
?
最后,選擇kmod-sunxi-vfe 選項(xiàng),可選擇<*> 表示編譯包含到固件,也可以選擇表示僅編譯不包含在固件。如下圖所示:
![image-20221123105750877](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUUmAcJEJAACAi4bCyjw163.png)
?
圖4-3: sunxi
?
4.4 如何增加ISP 效果配置
在完成ISP 調(diào)試之后,將會(huì)從ISP 調(diào)試工程師中得到相應(yīng)的頭文件配置,添加操作如下:
4.4.1 VFE 框架
將頭文件添加到驅(qū)動(dòng)的sunxi-vfe/isp_cfg/SENSOR_H 目錄下;
在驅(qū)動(dòng)sunxi-vfe/isp_cfg 目錄下,有個(gè)isp_cfg.c 文件,這文件中有個(gè)isp_cfg_array 數(shù)組,在sensor 的ISP 配置文件最下面也有個(gè)相應(yīng)的結(jié)構(gòu)體,在
isp_cfg_array 數(shù)組中按照數(shù)組的結(jié)構(gòu),增加sensor 的name 和結(jié)構(gòu)體即可,這樣將會(huì)在ISP 匹配的時(shí)候,將會(huì)根據(jù)name 匹配到相應(yīng)的配置;
4.4.2 VIN 框架
4.4.2.1 R 系列
vin 框架的操作也是類似的,只是更換了位置。vin 的ISP 配置在tina/package/allwinner/libAWIspApi 目錄下,其中R311、MR133 在src/isp520,而R818、
MR813 在src/isp522。在libisp/isp_cfg/SENSOR 目錄下增加相應(yīng)的頭文件,然后在上一層目錄的isp_ini_parse.c 文件增加頭文件以及修改相應(yīng)的isp_cfg_array cfg_arr 數(shù)組匹配即可。
VIN 使用ISP,需要在camerademo 中make menuconfig 的時(shí)候,選擇上Choosewhether to use VIN ISP (YES)。同時(shí)VIN 的需要注意,當(dāng)自己開發(fā)camera
HAL 層時(shí),需要自己運(yùn)行camera ISP service,具體實(shí)現(xiàn)可參考camerademo 的實(shí)現(xiàn)。添加正確時(shí),在運(yùn)行camerademo 將會(huì)輸出相應(yīng)的sensor 配置信息,
比如:
[ISP]find imx278_mipi_2048_1152_60_0 [imx278_mipi_default_ini_mr813] isp config
上述表示正確查找到imx278_mipi 這個(gè)sensor 2048*1152 60fps 的ISP 配置,其他的sensorISP 配置移植正確也將會(huì)有類似的打印,輸出信息分別是sensor name 、分辨率、幀率,確認(rèn)這些信息一致即可。
4.4.2.2 V 系列
V 系列ISP 庫(kù)目錄,V533、V83x 平臺(tái)位于:softwinner/eyesee-mpp/middleware/sun8iw19p1/media/V536 平臺(tái)位于:softwinner/eyesee-
mpp/middleware/v316/media/LIBRARY/libisp/,V85x 平臺(tái)位于:external/eyesee-mpp/middleware/sun8iw21/media/LIBRARY/libisp/
修改libisp/isp_cfg/isp_ini_parse.c,將ISP 效果.h 包含進(jìn)來(lái),并修改struct isp_cfg_arraycfg_arr[] 結(jié)構(gòu)體;其中參數(shù)定義:
(1)Sensor 模塊名稱:sensor_mipi (2)ISP 效果頭文件名稱 (3)分辨率寬 (4)分辨率高 (5)幀率 (6)紅外IR 模式標(biāo)志位 (7)WDR 模式標(biāo)志位 (8)ISP 參數(shù)結(jié)構(gòu)體
![image-20221123113519900](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUUmAAWyoAABP02ibBi0268.png)
?
圖4-4: sunxi
?
4.5 如何輸出RAW 數(shù)據(jù)
在ioctl 的VIDIOC_S_FMT 命令,將其參數(shù)pixelformat 設(shè)置為RAW 格式即可,RAW 格式如下:
V4L2_PIX_FMT_SBGGR8 V4L2_PIX_FMT_SGBRG8 V4L2_PIX_FMT_SGRBG8 V4L2_PIX_FMT_SRGGB8 V4L2_PIX_FMT_SBGGR10 V4L2_PIX_FMT_SGBRG10 V4L2_PIX_FMT_SGRBG10 V4L2_PIX_FMT_SRGGB10 V4L2_PIX_FMT_SBGGR12 V4L2_PIX_FMT_SGBRG12 V4L2_PIX_FMT_SGRBG12 V4L2_PIX_FMT_SRGGB12
將pixelformat 設(shè)置為上述的其一即可輸出RAW 數(shù)據(jù), 而如何選擇上述的操作, 這個(gè)根據(jù)sensor 驅(qū)動(dòng)選擇, 如果驅(qū)動(dòng)中sensor_formats 的mbus_code 設(shè)置為
MEDIA_BUS_FMT_SBGGR10_1X10,則在輸出RAW 數(shù)據(jù)時(shí)將pixelformat 設(shè)置為V4L2_PIX_FMT_SBGGR10
當(dāng)前camerademo 已經(jīng)支持輸出RAW 數(shù)據(jù),可參照本文檔《camerademo 輸出RAW 數(shù)據(jù)》章節(jié)。
4.6 如何計(jì)算實(shí)際曝光時(shí)間
該部分為使用到ISP 的RAW sensor 配置信息。曝光時(shí)間的計(jì)算和曝光控制寄存器、hts、pclk這些配置相關(guān),這些配置都在sensor 驅(qū)動(dòng),ISP 將會(huì)根據(jù)sensor 驅(qū)
動(dòng)中的設(shè)置計(jì)算相應(yīng)的曝光時(shí)間,所以驅(qū)動(dòng)中的配置必須正確,否則在調(diào)試ISP 效果可能會(huì)遇到其他的一些問(wèn)題。
static struct sensor_win_size sensor_win_sizes[] = { ... .hts = 928, .vts = 1720, .pclk = 48 * 1000 * 1000, ... }
在sensor 的驅(qū)動(dòng)中有以上的一些配置,曝光時(shí)間在驅(qū)動(dòng)中是以曝光行為計(jì)算單位的,即在sensor_s_exp() 函數(shù)中設(shè)置的參數(shù)為曝光行,部分sensor 是以16 為一
倍的,所以在計(jì)算實(shí)際的曝光行時(shí),需要將上述函數(shù)參數(shù)除以16。
曝光時(shí)間= 曝光行× hts / pclk
一般的pclk 都是M 級(jí)別的,所以時(shí)間單位為us,部分sensor 的曝光行為參數(shù)的十六分之一,需要除以十六,同時(shí),曝光行不能大于vts 的值,否則將會(huì)出現(xiàn)降
幀、沒有正常輸出圖像等問(wèn)題。
4.7 如何脫離isp tuning 工具微調(diào)圖像亮度
在isp 配置文件中,有類似以下的信息:
.ae_cfg = { 256, 555, 256, 555, 31, 22, 22, 25, 3, 130, 16, 60, 1, 2 },
上述ae_cfg 參數(shù)的倒數(shù)第4 個(gè)數(shù)值(130)即是控制圖像亮度的閥門(期望亮度),該值越大,圖像亮度越高。ae_cfg 一共14 個(gè),分別對(duì)應(yīng)著不同的環(huán)境亮度
(Lux)。如何確定AE 當(dāng)前處于哪組ae_cfg 參數(shù)呢?修改isp 配置文件中的isp_log_param = 0x1,然后重新編譯運(yùn)行相機(jī)應(yīng)用,留意應(yīng)用中關(guān)于isp 的打印信息:
[ISP_DEBUG]: isp0 ae_target 92, pic_lum 0, weight_lum 0, delta_exp_idx 138, ae_delay 0, AE_TOLERANCE
5
從上述信息可以看到當(dāng)前的目標(biāo)亮度是92,這時(shí)可以查看isp 配置文件ae_cfg 中哪組的閥門處于92 這個(gè)范圍,如果需要增加亮度,則提高相應(yīng)的閥門;降低亮度
則降低閥門。相應(yīng)的根據(jù)實(shí)際調(diào)試情況修改即可。調(diào)試之后,記得將isp_log_param 參數(shù)還原為0。
4.8 VIN 如何設(shè)置裁剪和縮放
裁剪修改sensor 驅(qū)動(dòng):在驅(qū)動(dòng)有類似以下的配置
static struct sensor_win_size sensor_win_sizes[] = { { .width = VGA_WIDTH, .height = VGA_HEIGHT, .hoffset = 0, .voffset = 0, .hts = 878, .vts = 683, .pclk = 72 * 1000 * 1000, .mipi_bps = 720 * 1000 * 1000, .fps_fixed = 120, .bin_factor = 1, .intg_min = 1 << 4, ? ? ? ?.intg_max = (683) << 4, ? ? ? ?.gain_min = 1 << 4, ? ? ? ?.gain_max = 16 << 4, ? ? ? ?.regs = sensor_VGA_120fps_regs, ? ? ? ?.regs_size = ARRAY_SIZE(sensor_VGA_120fps_regs), ? ? ? ?.set_size = NULL, ? ?}, };
上述的width height 表示經(jīng)過(guò)isp 輸出之后的數(shù)據(jù),如果需要裁剪,修改width、height、hoffset 和voffset。裁剪之后的輸出width = sensor_output_src -
2hoffset height = sensor_height_src - 2voffset 注意,上述的hoffset voffset 必須為雙數(shù)。
所以,假設(shè)sensor 輸出的是640 × 480,我們想裁剪為320 × 240 的,則上述配置修改為:
static struct sensor_win_size sensor_win_sizes[] = { { .width = 320, .height = 240, .hoffset = 160, .voffset = 120, .hts = 878, .vts = 683, .pclk = 72 * 1000 * 1000, .mipi_bps = 720 * 1000 * 1000, .fps_fixed = 120, .bin_factor = 1, .intg_min = 1 << 4, ? ? ? ?.intg_max = (683) << 4, ? ? ? ?.gain_min = 1 << 4, ? ? ? ?.gain_max = 16 << 4, ? ? ? ?.regs = sensor_VGA_120fps_regs, ? ? ? ?.regs_size = ARRAY_SIZE(sensor_VGA_120fps_regs), ? ? ? ?.set_size = NULL, ? ?}, };
縮放配置:使用硬件縮放,可以在應(yīng)用層通過(guò)VIDIOC_S_FMT 設(shè)置分辨率的時(shí)候,直接設(shè)置分辨率的大小為縮放的分辨率即可。
fmt.fmt.pix_mp.width = 320; fmt.fmt.pix_mp.height = 240;
上述的操作,將會(huì)使用硬件完成相應(yīng)的縮放輸出。
5 模塊調(diào)試常見問(wèn)題
初次調(diào)試建議打開device 中的DEV_DBG_EN 為1,方便調(diào)試。
Camera 模塊調(diào)試一般可以分為三步:
使用lsmod 命令查看驅(qū)動(dòng)是否加載,查看/lib/modules/內(nèi)核版本號(hào)目錄下是否存在相應(yīng)的ko,如果沒有,確認(rèn)modules.mk 是否修改正確,配置了開機(jī)自動(dòng)
加載。如果存在相應(yīng)的ko,可手動(dòng)加載測(cè)試確認(rèn)ko 是否正常,手動(dòng)加載成功,則確認(rèn)內(nèi)核的版本是否一致,導(dǎo)致開機(jī)時(shí)沒有找到相應(yīng)的ko 從而沒有加載。
使用ls /dev/v* 查看是否有video0/1 節(jié)點(diǎn)生成
在adb shell 中使用cat /proc/kmsg 命令,或者是使用串口查看內(nèi)核的打印信息,查看不能正常加載的原因。一般情況下驅(qū)動(dòng)加載不成功的原因有:一是讀取
的sys_config.fex 文件中的配置信息與加載的驅(qū)動(dòng)不匹配,二是probe 函數(shù)遇到某些錯(cuò)誤沒能正確的完成probe 的時(shí)候返回。
5.1 移植一款sensor 需要進(jìn)行哪些操作
移植camera sensor,主要進(jìn)行以下操作:
根據(jù)主板的原理圖,確認(rèn)與sensor 模組的接口是否一致,一致才可以保證配置和數(shù)據(jù)的正常接收。
根據(jù)產(chǎn)品的需求,讓sensor 模組廠提供產(chǎn)品所需的分辨率、幀率的寄存器配置,這一步需要注意,提供的配置需要是和模組匹配的。比如模組的mipi 接口只
引出2lane,而提供的寄存器配置卻是配置為4lane 輸出的,那么該配置在該模組無(wú)法正常使用,讓模組廠提供該模組可以正常使用的正確配置。注意,該寄存
器配置SOC 原廠沒有,需要sensor 廠提供。
拿到寄存器配置之后,按照本文檔《驅(qū)動(dòng)模塊實(shí)現(xiàn)》章節(jié)完成sensor 驅(qū)動(dòng)的編寫。
在完成驅(qū)動(dòng)的編寫之后,按照本文檔《Tina 配置》章節(jié)完成modules.mk 的修改。
根據(jù)板子的原理圖與模組的硬件連接,參照本文檔《sys_config.fex 配置》或者《MR813/R818平臺(tái)配置》章節(jié)完成sys_config.fex 或者board.dts 的修改。
完成上述操作之后,按照本文檔《menuconfig 配置說(shuō)明》章節(jié),選上camera 驅(qū)動(dòng)模塊,按照《camera 功能測(cè)試》章節(jié)選上camera 的測(cè)試程序,測(cè)試驅(qū)動(dòng)
移植是否正常。
5.2 I2C 通信出現(xiàn)問(wèn)題
5.2.1 R16 R11 R40 等
I2C 出現(xiàn)問(wèn)題內(nèi)核一般會(huì)伴隨打印” cci_write_aX_dX error! slave = 0xXX, addr = 0xXX,value = 0xXX“。
如果與此同時(shí),內(nèi)核出現(xiàn)打印“chip found is not an target chip.”,則說(shuō)明在初始化camera前,讀取camera 的ID 已經(jīng)失敗。此時(shí),一般是如下幾點(diǎn)出現(xiàn)問(wèn)題。
a. 最先考慮應(yīng)該是更換一個(gè)camera模組試試。 b. 電源 檢查sys_config.fex vip_dev0_iovdd = "axp22_eldo3" vip_dev0_iovdd_vol = 2800000 vip_dev0_avdd = "axp22_dldo4" vip_dev0_avdd_vol = 2800000 vip_dev0_dvdd = "axp22_eldo2" vip_dev0_dvdd_vol = 1500000 一定要與原理圖設(shè)計(jì)保持一致。必要時(shí),需要用萬(wàn)用表測(cè)量camera模組的各路電壓是否正常。 c. reset和power down腳 檢查sys_config.fex配置 vip_dev0_reset = port:PH2<1> vip_dev0_pwdn = port:PH1<1> 是否與原理圖設(shè)計(jì)保持一致。必要時(shí),需要用示波器測(cè)量reset,pwdn腳,在camera加載時(shí),是否有動(dòng)作。 d. mclk 檢查sys_config.fex配置 vip_csi_mck = port:PE01<3> pin腳是否與原理圖設(shè)計(jì)保持一致。必要時(shí),在加載camera時(shí),測(cè)量mclk,看是否有正確輸出(一般是24MHz或27MHz )
如果已經(jīng)能夠正確通過(guò)camera 的id 讀取,只是在使用過(guò)程當(dāng)中,偶爾出現(xiàn)I2C 的讀寫錯(cuò)誤,此時(shí)需要從打印里面,將報(bào)錯(cuò)的地址和讀寫值,結(jié)合camera 具體的
spec 來(lái)分析,到底是操作了camera 哪些寄存器帶來(lái)的問(wèn)題。
5.2.2 其他平臺(tái)
出錯(cuò)時(shí)一般出現(xiàn)以下信息:
[ 5.556579] sunxi_i2c_do_xfer()1942 - [i2c1] incomplete xfer (status: 0x20, dev addr: 0 x30) [ 5.566234] sunxi_i2c_do_xfer()1942 - [i2c1] incomplete xfer (status: 0x20, dev addr: 0 x30) [ 5.575963] sunxi_i2c_do_xfer()1942 - [i2c1] incomplete xfer (status: 0x20, dev addr: 0 x30) [ 5.585375] [VIN_DEV_I2C]sc031gs_mipi sensor read retry = 2 [ 5.591666] [sensorname_mipi] error, chip found is not an target chip.
出現(xiàn)上述錯(cuò)誤打印時(shí),可按以下操作逐步debug。
確認(rèn)sys_config.fex 中配置的sensor I2C 地址是否正確(sensor datasheet 中標(biāo)注,讀地 址為0x6d,寫地址為0x6c,那么sys_config.fex 配置sensor I2C 地址為0x6c);
在完成以上操作之后,在senor 上電函數(shù)中,將掉電操作屏蔽,保持sensor 一直上電狀態(tài), 方便debug;
確認(rèn)I2C 地址正確之后,測(cè)量sensor 的各路電源電壓是否正確且電壓幅值達(dá)到datasheet 標(biāo)注的電壓要求;
測(cè)量MCLK 的電壓幅值與頻率,是否正常;
測(cè)量senso r 的reset、pown 引腳電平配置是否正確,I2C 引腳SCK、SDA 是否已經(jīng)硬件 上拉;
確認(rèn)I2C 接口使用正確并使能(CCI / TWI);
如果還是I2C 出錯(cuò),協(xié)調(diào)硬件同事使用邏輯分析儀等儀器進(jìn)行debug;
5.2.3 經(jīng)典錯(cuò)誤
5.2.3.1 I2C 沒有硬件上拉
twi_start()450 - [i2c2] START can't sendout! twi_start()450 - [i2c2] START can't sendout! twi_start()450 - [i2c2] START can't sendout! [VFE_DEV_I2C_ERR]cci_write_a16_d16 error! slave = 0x1e, addr = 0xa03e, value = 0x1
出現(xiàn)上述的問(wèn)題是因?yàn)镾DA、SCK 沒有拉上,導(dǎo)致在進(jìn)行I2C 通信時(shí),發(fā)送開始信號(hào)失敗,SDA、SCK 添加上拉即可。
5.2.3.2 沒有使能I2C
[VFE]Sub device register "ov2775_mipi" i2c_addr = 0x6c start! [VFE_ERR]request i2c adapter failed! [VFE_ERR]vfe sensor register check error at input_num = 0
出現(xiàn)上述的錯(cuò)誤,是因?yàn)槭褂胻wi 進(jìn)行I2C 通信但沒有使能twi 導(dǎo)致的錯(cuò)誤,此時(shí)需要確認(rèn)sys_config.fex 中,[twiX] 中的twiX_used 是否已經(jīng)設(shè)置為1。
5.3 圖像異常
5.3.1 運(yùn)行camerademo 可以成功采集圖像,但圖像全黑(RAWsensor)
當(dāng)camerademo 成功采集到圖像時(shí),最起碼整條數(shù)據(jù)通路已經(jīng)正常,而發(fā)現(xiàn)圖像時(shí)全黑的,注意以下幾點(diǎn):
在編譯camerademo 之前,是根據(jù)平臺(tái)(MR813/R818/MR133/R311) 正確的選上了“Enable vin isp support”,選上之后,重新編譯camerademo
(建議cd package/allwinner/-camerademo 目錄后執(zhí)行mm -B 編譯);
通過(guò)上述操作之后, 執(zhí)行新編譯的camerademo 可執(zhí)行程序, 運(yùn)行過(guò)程應(yīng)可看到類似”[ISP]create isp0 server thread?‘信息,則正確運(yùn)行isp,這時(shí)再查看新
抓取的圖像數(shù)據(jù);
執(zhí)行運(yùn)行camerademo 只會(huì)抓取5 張圖像數(shù)據(jù),由于isp 計(jì)算合適的圖像曝光需要一定的幀數(shù),所以可能存在前面幾張圖像黑的情況,修改camerademo 運(yùn)行
參數(shù),抓取多幾張圖像數(shù)據(jù)查看(20 張);
如果是沒有移植isp 的環(huán)境,則可修改sensor 驅(qū)動(dòng)中寄存器組中的曝光參數(shù)配置,增加初始化時(shí)曝光時(shí)間,從而使初始輸出的圖像亮度較合適;
5.3.2 camerademo 采集的圖像顏色異常
運(yùn)行camerademo 采集圖像之后,發(fā)現(xiàn)拍攝得到的輪廓正確但顏色不對(duì),比如紅藍(lán)互換、畫面整體偏紅或偏藍(lán)等顏色異常的情況,出現(xiàn)這樣的問(wèn)題,首先考慮是
sensor 驅(qū)動(dòng)中配置的RAW 數(shù)據(jù)RGB 順序錯(cuò)誤導(dǎo)致的。在sensor 驅(qū)動(dòng)中有類似以下的配置:
static struct sensor_format_struct sensor_formats[] = { { .desc = "Raw RGB Bayer", .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, .regs = sensor_fmt_raw, .regs_size = ARRAY_SIZE(sensor_fmt_raw), .bpp = 1 }, };
以上配置表明sensor 輸出的圖像數(shù)據(jù)是RAW10,RGB 排列順序是BGGR,出現(xiàn)顏色異常時(shí),一般就是RGB 的排列順序配置錯(cuò)誤導(dǎo)致的,RGB 排列順序一共有4 種
(MEDIA_BUS_FMT_SBGGR10_1X10/MEDIA_BUS_FMT_SGBRG10_1X10/MEDIA_BUS_FMT_SGRBG10_修改驅(qū)動(dòng)中的mbus_code 為上述的4 種之一,確認(rèn)哪一種
顏色比較正常,則驅(qū)動(dòng)配置正確。
如果顏色還有細(xì)微的不夠艷麗、準(zhǔn)確等問(wèn)題,需要進(jìn)行isp 效果調(diào)試,改善圖像色彩。上述是以10bit sensor 為例進(jìn)行介紹,其他的8bit、12bit、14bit 類似,參
考上述即可。
5.4 調(diào)試camera 常見現(xiàn)象和功能檢查
insmod 之后首先看內(nèi)核打印,看加載有無(wú)錯(cuò)誤打印,部分驅(qū)動(dòng)在加載驅(qū)動(dòng)進(jìn)行上下電時(shí)候會(huì)進(jìn)行i2c 操作,如果此時(shí)報(bào)錯(cuò)的話就不需要再進(jìn)入camera 了,先
檢查是否io 或電源配置不對(duì)。或者是在復(fù)用模組時(shí)候有可能是另外一個(gè)模組將i2c 拉住了。
如果i2c 讀寫沒有問(wèn)題的話,一般就可以認(rèn)為sensor 控制是ok 的,只需要根據(jù)sensor 的配置填好H/VREF、PCLK 的極性就能正常接收?qǐng)D像了。這個(gè)時(shí)候可以
在進(jìn)入camera 應(yīng)用之后用示波器測(cè)量sensor 的各個(gè)信號(hào),看h/vref、pclk 極性、幅度是否正常(2.8V 的vpp)。
如果看到畫面了,但是看起來(lái)是綠色和粉紅色的,但是有輪廓,一般是YUYV 的順序設(shè)置反了,可檢查yuyv 那幾個(gè)寄存器是否填寫正確配置,其次,看是否是
在配置的其他地方有填寫同一個(gè)寄存器的地方導(dǎo)致將yuyv fmt 的寄存器被改寫。
如果畫面顏色正常,但是看到有一些行是粉紅或者綠色的,往往是sensor 信號(hào)質(zhì)量不好所致,通常在比較長(zhǎng)的排線中出現(xiàn)這個(gè)情況。在信號(hào)質(zhì)量不好并且
yuyv 順序不對(duì)的時(shí)候也會(huì)看見整個(gè)畫面的是綠色的花屏。
當(dāng)驅(qū)動(dòng)能力不足的時(shí)候增強(qiáng)sensor 的io 驅(qū)動(dòng)能力有可能解決這個(gè)問(wèn)題。此時(shí)用示波器觀察pclk 和數(shù)據(jù)線可能會(huì)發(fā)現(xiàn):pclk 波形擺幅不夠IOVDD 的幅度,或者
是data 輸出波形擺幅有時(shí)候能高電平達(dá)到IOVDD 的幅度,有時(shí)候可能連一半都不夠。
如果是兩個(gè)模組復(fù)用數(shù)據(jù)線的話,不排除是另外一個(gè)sensor 在進(jìn)入standby 時(shí)候沒有將其數(shù)據(jù)線設(shè)置成高阻,也會(huì)影響到當(dāng)前模組的信號(hào)擺幅,允許的話可
以剪斷另一個(gè)模組來(lái)證實(shí)。
當(dāng)畫面都正常之后檢查前置攝像頭垂直方向是否正確,水平方向是否是鏡像,后置水平垂直是否正確,不對(duì)的話可以調(diào)節(jié)sys_config.fex 中的hflip 和vflip 參數(shù)
來(lái)解決,但如果屏幕上看到的畫面與人眼看到的畫面是成90 度的話,只能是通過(guò)修改模組的方向來(lái)解決。
之后可以檢查不同分辨率之間的切換是否ok,是否有切換不成功的問(wèn)題;以及拍照時(shí)候是否圖形正常,亮度顏色是否和預(yù)覽一致;雙攝像頭的話需要檢查前后
切換是否正常。
如果上述都沒有問(wèn)題的話,可認(rèn)為驅(qū)動(dòng)無(wú)大問(wèn)題,接下來(lái)可以進(jìn)行其他功能(awb/exp bias/-color effect 等其他功能的測(cè)試)。
測(cè)試對(duì)焦功能,單次點(diǎn)觸屏幕,可正確對(duì)上不同距離的物體;不點(diǎn)屏幕時(shí)候可以自動(dòng)對(duì)焦對(duì)上畫面中心物體,點(diǎn)下拍照后拍出來(lái)的畫面能清晰。
打開閃光燈功能,檢查在單次對(duì)焦時(shí)候能打開燈,對(duì)完之后無(wú)論成功失敗或者超時(shí)能夠關(guān)閉,在點(diǎn)下拍照之后能打開,拍完之后能關(guān)閉。
如果加載模塊后,發(fā)現(xiàn)dev/videoX 節(jié)點(diǎn)沒有生成,請(qǐng)檢查下面幾點(diǎn)。
a. 模塊加載的順序 一定要按照以下順序加載模塊 insmod videobuf-core.ko insmod videobuf-dma-contig.ko ;如果有對(duì)應(yīng)的vcm driver,在這里加載,如果沒有,請(qǐng)省略。 insmod actuator.ko insmod ad5820_act.ko ;以下是camera驅(qū)動(dòng)和vfe驅(qū)動(dòng)的加載,先安裝一些公共資源。 insmod vfe_os.ko insmod vfe_subdev.ko insmod cci.ko insmod ov5640.ko insmod gc0308.ko ;如果一個(gè)csi接兩個(gè)camera,所有camera對(duì)應(yīng)的ko都要在vfe_v4l2.ko之前加載。 insmod vfe_v4l2.ko b. sys_config.fex配置 vip_used = 1 ;確保used為1 vip_dev_qty = 2 ;確保csi接口上接的camera數(shù)量與ko加載情況相同 vip_dev0_mname = "ov5640" ;確保camera型號(hào)與ko加載情況相同 vip_dev0_twi_id = 1 ;確保camera使用的i2c總線id與配置一樣 vip_dev1_mname = "gc0308" ;確保camera型號(hào)與ko加載情況相同 vip_dev1_twi_id = 1 ;確保camera使用的i2c總線id與配置一樣
5.5 畫面大體輪廓正常,顏色出現(xiàn)大片綠色和紫紅色
一般可能是csi 采樣到的yuyv 順序出現(xiàn)錯(cuò)位。
確認(rèn)camera 輸出的yuyv 順序的設(shè)置與camera 的spec 一致 若camera 輸出的yuyv 順序沒有問(wèn)題,則可能是由于走線問(wèn)題,導(dǎo)致pclk 采樣data 時(shí)發(fā)生錯(cuò)位,此時(shí)可以調(diào)整pclk 的采樣沿。具體做法如下:
在對(duì)應(yīng)的camara 驅(qū)動(dòng)源碼,如ov5640.c 里面,找到宏定義#define CLK_POL。此宏定義可以有兩個(gè)值V4L2_MBUS_PCLK_SAMPLE_RISING 和
V4L2_MBUS_PCLK_SAMPLE_FALLING。若原來(lái)是其中一個(gè)值,則修改成另外一個(gè)值,便可將PCLK 的采樣沿做反相。
5.6 畫面大體輪廓正常,但出現(xiàn)不規(guī)則的綠色紫色條紋
一般可能是pclk 驅(qū)動(dòng)能力不足,導(dǎo)致某個(gè)時(shí)刻采樣data 時(shí)發(fā)生錯(cuò)位。
解決辦法:
? 若pclk 走線上有串聯(lián)電阻,嘗試將電阻阻值減小。
? 增強(qiáng)pclk 的驅(qū)動(dòng)能力,需要設(shè)置camera 的內(nèi)部寄存器。
5.7 畫面看起來(lái)像油畫效果,過(guò)渡漸變的地方有一圈一圈
一般是CSI 的data 線沒有接好,或短路,或斷路。
5.8 出現(xiàn)[VFE_WARN] Nobody is waiting on thisvideo buffer
上層還回來(lái)所有的buffer,但是沒有再來(lái)取buffer。
5.9 出現(xiàn)[VFE_WARN] Only three buffer left for csi
上層占用了大部分buffer,沒有還回,驅(qū)動(dòng)部分只有三個(gè)buffer 此時(shí)驅(qū)動(dòng)不再進(jìn)行buffer 切換,直到有buffer 還回為止。
5.10 sensor 的硬件接口注意事項(xiàng)
如果是使用并口的sensor 模組,會(huì)使用到720p@30fps 或更高速度的,必須在mclk/pclk/- data/vsync/hsync 上面串33ohm 電阻,5M 的sensor 一律串電阻;
使用Mipi 模組時(shí)候PCB layout 需要盡量保證clk/data 的差分對(duì)等長(zhǎng),過(guò)孔數(shù)相等,特征 阻抗100ohm;
如果使用并口復(fù)用pin 的模組時(shí)候,不建議reset 腳的復(fù)用;
并口模組的排線長(zhǎng)度加上pcb 板上走線長(zhǎng)度不超過(guò)10cm,mipi 模組排線長(zhǎng)度加上pcb 板上 走線長(zhǎng)度不超過(guò)20cm,超過(guò)此距離不保證能正常使用。
主控并口數(shù)據(jù)線有D11~D0 共12bit,并口的sensor 輸出一般為8/10bit,原理圖連接需 要做高位對(duì)齊。
6 camera 功能測(cè)試
Tina 系統(tǒng)可以通過(guò)SDK 中的camerademo 包來(lái)驗(yàn)證camera sensor(usb camera)是否移植成功,如果可以正常捕獲保存圖像數(shù)據(jù),則底層驅(qū)動(dòng)、板子硬件正常。
6.1 camerademo 配置
在命令行中進(jìn)入Tina 根目錄,執(zhí)行make menuconfig 進(jìn)入配置主界面,并按以下配置路徑操作:
Allwinner └─>camerademo
首先,選擇Allwinner 選項(xiàng)進(jìn)入下一級(jí)配置,如下圖所示:
![image-20221123141424322](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUUqAfj8cAADkviwVHrU729.png)
?
圖6-1: allwinner
?
然后,選擇camerademo 選項(xiàng),可選擇<*> 表示直接編譯包含在固件,也可以選擇表示僅編譯不包含在固件。當(dāng)平臺(tái)的camera 框架是VIN 且需要使用ISP 時(shí),將
需要在camerademo 的選項(xiàng)處點(diǎn)擊回車進(jìn)行以下界面選擇使能ISP。(該選項(xiàng)只能在VIN 框架中,使用RAW sensor時(shí)使用,在修改該選項(xiàng)之后,需要先單獨(dú)mm -
B 編譯該package)。
![image-20221123141504379](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUUuAEVNnAAAy2hYzIhQ870.png)
?
圖6-2: camerademo
?
![image-20221123141522573](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUUuARW9HAAAZvHwElCk431.png)
?
圖6-3: vinisp
?
6.2 源碼結(jié)構(gòu)
camerademo 的源代碼位于package/allwinner/camerademo/目錄下:
|---src | camerademo.c //camea測(cè)試的主流程代碼 | camerademo.h //camera demo相關(guān)數(shù)據(jù)結(jié)構(gòu) | common.c //實(shí)現(xiàn)共用的函數(shù),轉(zhuǎn)換時(shí)間、保存文件、測(cè)試幀率等 | common.h //共用函數(shù)頭文件 | convert.c //實(shí)現(xiàn)圖像格式轉(zhuǎn)換函數(shù) | convert.h //圖像格式轉(zhuǎn)換函數(shù)頭文件
6.3 camerademo 使用方法
在小機(jī)端加載成功后輸入camerademo help,假如驅(qū)動(dòng)產(chǎn)生的節(jié)點(diǎn)video0(測(cè)試默認(rèn)以/dev/video0 作為設(shè)備對(duì)象)可以打開則會(huì)出現(xiàn)下面提示:
通過(guò)提示我們可以得到一些提示信息,了解到該程序的運(yùn)行方式、功能,可以查詢sensor 支持的分辨率、sensor 支持的格式以及設(shè)置獲取照片的數(shù)量、數(shù)據(jù)保存
的格式、路徑、添加水印、測(cè)試數(shù)據(jù)輸出的幀率、從open 節(jié)點(diǎn)到數(shù)據(jù)流打通需要的時(shí)間等,help 打印信息如下圖:
![image-20221123142705806](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUUyARctYAAE8fwMmXO8056.png)
?
圖6-4: help
?
Camerademo 共有4 種運(yùn)行模式:
默認(rèn)方式:直接輸入camerademo 即可,在這種運(yùn)行模式下,將設(shè)置攝像頭為640*480 的NV21 格式輸出圖像數(shù)據(jù),并以BMP 和YUV 的格式保存在/tmp 目
錄下,而當(dāng)輸入camerademodebug 將會(huì)輸出更詳細(xì)的debug 信息;
探測(cè)設(shè)置camerademo setting:將會(huì)在運(yùn)行過(guò)程中根據(jù)具體camera 要求輸入設(shè)置參數(shù),當(dāng)輸入camerademo setting debug 的時(shí)候,將會(huì)輸出詳細(xì)的debug 信息;
快速設(shè)置:camerademo argv[1] argv[2] argv[3] argv[4] argv[5] argv[6] argv[7],將會(huì)按照輸入?yún)?shù)設(shè)置圖像輸出,同樣,當(dāng)輸入camerademo argv[1]
argv[2] argv[3] argv[4] argv[5] argv[6] argv[7] debug 時(shí)將會(huì)輸出更詳細(xì)的debug 信息。
選擇camera 設(shè)置:camerademo argv[1] argv[2] argv[3] argv[4] argv[5] argv[6] argv[7] argv[8],將會(huì)按照輸入?yún)?shù)設(shè)置圖像輸出,同樣,當(dāng)輸入
camerademo argv[1] argv[2] argv[3] argv[4] argv[5] argv[6] argv[7] argv[8] debug 時(shí)將會(huì)輸出更詳細(xì)的debug 信息。
6.3.1 默認(rèn)方式
當(dāng)輸入camerademo 之后,使用默認(rèn)的參數(shù)運(yùn)行,則會(huì)打印一下信息,如下圖:
![image-20221123142833252](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUU2ASCCEAAFpGkzxUuw394.png)
?
圖6-5: camerademouser
?
首先可以清楚的看到成功open video0 節(jié)點(diǎn),并且知道照片數(shù)據(jù)的保存路徑、捕獲照片的數(shù)量以及當(dāng)前設(shè)置:是否添加水印、輸出格式、分辨率和從開啟流傳輸?shù)?/p>
第一幀數(shù)據(jù)達(dá)到時(shí)間間隔等信息。如果需要了解更多的詳細(xì)信息,可以在運(yùn)行程序的時(shí)候輸入?yún)?shù)debug 即運(yùn)行camerademo debug,將會(huì)打開demo 的debug
模式,輸出更詳細(xì)的信息,包括camera 的驅(qū)動(dòng)類型,支持的輸出格式以及對(duì)應(yīng)的分辨率,申請(qǐng)buf 的信息,實(shí)際輸出幀率等。
6.3.2 選擇方式
在選擇模式下有兩種運(yùn)行方式,一種是逐步選擇,在camera 的探測(cè)過(guò)程,知道其支持的輸出格式以及分辨率之后再設(shè)置camera 的相關(guān)參數(shù);另一種是直接在運(yùn)
行程序的時(shí)候帶上相應(yīng)參數(shù),程序按照輸入?yún)?shù)運(yùn)行(其中還可以選擇camera 索引,從而測(cè)試不同的camera)。
輸入camerademo setting,則按照程序的打印提示輸入相應(yīng)選擇信息即可。 ? 輸入保存路徑、照片數(shù)量、保存的格式等。
![image-20221123142929515](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUU2ASJiKAAB1Ad-DUtY130.png)
?
圖6-6: info
?
? 選擇輸出格式。
![image-20221123142950450](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUU6AbGbcAACEUBve98A819.png)
?
圖6-7: format
?
? 選擇輸出圖像分辨率。
![image-20221123143011933](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUU6ADtB0AACfwaZ83fs549.png)
?
圖6-8: size
?
其它信息與默認(rèn)設(shè)置一致,如需打印詳細(xì)的信息,運(yùn)行camerademo setting debug 即可。
第二種是設(shè)置參數(shù): ? 默認(rèn)的video 0 節(jié)點(diǎn):camerademo argv[1] argv[2] argv[3] argv[4] argv[5] argv[6] argv[7]。 輸入?yún)?shù)代表意義如下:
argv[1]:camera輸出格式---NV21 YUYV MJPEG等; argv[2]:camera分辨率width; argv[3]:camera分辨率height; argv[4]:sensor輸出幀率; argv[5]:保存照片的格式:all---bmp和yuv格式都保存、bmp---僅以bmp格式保存、yuv---僅以yuv格式保存; argv[6]:捕獲照片的保存路徑; argv[7]:捕獲照片的數(shù)量;
例如:camerademo NV21 640 480 30 yuv /tmp 2,將會(huì)輸出640*480@30fps 的NV21格式照片以yuv 格式、不添加水印保存在/tmp 路徑下,照片共2 張。
其它信息與默認(rèn)設(shè)置一致,如需打印詳細(xì)的信息,運(yùn)行camerademo argv[1] argv[2] argv[3] argv[4] argv[5] argv[6] argv[7] debug 即可。
![image-20221123143239114](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUU-AKFZAAAFVSDL5-H4958.png)
?
圖6-9: run1
?
? 選擇其他的video 節(jié)點(diǎn):camerademo argv[1] argv[2] argv[3] argv[4] argv[5] argv[6] argv[7] argv[8]。
輸入?yún)?shù)代表意義如下:
argv[1]:camera輸出格式---NV21 YUYV MJPEG等; argv[2]:camera分辨率width; argv[3]:camera分辨率height; argv[4]:sensor輸出幀率; argv[5]:保存照片的格式:all---bmp和yuv格式都保存、bmp---僅以bmp格式保存、yuv---僅以yuv格式保存; argv[6]:捕獲照片的保存路徑; argv[7]:捕獲照片的數(shù)量; argv[8]:video節(jié)點(diǎn)索引;
例如:camerademo YUYV 640 480 30 yuv /tmp 1 1,將會(huì)打開/dev/video1 節(jié)點(diǎn)并輸出640*480@30fps 的以yuv 格式、不添加水印保存在/tmp 路徑下,照片共
1 張。
其它信息與默認(rèn)設(shè)置一致,如需打印詳細(xì)的信息,運(yùn)行camerademo argv[1] argv[2] argv[3] argv[4] argv[5] argv[6] argv[7] argv[8] debug 即可。
![image-20221123143328632](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUVCAPJXMAAE9jZEE2L4579.png)
?
圖6-10: run2
?
6.3.3 camerademo 保存RAW 數(shù)據(jù)
當(dāng)需要使用camerademo 保存RAW 數(shù)據(jù)時(shí),只需要將輸出格式設(shè)置為RAW 格式即可。先確認(rèn)sensor 驅(qū)動(dòng)中的mbus_code 設(shè)置為多少位, 假設(shè)驅(qū)動(dòng)中, 配置為
mbus_code =MEDIA_BUS_FMT_SGRBG10_1X10,那么可以確認(rèn)sensor 輸出是RAW10,camerademo 的輸出格式設(shè)置為RAW10 即可。比如輸入camerademo
RGGB10 1920 1080 30 bmp /tmp 5,以上命令輸出配置sensor 輸出RAW 數(shù)據(jù)并保存在/tmp 目錄,命令的含義參考本章節(jié)的《選擇方式》。
注意:RAW 數(shù)據(jù)文件的保存后綴是.raw 。
6.3.4 debug 信息解析
以下debug 信息將說(shuō)明sensor 驅(qū)動(dòng)的相關(guān)信息,拍攝到的照片保存位置、數(shù)量、保存的格式以及水印使用情況等:
![image-20221123143422192](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUVCAVmGkAADCUBWkCns207.png)
?
圖6-11: debug1
?
以下debug 信息將說(shuō)明驅(qū)動(dòng)框架支持的格式以及sensor 支持的輸出格式:
![image-20221123143618199](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUVGAddCFAAHAnijRitg548.png)
?
圖6-12: debug2
?
類似以下的信息代表這相應(yīng)格式支持的分辨率信息:
![image-20221123143642323](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUVGAeDbKAACJg6RDZyo516.png)
?
圖6-13: debug3
?
以下信息將會(huì)提示將要設(shè)置到sensor 的格式和分辨率等信息:
![image-20221123143703117](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUVKARnesAAAtu50i90g011.png)
?
圖6-14: debug4
?
以下信息將會(huì)提示設(shè)置格式的情況,buf 的相應(yīng)信息等:
![image-20221123143723798](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUVOAKgCQAAClLCTaF4M690.png)
?
圖6-15: debug5
?
以下信息將提示當(dāng)前拍照的照片索引以及從開啟流傳輸?shù)絛qbuf 成功的時(shí)間間隔:
![image-20221123143742621](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUVOAQkfPAABRNy_dUcs773.png)
?
圖6-16: debug6
?
以下信息提示該sensor 的實(shí)際測(cè)量幀率信息:
![image-20221123143807349](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUVSANw23AAAz-Dk0Bo8089.png)
?
圖6-17: debug7
?
以下信息提示從open 節(jié)點(diǎn)到可以得到第一幀數(shù)據(jù)的時(shí)間間隔,默認(rèn)設(shè)置為測(cè)試拍照的相應(yīng)設(shè)置:
![image-20221123143825189](https://file.elecfans.com//web2/M00/95/B7/poYBAGQFUVSATzuUAABHRBLb8Q0199.png)
?
圖6-18: debug8
?
6.3.5 文件保存格式
設(shè)置完畢之后,將會(huì)在所設(shè)路徑(默認(rèn)/tmp)下面保存圖像數(shù)據(jù),數(shù)據(jù)分別有兩種格式,一種是YUV 格式,以source_ 格式.yuv 名稱保存;一種是BMP 格式,以
bmp_ 格式.bmp 格式保存,如下圖所示。
查看圖像數(shù)據(jù)時(shí),需要通過(guò)adb pull 命令將相應(yīng)路徑下的圖像數(shù)據(jù)pull 到PC 端查看。
![image-20221123143900168](https://file.elecfans.com//web2/M00/96/3E/pYYBAGQFUVWAZ3OeAABtQnWMrok697.png)
?
圖6-19: save
?
6.4 select timeout 了,如何操作?
在完成sensor 驅(qū)動(dòng)的移植,驅(qū)動(dòng)模塊正常加載,I2C 正常通信,將會(huì)在/dev 目錄下創(chuàng)建相應(yīng)的video 節(jié)點(diǎn),之后可以使用camerademo 進(jìn)行捕獲測(cè)試,如果出現(xiàn)
select timeout,end capture thread!,這個(gè)情況可按照以下操作進(jìn)行debug。
先和模組廠確認(rèn),當(dāng)前提供的寄存器配置是否可以正常輸出圖像數(shù)據(jù)。有些模組廠提供的寄存器配置還需要增加一個(gè)使能寄存器,這些可以在sensor
datasheet 上查詢得到或者與模組廠溝通;
通過(guò)dmesg 命令, 查看在運(yùn)行camerademo 的過(guò)程中內(nèi)核是否有異常的打印。在MR813/R818 平臺(tái),內(nèi)核出現(xiàn)tdm 相關(guān)字段的連續(xù)打印,則需要確認(rèn),
board.dts 中的isp配置是否正確,單攝的配置,isp_sel 和tdm_rx_sel 都需要配置為0;雙攝的則需要先運(yùn)行配置為isp0 的video 節(jié)點(diǎn)才能再運(yùn)行isp1 的video
節(jié)點(diǎn);
其他的按照是并口還是mipi 接口進(jìn)行相應(yīng)的debug;
6.4.1 DVP sensor
確定sensor 的出圖data 配置正確,是8 位的、10 位的、12 位的?確認(rèn)之后,檢查驅(qū)動(dòng)中的sensor_formats 和sys_config.fex 中的csi data pin 設(shè)置是否正
確;
MCLK 的頻率配置是否正確;
sensor 驅(qū)動(dòng)的sensor_g_mbus_config() 函數(shù)配置為DVP sensor,type 需要設(shè)置為V4L2_MBUS_PARALLEL;
確定輸出的data 是高8 位、高10 位,確定硬件引腳配置沒有問(wèn)題;
示波器測(cè)量VSYNC、HSYNC 有沒有波形輸出,這兩個(gè)標(biāo)記著有一場(chǎng)數(shù)據(jù)、一行數(shù)據(jù)信號(hào)產(chǎn) 生;
測(cè)量data 腳有沒有波形,電壓幅值是否正常;
如果沒有波形,檢查一下sensor 的寄存器配置,看看有沒有軟件復(fù)位的操作,如果有,在該寄存器配置后面加上”{REG_DLY,0xff}“進(jìn)行相應(yīng)的延時(shí),防止在
軟件復(fù)位的時(shí)候,sensor還沒有準(zhǔn)備好就I2C 配置寄存器;
如果上面都還是沒有接收到數(shù)據(jù),那么在sensor 的驅(qū)動(dòng)文件,有以下配置,這三個(gè)宏定義的具體值。每個(gè)都有兩種配置,將這三個(gè)宏的配置兩兩組合,共8 種
配置,都嘗試一下;
#define VREF_POL V4L2_MBUS_VSYNC_ACTIVE_HIGH #define HREF_POL V4L2_MBUS_HSYNC_ACTIVE_HIGH #define CLK_POL V4L2_MBUS_PCLK_SAMPLE_RISING
6.4.2 mipi sensor
如果mipi sensor 沒有正常出圖,做以下debug 操作:
mipi 接口和主控板子連接不要飛線,mipi 信號(hào)本身就是高頻差分信號(hào),布線時(shí)都要求高,飛線更會(huì)影響其信號(hào)質(zhì)量,導(dǎo)致無(wú)法正常接收數(shù)據(jù);
確認(rèn)sensor 驅(qū)動(dòng)設(shè)置的mipi 格式,同樣是查看sensor_g_mbus_config() 函數(shù)(lane 和通道數(shù));
示波器測(cè)量mipi 接口的data 線、時(shí)鐘線,看看有沒有數(shù)據(jù)輸出;
檢查一下寄存器配置方面有沒有軟件復(fù)位的,增加相應(yīng)的延時(shí);
和模組廠商確認(rèn)sensor 驅(qū)動(dòng)中對(duì)應(yīng)分辨率的sensor_win_sizes 以下參數(shù)配置是否與寄存器組配合的,因?yàn)檫@些參數(shù)將會(huì)影響mipi 接收數(shù)據(jù);
.hts = 3550, .vts = 1126, .pclk = 120 * 1000 * 1000, .mipi_bps = 480 * 1000 * 1000,
上面的hts,又稱line_length_pck,VTS 又稱frame_length_lines,與寄存器的值要一致,Pclk(Pixel clock) 的值由PLL 寄存器計(jì)算得出,可簡(jiǎn)單計(jì)算,pclk = hts ×
vts × fps;而mipi_bps 為mipi 數(shù)據(jù)速率,mipi_bps = hts × vts × fps ×(12bit/10bit/8bit)/ lane。
有些sensor 的datasheet 沒有標(biāo)注hts 和vts 的,但是他們有H Blanking 和Vertical blanking,他們的轉(zhuǎn)換公式是:
hts = H Blanking + output_width
vts = Vertical blanking + output_height
Output_width 就是輸出的一行的大小,output_height 就是輸出的一列的大小。
gc 廠的sensor,vts = VB + win_height + 16;VB 和win_height 都是可以從寄存器中獲取得到的,注意,win_height 是寄存器值,而不是輸出的高。
6.4.3 其他注意事項(xiàng)
6.4.3.1 R311、MR133
sensor_sel
在vin 框架中,sys_config.fex 有以下配置:
[vind0/sensor0] ... [vind0/sensor1] ... [vind0/vinc0] vinc0_used = 1 vinc0_csi_sel = 0 vinc0_mipi_sel = 0 vinc0_isp_sel = 0 vinc0_rear_sensor_sel = 0 vinc0_front_sensor_sel = 0 vinc0_sensor_list = 0
在這里主要是需要注意vinc0_rear_sensor_sel 和vinc0_front_sensor_sel 的配置,當(dāng)它們都配置為0,表明vind0/vinc0 配置的video0 節(jié)點(diǎn),使用的是
vind0/sensor0 節(jié)點(diǎn)中配置的sensor 輸出圖像數(shù)據(jù);當(dāng)它們配置為0、1,表明vind0/vinc0 配置的video0 節(jié)點(diǎn),可以使用vind0/sensor0 和vind0/sensor1 兩個(gè)
sensor 輸出圖像數(shù)據(jù),可以通過(guò)ioctl 的VIDIOC_S_INPUT 的index 選擇使用哪個(gè)sensor 的輸出;當(dāng)它們都配置為1 的時(shí)候,表明vind0/vinc0 配置的video0 節(jié)
點(diǎn),使用的是vind0/sensor1 的輸出。
mipi AB 配置
mipi 配置方面,還有一個(gè)需要注意的,該部分在R311、MR133 平臺(tái)才有這種情況。一般情況,我們使用的是MCSIB 組的mipi 接口,這個(gè)按照一般配置使用即
可,MCSIA、MCSIB,這兩個(gè)會(huì)在原理圖上表明使用的是哪一組接口,如果單獨(dú)使用MCSIA 組的mipi 接口,在sys_config.fex 中配置如下:
由于只是使用MCSIA,所以應(yīng)該配置的是[vind0/sensor1] 組sensor,vinc0_rear_sensor_sel 和 vinc0_front_sensor_sel 都配置為1. [vind0/vinc0] vinc0_used = 1 vinc0_csi_sel = 0 vinc0_mipi_sel = 0 vinc0_isp_sel = 0 vinc0_rear_sensor_sel = 1 vinc0_front_sensor_sel = 1 vinc0_sensor_list = 0
-
Linux
+關(guān)注
關(guān)注
87文章
11345瀏覽量
210399 -
開發(fā)指南
+關(guān)注
關(guān)注
0文章
34瀏覽量
7569 -
Camera
+關(guān)注
關(guān)注
0文章
79瀏覽量
20899 -
Tina
+關(guān)注
關(guān)注
2文章
45瀏覽量
17027
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
Tina_Linux系統(tǒng)裁剪開發(fā)指南
Rockchip Linux SDK uboot logo開發(fā)指南
Linux的平臺(tái)下Mini210S裸機(jī)程序開發(fā)指南
![<b class='flag-5'>Linux</b>的平臺(tái)下Mini210S裸機(jī)程序<b class='flag-5'>開發(fā)指南</b>](https://file.elecfans.com/web2/M00/49/36/poYBAGKhwI6AWG-4AAA6tsuLilA249.png)
Rockchip Linux SDK的開發(fā)指南的詳細(xì)資料說(shuō)明
![Rockchip <b class='flag-5'>Linux</b> SDK的<b class='flag-5'>開發(fā)指南</b>的詳細(xì)資料說(shuō)明](https://file.elecfans.com/web1/M00/B2/FE/o4YBAF4YREKAQ21mAARUn4hgC2A794.png)
Tina Linux圖形系統(tǒng)開發(fā)指南
![<b class='flag-5'>Tina</b> <b class='flag-5'>Linux</b>圖形系統(tǒng)<b class='flag-5'>開發(fā)指南</b>](https://file.elecfans.com//web2/M00/95/BB/poYBAGQFVyCAYfqiAABAKmgwy7Y112.jpg)
評(píng)論