这篇文章主要介绍数据流这边Camera ISP这块所遇到的问题,主要介绍bus overflow和sof freeze;

(一)bus overflow

  摄像头传感器时钟通道(即 MIPI DDR 时钟)的工作频率与激活的数据通道数决定摄像头传感器在指定操作模式下的总数据传输速率(吞吐量)。每个通道的数据传输速率是 MIPI DDR 时钟速度的两倍。例如,工作在 200 MHz MIPI DDR 时钟频率和 4 个激活通道下的摄像头传感器的总数据传输速率为 1600 Mbps(每个通道的数据传输速率为 200 * 2 = 400 Mbps)。

  每个帧的分辨率、额外/虚拟像素/线数、水平消隐、垂直消隐、MIPI 包开销、每像素位数、数据格式、内部是否存在多个交错数据流以及每个流的数据传输速率/开销等,都会影响数据传输速率。指定工作模式下初步摄像头调通,计算:X = 帧宽 * (帧高垂直消隐) 每像素位数 * 每秒帧数 * (MIPI 协议和其他数据流的开销)在 VFE 时钟优化中为给定的 MSM 找到大于 X 的最接近的值作为 VFE 时钟的初始值。

  在标称时钟模式下,比如MSM8909的VFE最大速度为266MHz每条MIPI通道的PHY限制为1.5 Gbps (1.5 * 109 bps),由于存在MIPI/空白开销(约15-25%,各传感器的具体数值有所不同),实际帧数据吞吐量略少于预期原图拍摄接口数据传输速率与VFE时钟无关在4通道PHY接口上,每条通道的最大数据为(266 x bpp)/通道数;bpp → 每像素的传感器输出位数对于每通道10位数据传输速率 - (266*10)/4 - 665 Mbps;

  当我们VFE 时钟设置为小于传感器输出MIPI的数据传输速率时,将出现溢出bus overflow;

502:        pr_err_ratelimited("%s: image master 0 bus overflow\n",
507:        pr_err_ratelimited("%s: image master 1 bus overflow\n",
512:        pr_err_ratelimited("%s: image master 2 bus overflow\n",
517:        pr_err_ratelimited("%s: image master 3 bus overflow\n",
522:        pr_err_ratelimited("%s: image master 4 bus overflow\n",
527:        pr_err_ratelimited("%s: image master 5 bus overflow\n",
532:        pr_err_ratelimited("%s: image master 6 bus overflow\n",

  增大VFE时钟可防止溢出发生。要更改VFE时钟,需打Vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/sensor_libs/xxxx/ xxxx_lib.c文并编辑 op_pixel_clk 参数。

  选择正确的 VFE 时钟非常重要。VFE 时钟频率应足够高以匹配传感器输出端的数据速率(即传感器输出帧 x 帧/s),否则可能会引起 ISPIF 溢出。不过也不应设置过高的频率。设置过高的 VFE 时钟频率会导致两类问题: 
1. 由于可能填充内部 VFE 输出缓存(也称为统一缓存),总线溢出的几率增大。 
2. 如果 VFE 时钟频率较高,会导致功耗增大。

A. 检查与 VFE 总线溢出相关的总线时钟

  当过多的 VFE 数据流量以超过可用总线带宽的速率产生时,会导致 VFE 总线溢出错误。解决该问题的一种可行方法是检查能否通过设置更高的总线时钟频率来增加总线带宽。例如在 MSM8916 芯片组中,VFE 生成处理后的输出帧到系统 NoC (SNoC) 总线。数据流随后被转发到总线集成内存控制器 (BIMC) 总线,暂时保存在 DDR 内存中。VFE 生成的数据流将在这两条总线形成的路径上运行。因此,SNoC 和 BMIC 总线都必须进行检查。adb shell 脚本每隔一秒会转储 SNoC 和 BIMC 时钟频率。

#adb shell "while true; do cat /d/clk/snoc_clk/measure; cat /d/clk/bimc_clk/measure; echo '-----'; sleep 1; done"

200001391
748805675
-----

B. 将时钟总线设为最大频率

  VFE 总线溢出分类的第一步是检查能否通过设置更高总线时钟频率来增加可用总线带宽。增加总线带宽后,查看 VFE 总线溢出问题是否得以解决。

adb root
adb shell sleep 1
adb shell mount -t debugfs none /d
adb shell echo "22 > /d/msm-bus-dbg/shell-client/mas"
adb shell echo "512 > /d/msm-bus-dbg/shell-client/slv"
adb shell echo "0 > /d/msm-bus-dbg/shell-client/ab"
adb shell echo "6400000000 > /d/msm-bus-dbg/shell-client/ib"
adb shell echo "1 > /d/msm-bus-dbg/shell-client/update_request"

  以上脚本尝试设置从 MDP(显示硬件模块)到 DDR 内存路径中的所有总线。不管摄像头如何操作,通过从 MDP 显示屏侧(ID 22 表示 MDP)请求高带宽,总线会始终保持最大时钟频率。选择显示屏 (MDP) 而不是摄像头 ISP (VFE) 的原因是显示屏 MDP 一直运行,而摄像头驱动程序在启动和停止时会覆盖摄像头表决。而且这种更简单的测试场景能解决所有起伏问题。通过以上测试,再次检查总线时钟是否增加到最大频率。应用上述设置后,SNoC 和BIMC 时钟频率分别应为 266 MHz 和 533 MHz(不同平台参数不一致,对应不同的性能等级)。

  如果没有任何改进,可尝试按以下步骤在 CPU 高性能模式下运行系统并设置最大总线时钟频率:

adb shell "echo 1 > /sys/devices/system/cpu/cpu1/online"

adb shell "echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"

C. 从 VFE 检查 AB/IB 表决带宽

在检查 VFE 侧要求的总 AB 和 IB 带宽时,确保摄像头已启动。
运行以下命令:
adb root
adb shell cat /d/msm-bus-dbg/client-data/msm_camera_isp

1223.023734896
curr   : 1
masters: 29  
slaves : 512  
ab     : 100000000  
ib     : 100000000

1223.024648282
curr   : 2
masters: 29  
slaves : 512  
ab     : 200000000  
ib     : 200000000

1228.214552238
curr   : 1
masters: 29  
slaves : 512  
ab     : 921819520  
ib     : 921819520

  输出第一行中的数字 351.706326427 表示发出请求时的内核时间戳。Master(s) 29 表示总线流量来自 VFE,Slave(s) 512 表示总线流量的目的地设为 memory;AB/IB VFE 发出的最终宽带请求分别为 930 MBps/1.62 GBps。

D. 识别 AXI 配置

  VFE 总线溢出日志经常始于表明某个具体写入主控上出现溢出,因此内核日志显示的首个溢出实例就显得非常重要,可以帮助确认溢出来源。在 VFE 总线溢出分析(特别是 ZSL 预览场景)过程中,通常要求找到具体图像写入主器件和预览/快照输出帧面的映射关系,以确定要优化的数据流。例如,确定预览数据流的总线溢出后,仅关注预览数据流。在内核中添加以下调试日志消息,并在 Salesforce 用列系统分享该日志。

--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -1384,8 +1384,10 @@ static int  msm_isp_axi_stream_enable_cfg(
        if (stream_info->state == START_PENDING ||
                stream_info->state == RESUME_PENDING) {
                enable_wm = 1;
+        pr_err("__debug__: WM[%d] ENABLE, src = %d, max_width = %u\n",stream_info->wm[i], stream_info->stream_src, stream_info->max_width);
        } else {
                enable_wm = 0;
+        pr_err("__debug__: WM[%d] DISENABLE, src = %d, max_width = %u\n",stream_info->wm[i], stream_info->stream_src, stream_info->max_width);
        }

E. 增加 AB/IB

  如果将时钟总线设为最大频率,能够解决buffer ovflow的问题,可以尝试增加总体总线时钟频率,总线时钟频率只会在摄像头工作时增加,逐渐增加或将原来数字乘2或逐渐减少来找出最优数量。

//kernel/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c

62 #define MSM_ISP_MIN_AB 100000000                                                                                                                   
 63 #define MSM_ISP_MIN_IB 100000000

F. 提高VFE 突发长度变化

  尽管最优 VFE 突发长度没有明确答案,但改变 VFE 突发长度也能够减少 VFE 总线溢出问题。

28 #define VFE40_BURST_LEN 1                                                                                                                         
  29 #define VFE40_BURST_LEN_8916_VERSION 2
  30 #define VFE40_BURST_LEN_8952_VERSION 3

33 #define VFE40_STATS_BURST_LEN 1
  34 #define VFE40_STATS_BURST_LEN_8916_VERSION 2

(二)sof freeze

  sof freeze(SOF:start of frame)表示ISP这边没有收到sensor这边输出的图像帧数据,这时必须检查 CSID/CSIPHY/CAMIF是否出错。有专门建立了thread来负责SOF的检测,start_sof_check_thread() -> mct_bus_sof_thread_run(),log当中会有下面的错误发出:

// msm-3.18/drivers/media/platform/msm/camera_v2/msm.c

803     case MSM_CAM_V4L2_IOCTL_NOTIFY_DEBUG: {
 804         if (event_data->status) {
 805             pr_err("%s:Notifying subdevs about potential sof freeze\n",
 806                 __func__);

  首先看能否dump出现数据:

/*
        0 Disabled; this value is set by default
        2 Dump preview frames
        8 Dump snapshot frames
        16 Dump video frames
        */

adb root
        adb shell setprop persist.camera.isp.dump 8
        adb shell chmod 777 /data

   Verifying the VFE hardware configuration

In the msm_isp_axis_util.c file, locate the following code snippet:

if (vfe_dev->dump_reg)
     msm_camera_io_dump_2(vfe_dev->vfe_base, 0x900);

Replace it with:

24 if (1)
    25 msm_camera_io_dump_2(vfe_dev->vfe_base, 0x900);
  若声明的传感器输出大小与 VFE 实际接收到的传感器输出大小之间不匹配,将发生 CAMIF错误。

//mm-camera/mm-camera2/media-controller/modules/iface2/iface_util.c

8878 static void iface_util_dump_camif_cfg(struct msm_vfe_input_cfg *input_cfg)                                                                       
 8879 {
 8880   struct msm_vfe_pix_cfg *pix_cfg = NULL;
 8881 
 8882   if (input_cfg == NULL)
 8883     return;
 8884 
 8885   pix_cfg = &input_cfg->d.pix_cfg;
 8886   IFACE_HIGH("=====Camif DUMP cfg for PIX interface====\n");
 8887   IFACE_HIGH("camif input type = %d(MIPI=3), op_pix_clk = %d\n",
 8888     pix_cfg->camif_cfg.camif_input, input_cfg->input_pix_clk);
 8889   IFACE_HIGH("camif pix_pattern(RGRG-0/GRGR-1/BGBG-2/GBGB-3) = %d\n",
 8890     pix_cfg->pixel_pattern);
 8891   IFACE_HIGH("camif first_pix = %d, last_pix = %d\n",
 8892     pix_cfg->camif_cfg.first_pixel, pix_cfg->camif_cfg.last_pixel);
 8893   IFACE_HIGH("camif first_line = %d, last_line = %d\n",
 8894     pix_cfg->camif_cfg.first_line, pix_cfg->camif_cfg.last_line);
 8895   IFACE_HIGH("camif pixels_per_line = %d, lines_per_frame = %d\n",
 8896     pix_cfg->camif_cfg.pixels_per_line, pix_cfg->camif_cfg.lines_per_frame);
 8897   IFACE_HIGH("camif irq subsample pattern = %x, period = %d sof_step %d\n",
 8898     pix_cfg->camif_cfg.subsample_cfg.irq_subsample_pattern,
 8899     pix_cfg->camif_cfg.subsample_cfg.irq_subsample_period,
 8900     pix_cfg->camif_cfg.subsample_cfg.sof_counter_step);
 8901 }

  将调试消息中指示的帧大小与 ISP 传感器的帧大小进行比较。在以下 CAMIF 错误示例中,错误状态 0x9a70a00 表示 ISP 接收帧的大小为 2471x2560(0x9a7 = 2471,0xa00 = 2560)。

01-01 08:07:20.175 E/mm-camera( 302): isp_hw_camif_dump_cfg: camif
input_format= 0 
01-01 08:07:20.175 E/mm-camera( 302): isp_hw_camif_dump_cfg: camif
last_pix = 6527 
01-01 08:07:20.175 E/mm-camera( 302): isp_hw_camif_dump_cfg: camif
last_line = 0 
01-01 08:07:20.175 E/mm-camera( 302): isp_hw_camif_dump_cfg: camif
lines per frame = 2448 
01-01 08:07:24.335 E/klogd (640): [81.563301]
msm_vfe40_process_error_status: camif error status: 0x9a70a00

如果存在不匹配,则根本原因可能如下:

  检查传感器设置是否正确,是否满足分辨率大小的要求。例如,传感器的输出大小配置为 12 MB,但 ISP 的接收大小却配置为 8 MB。可能有些传感器无法确保在新分辨率设置发送至传感器后,最初的帧大小能够满足要求。在这种情况下,需要与传感器供应商一起解决此问题。

高通Camera 驱动调试要点(二)相关推荐

  1. 高通Camera 驱动调试要点(一)

    高通Camera 驱动调试要点(一)_bobuddy的博客-CSDN博客_camera 驱动调试

  2. 高通camera驱动 camx相关内容 (二)

    camx 编译环境中的driver文件的相关位置 sensor driver XML files : chi-cdk/vendor/sensor/default/<sensor_name> ...

  3. android4.3.0 camera,4.3、高通camera驱动简析

    1.Sensor slave配置 结构体msm_camera_sensor_slave_info定义在media/msm_cam_sensor.h中: struct msm_camera_sensor ...

  4. 高通camera驱动分析

    点击打开链接 1.Sensor slave配置 结构体msm_camera_sensor_slave_info定义在media/msm_cam_sensor.h中: struct msm_camera ...

  5. 高通Camera驱动(2)-- openinitialize

    码字不易,多谢支持 前文回顾 简单介绍Camx架构,接下来看下initialize流程 一.open&initialize 流程 1.1 原文解读 * 1. Framework calls c ...

  6. 高通Camera驱动(3)-- configure_streams

    前文回顾 上一篇文章,简单讲述initialize的过程 一. configure_streams 流程 1.1 原文解读 * 4. The framework calls camera3_devic ...

  7. 高通音频驱动调试(十七)

    android audio 生产者与消费者 简介 全面接触生产者/消费者问题是在操作系统原理中,并发性原理讨论的问题 生产者/消费者问题.最近的工作偏向音频,接着上一篇文章,用生产者,消费者模型来理解 ...

  8. 高通Camera驱动(5)-- notify

    前文回顾 上一篇文章,简单讲述process_capture_request的过程 一. notify 流程 1.1 原文解析 * 9. When the capture of a request b ...

  9. 高通camera调试

    高通camera驱动分析 ./qcom/proprietary/mm-still/codec_v1/omx/jpeg_encoder/Android.mk:15:CHROMATIX_VERSION : ...

最新文章

  1. EL之RF(随机性的Bagging+DTR):利用随机选择属性的bagging方法解决回归(对多变量的数据集+实数值评分预测)问题
  2. mysql8.0其他机器访问_论文导读|基于机器学习的高速缓存预取
  3. TRDD got lost again
  4. 程序员必备的 10 大 GitHub 仓库
  5. Java:在Runnable中处理RuntimeException
  6. QPW 手机短信验证码发送日志表(tf_sms_send_log)
  7. 【练习手记】【多题合集】用树状数组做线段树练习1、2、3
  8. ubuntu16.04+opencv3.1配置
  9. 【操作系统/OS笔记13】信号量、PV操作、管程、条件变量、生产者消费者问题
  10. python将txt文档中的内容按字母顺序进行排序,并存入txt中
  11. 介绍:native2ascii命令用法详解
  12. 用php编写一个同学录,PHP+DBM的同学录程序(2)
  13. 笔记本手机都能用,轻松实现100W快充,AOHi 100W氮化镓PD 充电器体验
  14. java使用freemark实现word(.doc/.docx)/pdf生成和导出(附源码和模板文件)
  15. 智能开关继电器-选型篇2
  16. 计算机对幼儿教育发展的优点,音乐教育对幼儿发展的影响
  17. 元器件温度系数(ppm/℃)是什么?
  18. 没有windows安装光盘怎么修复计算机,教你用Windows XP的安装盘修复系统
  19. Java NIO三大核心之缓冲区Buffer概述
  20. BLAM源码解析(一)—— 模块初始化

热门文章

  1. ImHex:十六进制编辑器
  2. 2020年云市场占有率-数据来源Canalys
  3. 历年计算机二级等级考试真题,[历年全国计算机等级考试二级QBASIC部分真题]全国计算机二级...
  4. 基于PHP企业合同管理系统
  5. Word的文件被锁定,无法编辑的解决办法
  6. 一张图介绍mysql执行过程
  7. 一段MySQL的小总结
  8. Chisel 手册(中文part2)
  9. jupyter下的ipynb文件转换为pdf并且完全保留图片
  10. 一木.溪桥学Python-13:多继承、多态、常用魔法方法、单例模式