TDA4VM-Camera调试笔记

虚拟通道调试日志

20230321

media_entity_remote_pad

如何使用 media_pad *media_entity_remote_pad(const struct media_pad *pad) 函数调用

该函数的作用是获取给定媒体 pad 的远端 pad。

使用方法如下:

  1. 在你的代码中包含 "media/media-entity.h" 头文件。
  2. 定义一个 media_pad 类型的指针变量,指向你要获取远端 pad 的媒体 pad。
  3. 调用 media_entity_remote_pad() 函数,传入该媒体 pad 的指针。
  4. 函数返回一个 media_pad 类型的指针,该指针指向该媒体 pad 的远端 pad。

示例代码:

#include <media/media-entity.h> // 假设有一个媒体 pad 的指针变量叫做 pad media_pad *remote_pad = media_entity_remote_pad(pad); if (remote_pad) {  // 成功获取远端 pad  // ... } else {  // 获取远端 pad 失败  // ... }

注意:

  • 如果该媒体 pad 没有远端 pad,则函数返回 NULL。
  • 在使用返回的远端 pad 前,要确保该 pad 存在并且有效。

调试日志

20230314

换另一块TDA4VM

换另一块开发,就可以正常读出图像数据

读取0x04504048(CSI_RX_IF_VBUS2APB_DPHY_STATUS) = 0x00333306/0x00222206正常

捕获数据流

v4l2-ctl -d /dev/video2 --set-fmt-video=width=1920,height=1080,pixelformat=UYVY --stream-mmap --stream-count=1000

图片数据分析

YUVEye官方下载-ZigZagSin

v4l2-ctl --device /dev/video2 --stream-mmap --stream-to=frame.raw --stream-count=1

convert -size 1920x1080 -depth 16 uyvy:frame.raw frame.png

linux/v4l2 – Gateworks

直接显示

gst-launch-1.0 v4l2src device="/dev/video2" ! video/x-raw, width=1920, height=1080, format=UYVY ! autovideosink

正常显示如下

soc端csi抓出来图像纯绿色

max9296+max9295调试总结_max9295a_xuecz1230的博客-CSDN博客

出图

执行

gst-launch-1.0 v4l2src device="/dev/video2" ! video/x-raw ,width=1920, height=1080, framerate=30/1 ! waylandsink
sleep 1
gst-launch-1.0 v4l2src device="/dev/video2" ! video/x-raw, width=1920, height=1080, format=UYVY ! autovideosink

a

20230313

寄存器状态值参考

参考TDA4VM: CSI-RX clock resistor calibration problem - Processors forum - Processors - TI E2E support forums

TDA4VM: CSI-RX Lane Speed Setting - Processors forum - Processors - TI E2E support forums

TDA4VM: How to configure csi? - Processors forum - Processors - TI E2E support forums

读 0458 0C10 值 0x00000039意味着:DPHY_RX 处理停止状态

Receives DPHY_RX_VBUS2APB_LANE state status RxStopStateClk_cl_l

正常工作,值是0x29或0x2d

DPHY正常状态

0x04590B00(DPHY_RX_VBUS2APB_PCS_TX_DIG_TBIT0) = 0x000001ef
0x04504040(CSI_RX_IF_VBUS2APB_DPHY_LANE_CONTROL) = 0x0001F01F
0x04504048(CSI_RX_IF_VBUS2APB_DPHY_STATUS) = 0x00333306/0x00222206
0x04504060(CSI_RX_IF_VBUS2APB_INTEGRATION_DEBUG) = 0x10000000 // WAIT_FOR_PACKET
0x04504074(CSI_RX_IF_VBUS2APB_ERROR_DEBUG) = 0x0F00005E/0x0F00015E/0x0F00025E/0x0F00035E// DT:0K vc:错误
0x04504100(CSI_RX_IF_VBUS2APB_STREAM0_CTRL) = 0x00000001
0x04504104(CSI_RX_IF_VBUS2APB_STREAM0_STATUS) = 0x80000111

0x04580C10 ( DPHY_RX_VBUS2APB_ISO_PHY_ISO_CL_CNTRL_L ) = 0x00000029 //normal

目前的状态

0x04590B00(DPHY_RX_VBUS2APB_PCS_TX_DIG_TBIT0) = 0x000001ef
0x04504040(CSI_RX_IF_VBUS2APB_DPHY_LANE_CONTROL) = 0x0001F01F
0x04504048(CSI_RX_IF_VBUS2APB_DPHY_STATUS) = 0x00333307/0x00222207 //err
0x04504060(CSI_RX_IF_VBUS2APB_INTEGRATION_DEBUG) = 0x10000000
0x04504074(CSI_RX_IF_VBUS2APB_ERROR_DEBUG) = 0x00000000 //
0x04504100(CSI_RX_IF_VBUS2APB_STREAM0_CTRL) = 0x00000001
0x04504104(CSI_RX_IF_VBUS2APB_STREAM0_STATUS) = 0x80000111

0x04580C10 ( DPHY_RX_VBUS2APB_ISO_PHY_ISO_CL_CNTRL_L ) = 0x00000039

// DPHY_RX_VBUS2APB_LANE ULPS no active state status

0x04504000 (CSI_RX_IF_VBUS2APB_DEVICE_CONFIG) = 0x8C63164C

0x04504008 (CSI_RX_IF_VBUS2APB_STATIC_CFG) = 0x43210400 //normal is 0x43210410

bit 4 = Support extended VC, up to 16 virtual channels 读取出来为0,即没有16 VC???

参考

TDA4VM: tda4vm CSI_RX_1 cannot get yuv 422 8bit - Processors forum - Processors - TI E2E support forums

20230310

梳理设备树

参考

对比k3-j721e-cpb-csi2-ov5640设备的解析

fwnode_property_read_u32

fwnode_property_read_u32_array(const struct fwnode_handle *fwnode,

const char *propname, u32 *val, size_t nval)

从中读取带有@propname的 u32 属性数组@fwnode将它们存储到@val(如果找到)。

struct fwnode_handle *

fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,

struct fwnode_handle *prev)

* fwnode_graph_get_next_endpoint - Get next endpoint firmware node

* @fwnode: Pointer to the parent firmware node

* @prev: Previous endpoint node or %NULL to get the first

返回端点固件节点指针,如果没有更多端点,则返回 %NULL可用。

v4l2_fwnode_endpoint_parse

fwnode_handle_put

void fwnode_handle_put(struct fwnode_handle *fwnode)

删除对设备节点的引用

fwnode_graph_get_remote_endpoint

设备树问题

[PATCH v4 0/4] MAX9286 GMSL Support

[ 73.437451] cdns-csi2rx 4504000.csi-bridge: Driver cdns-csi2rx uses device fwnode, incorrect match may occur

驱动程序 cdns-csi2rx 使用设备 fwnode,可能会出现不正确的匹配

[ 73.447265] cdns-csi2rx 4504000.csi-bridge: Consider updating driver cdns-csi2rx to match on endpoints

考虑更新驱动程序 CDNS-csi2rx 以匹配终结点

思路:

sensor->9295->9296->soc

现在是将sensor->9295->9296抽象为一个设备

9296->soc

所以目前在设备树只关注了9296的设备节点

对比RTOS

/* Configure Rx Osc calibration feedback clock counter start values */

/* It is 500MHz / 6 */

#define DPHYRX_PSM_CLK_FREQ_MHZ (83.33)

重新验证这个参数

20230309

排查DPHY时钟

0x04504048

DPHY Clock lane Stop State

验证V4L2_CID_LINK_FREQ只是对时钟进行微调,在DHPY中实际已经做好了。

如果不设置V4L2_CID_LINK_FREQ或V4L2_CID_PIXEL_RATE,或者值设置过大,都会在这个函数phy_configure(csi2rx->dphy, &opts);报错

原因分析:目前SOC端没有检测到9296的时钟

验证一

6.7us

1920*2*8 = 30720

30720/4 = 7680

6700/7680 = 0.872

由于是双边沿,0.872*2 = 1.74

1/1.74 * 1000000000 = 574MHz

SOC还是没有检测到9296的时钟

验证二

SOC还是没有检测到9296的时钟

验证三

在9296中添加寄存器配置

/*per clk*/
    max9296_write(priv, 0x0331, 0x01);
    msleep(1);
验证四

开发板掉电重启后,读取地址

root@j7-evm:~# devmem2 0x04504048

/dev/mem opened.

Memory mapped at address 0xffffa7d16000.

Read at address 0x04504048 (0xffffa7d16048): 0x00222206

0010 0010 0010 0010 0000 0110

暴力验证
    priv->tx_link_freq[0] = 1148000000;//err
    priv->tx_link_freq[0] = 130000000;//err 307 207
    priv->tx_link_freq[0] = 150000000;//err
    priv->tx_link_freq[0] = 170000000;//err
    priv->tx_link_freq[0] = 190000000;//err
    priv->tx_link_freq[0] = 210000000;//err
    priv->tx_link_freq[0] = 230000000;//err
    priv->tx_link_freq[0] = 250000000;//err
    priv->tx_link_freq[0] = 270000000;//err
    priv->tx_link_freq[0] = 290000000;//err
    priv->tx_link_freq[0] = 310000000;//err
    priv->tx_link_freq[0] = 330000000;//err
    priv->tx_link_freq[0] = 350000000;//err
    priv->tx_link_freq[0] = 370000000;//err
    priv->tx_link_freq[0] = 390000000;//err
    priv->tx_link_freq[0] = 410000000;//err
    priv->tx_link_freq[0] = 430000000;//err
    priv->tx_link_freq[0] = 450000000;//err
    priv->tx_link_freq[0] = 470000000;//err
    priv->tx_link_freq[0] = 490000000;//err
    priv->tx_link_freq[0] = 510000000;//err
    priv->tx_link_freq[0] = 530000000;//err
    priv->tx_link_freq[0] = 550000000;//err
    priv->tx_link_freq[0] = 570000000;//err
    priv->tx_link_freq[0] = 590000000;//err
    priv->tx_link_freq[0] = 600000000;//err

需要确定是否写的是那个值,还需要判断0x04504048的值是否正确

dtb反编译为dts

kernel_dir/script/dtc/dtc -I dtb -O dts -o xxx.dts xxx.dtb

dtb通过dtc转换为dts后是一个全的device tree,因为之前#include "xxx.dtsi"中的内容也一起在反编译出来的dts中了,所有的内容都集中在一个dts文件中了。

/home/wp/ti-processor-sdk-linux-j7-evm-08_05_00_08/board-support/linux-5.10.153+gitAUTOINC+90c3a58fd2-g90c3a58fd2/scripts/dtc/dtc -I dtb -O dts -o

生成拓扑图

Graphviz插件需要先注册才能使用。键入dot -c进行注册。您可以通过键入dot -v进行验证

dot -Tpng InputFile.dot -o OutputFile.png

  1. media-ctl --print-dot> media0.dot
  2. media-ctl -d /dev/media1 --print-dot> media1.dot

验证960生成的原生拓扑

修改k3-j721e-fpdlink-cpb-fusion.dtbo地址为48 40

进入boot模式

setenv name_overlays k3-j721e-fpdlink-cpb-fusion.dtbo k3-j721e-fpdlink-imx390-rcm-0-0.dtbo
boot
media-ctl --print-dot> media0.dot
dot -Tpng media0.dot -o OutputFile.png

结果:9296与960生成同样的拓扑结构图

提问

查看寄存器手册相关的DPHY Clock

20230307

确认上电时序

priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable",
                           GPIOD_OUT_HIGH);
    if (IS_ERR(priv->gpiod_pwdn))
        return PTR_ERR(priv->gpiod_pwdn);


    gpiod_set_consumer_name(priv->gpiod_pwdn, "max9296-pwdn");
    gpiod_set_value_cansleep(priv->gpiod_pwdn, 1);


    /* Wait at least 4ms before the I2C lines latch to the address */
    if (priv->gpiod_pwdn)
        usleep_range(4000, 5000);


    ret = max9296_register_gpio(priv);
    if (ret)
        goto err_powerdown;


    priv->regulator = devm_regulator_get(&client->dev, "poc");
    if (IS_ERR(priv->regulator)) {
        if (PTR_ERR(priv->regulator) != -EPROBE_DEFER)
            dev_err(&client->dev,
                "Unable to get PoC regulator (%ld)\n",
                PTR_ERR(priv->regulator));
        ret = PTR_ERR(priv->regulator);
        goto err_powerdown;
    }

理清上电时序是否必须?

基于上面修改验证结果如下:

总结:目前上电时序对相机出数据没有影响

确认ti-CSI2的buf是否有数据

验证j721e-csi2rx中的数据

计算像素速率和总线频率

验证

priv->pixelrate = v4l2_ctrl_new_std(&priv->ctrls,
                        &max9296_ctrl_ops,
                        V4L2_CID_PIXEL_RATE,
                        1, INT_MAX, 1, 600000000);

输出

1920*1080 30fps raw16

pixel_rate = 2500*1120*30 = 8400 0000 ????

pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample

priv->pixelrate = v4l2_ctrl_new_std(&priv->ctrls,
                        &max9286_ctrl_ops,
                        V4L2_CID_PIXEL_RATE,
                        1, INT_MAX, 1, 50000000);

这里是跟dphy的时钟

为100MHz

总结:此参数不变

20230306

读取寄存器进行判断

9296 0x48

i2ctransfer -f -y 9 w2@0x48 0x01 0x2c r1

当9295起来后,配置完9296,才能读取

参考英伟达现有的9296-9295驱动

只有寄存器配置代码

验证V4L2_CID_PIXEL_RATE不同参数,产生的影响

测试一
priv->pixelrate = v4l2_ctrl_new_std(&priv->ctrls,
                        &max9296_ctrl_ops,
                        V4L2_CID_PIXEL_RATE,
                        1, INT_MAX, 1, 100000000);

输出:csi2rx_configure_external_dphy link_freq:200000000

测试二
priv->pixelrate = v4l2_ctrl_new_std(&priv->ctrls,
                        &max9296_ctrl_ops,
                        V4L2_CID_PIXEL_RATE,
                        1, INT_MAX, 1, 50000000);

csi2rx_configure_external_dphy link_freq:100000000

测试三
priv->pixelrate = v4l2_ctrl_new_std(&priv->ctrls,
                        &max9296_ctrl_ops,
                        V4L2_CID_PIXEL_RATE,
                        1, INT_MAX, 1, 800000000);

csi2rx_configure_external_dphy link_freq:1600000000

在这里返回错误

20230303

验证解串器生成16个虚拟通道

0x04504048

该值在 0x00333306 和 0x00222206 之间交替变化

这意味着车道正在切换,并且被CSIRX检测到。

继续验证

查看反序列化器设置并确认它以CSIRX中配置的正确速度输出?另外,请检查数据类型和虚拟通道号是否正确

确保在反序列化程序中正确配置了虚拟通道 ID 和数据类型。因为如果不匹配,CSIRX 将不会捕获帧。

您能否确保解串器中的输出配置正确,并确保解串器和传感器输出仅在流回调中启动,而不是在流回调之前启动

验证取消VM的虚拟通道

CSI2RX_STREAM_DATA_CFG_VC_ALL

读取VM的CSI2RX状态

内核调试devmem2,启动捕获数据命令后,读取状态值

CSI_RX_IF_VBUS2APB_MONITOR_IRQS

结果: STREAM 没有被使能?

CSI_RX_IF_VBUS2APB_DPHY_LANE_CONTROL

结果:DPHY的通道和时钟使能

CSI_RX_IF_VBUS2APB_DPHY_STATUS

结果:四个通道全部停了

CSI_RX_IF_VBUS2APB_DPHY_ERR_STATUS_IRQ

结果:没有显示中断错误

CSI_RX_IF_VBUS2APB_DPHY_ERR_IRQ_MASK_CFG

结果:没有显示错误掩码

CSI_RX_IF_VBUS2APB_INTEGRATION_DEBUG

结果:

CSI_RX_IF_ECC_SEC_STATUS_REG0

结果:

CSI_RX_IF_ECC_DED_STATUS_REG0

结果:

CSI_RX_IF_ECC_DED_ENABLE_SET_REG0

结果:

CSI_RX_IF_ECC_DED_ENABLE_CLR_REG0

结果:

CSI_RX_IF_ECC_AGGR_ENABLE_SET

结果:

CSI_RX_IF_ECC_AGGR_STATUS_SET

结果:

CSI_RX_IF_SHIM_CSIRX_ID

结果:

CSI_RX_IF_SHIM_VP0

结果:video port0端口配置为空?

CSI_RX_IF_SHIM_CNTL

结果:四个stream都处于空闲状态

CSI_RX_IF_SHIM_DMACNTX

结果:DMA使能, YVYU格式

CSI_RX_IF_SHIM_PSI_CFG0

结果:

CSI_RX_IF_VBUS2APB_STREAM0_MONITOR_FRAME

结果:没有最后一帧数据,也没有大小

CSI_RX_IF_VBUS2APB_STREAM0_STATUS

结果: Stream 是使能的

CSI_RX_IF_VBUS2APB_STREAM1_STATUS

结果: Stream 是使能的

CSI_RX_IF_VBUS2APB_STREAM2_STATUS

CSI_RX_IF_VBUS2APB_STREAM0_DATA_CFG

结果:虚拟通达?

CSI_RX_IF_VBUS2APB_STREAM0_FIFO_FILL_LVL

DPHY_RX_MMR_SLV_LANE

结果:表示公共组件的启动过程为完成,共同点已准备就绪。表示启动完成通用模块的过程。

下面是没有使用捕获命令

DPHY_RX_VBUS2APB_DL0_RX_DIG_TBIT33

结果:HS 数据期间同步检测 FSM 的当前状态接收模式或偏斜校准模式

DPHY_RX_VBUS2APB_DL0_RX_DIG_TBIT34

结果: lp_status 也是使能状态?

20230302

验证虚拟通道

VM这边是直接创建16个video节点,所以验证9296-9295配置为虚拟通道,验证VM是否收到数据。

相机那边也配置16个虚拟通道

验证后,依然没有数据

验证960

  1. 在启动期间,通过按任意键在u-boot提示符处停止并设置相机覆盖dtb:
setenv name_overlays k3-am625-sk-csi2-ov5640.dtbo 
boot
setenv name_overlays k3-am625-sk-csi2-ov5640.dtbo 
boot

2、重置默认环境变量

env default -f -a
saveenv

加载ds960后的结果

验证设置

验证方向

  • sink-pad的设置
  • link_freq的设置
  • 研究决定参考960-953
sink-pad的验证

grep -H '' /sys/class/video4linux/video*/name

link_freq的验证

修改为1GHz,依然没有数据

20230301

调研如何设置sink-pad

7.5. i.MX Video Capture Driver — The Linux Kernel documentation

Search — The Linux Kernel documentation

修改max9296的link_freq,导致Failed to configure external DPHY

修改

结果

参考

1.14. Image Process Control Reference — The Linux Kernel documentation

7. MIPI CSI-2 — The Linux Kernel documentation

max9296+max9295驱动调试-网络知识

1.14. Image Process Control Reference — The Linux Kernel documentation

V4L2_CID_LINK_FREQ

数据总线频率。数据总线频率与媒体总线像素代码、总线类型(每个样本的时钟周期)一起定义了像素阵列中的像素速率(V4L2_CID_PIXEL_RATE),如果设备不是图像传感器,则可能定义其他像素速率()。帧速率可以通过像素时钟、图像宽度和高度以及水平和垂直消隐来计算。虽然像素速率控制可以在包含像素数组的子开发中以外的其他位置定义,但无法从该信息中获取帧速率。这是因为只有在像素阵列上,才能假设垂直和水平消隐信息是精确的:像素数组中不允许其他消隐。通过选择所需的水平和垂直消隐来选择帧速率。此控件的单位是 Hz。

V4L2_CID_PIXEL_RATE

子开发源垫中的像素率。此控件是只读的,其单位为像素/秒。Ex mipi 总线:pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample位深

mipi_link_freq = w*h * fps * bits_per_sample / nr_of_lanes / 2

pixel_clk_rate = w*h * fps

设置参数

max9296配置1920*1080,CSI2RX配置1920*1080

其中修改MAX9296_DPLL_FREQ 为2000,原来为1000

结果

依旧没有数据,是什么原因导致的呢?

确认i2c-16的操作

怀疑:是因为在启流的时候,手动配置脚本,导致没有及时使能camera。

regmap_bulk_write

regmap_bulk_read

在启流的时候,使能camera

可以使用regmap_read/regmap_write读写16

验证只配置9296

成功在max9296驱动中配置相关寄存器,但是依旧读取不到数据

操作流程:将9296配置加入驱动,先加载驱动,脚本使能9295,再启动获取数据命令(即打开数据流),示波器检测有数据输出,但是软件依然没有捕获到数据

验证link_freq是什么参数导致改变的

这是max9286输出的link_freq

max9286配置1920*1080,CSI2RX配置640*480

max9286配置640*480,CSI2RX配置640*480

验证后在这里修改会导致link_freq改变

怀疑是link_freq和9296对不上

9296为1.3GHz

SOC的DPHY为500MHz

其中修改MAX9296_DPLL_FREQ 为2500,原来为1000

修改MAX9296_DPLL_FREQ 为2600,link_freq改为

问题猜测:是因为像素格式的配置

将cdns-csi2rx和max9296更改为1920*1080

问题依旧

参考ub960-ub953

由于需要配置9296-9295,所以参考ub960-ub953驱动更改。

之前的max9286只有对解串器进行配置

20230228

使能配置max9296

设备树I2C-6改为0x48地址,在驱动中读错误

注意:

驱动里面不能执行sh脚本

驱动max9286里面的I2C是8位操作:确认一下9286里面的I2C是8位操作?

regmap_read可以读写16,但是函数没有打开

尝试使用i2c_smbus_read_byte

max96721

max96712.c - drivers/staging/media/max96712/max96712.c - Linux source code (v5.17.15) - Bootlin

跟现在max9286的驱动相差不大

YUV对应的格式标识符

4.13.3.4.1. Media Bus Formats — The Linux Kernel documentation

static void max9286_init_format(struct v4l2_mbus_framefmt *fmt)
{
    fmt->width      = 1920;
    fmt->height     = 1080;
    fmt->code       = MEDIA_BUS_FMT_UYVY8_2X8;
    fmt->colorspace     = V4L2_COLORSPACE_SRGB;
    fmt->field      = V4L2_FIELD_NONE;
    fmt->ycbcr_enc      = V4L2_YCBCR_ENC_601;
    fmt->quantization   = V4L2_QUANTIZATION_LIM_RANGE;
    fmt->xfer_func      = V4L2_XFER_FUNC_SRGB;
}
static int csi2rx_init_cfg(struct v4l2_subdev *subdev,
               struct v4l2_subdev_state *state)
{
    struct v4l2_subdev_format format = {
        .which = state ? V4L2_SUBDEV_FORMAT_TRY
            : V4L2_SUBDEV_FORMAT_ACTIVE,
        .pad = CSI2RX_PAD_SINK,
        .format = {
            .width = 1920,
            .height = 1080,
            .code = MEDIA_BUS_FMT_UYVY8_2X8,
            .field = V4L2_FIELD_NONE,
            .colorspace = V4L2_COLORSPACE_SRGB,
            .ycbcr_enc = V4L2_YCBCR_ENC_601,
            .quantization = V4L2_QUANTIZATION_LIM_RANGE,
            .xfer_func = V4L2_XFER_FUNC_SRGB,
        },
    };


    return csi2rx_set_fmt(subdev, state, &format);
}
查看对应节点

grep -H '' /sys/class/video4linux/video*/name

环宇

技术论坛

TDA4VM: Whether the CSI-TX and CSI-RX share computation resource? - Processors forum - Processors - TI E2E support forums

TDA4VM: How to stream camera video to linux? - Processors forum - Processors - TI E2E support forums

LINUX-SDK 8.1版本就开始支持LIUNX-CSI驱动,

TDA4VM: TDA4VM - Vision apps: Single app cam getting stuck - Processors forum - Processors - TI E2E support forums

从一个内核写入传感器寄存器,从其他内核写入 csirx 是不正确的。有一个操作序列,需要完成。如果未正确完成,CSIRX 可能无法检测到传入流。

TDA4VM: app single cam File INPUT - Processors forum - Processors - TI E2E support forums

基于RTOS-SDK-7.1版本

20230227

排查DPHY

主要验证:是否可以直接读取DPHY的状态,判断物理接口是否有数据接收进来。

调试log如下

进展:查看可能检测DPHY状态的信息,寄存器手册没有找到可操作的读取的状态寄存器。

Video节点buf写入数据,验证数据通路是否正常

如果在video-buf写入,不能验证整个pipeline的数据流;在CSI2-buf写入数据很麻烦,也很难验证整个piepline。

环宇和VM的对比
v4l2-ctl -d /dev/video2 --set-fmt-video=width=1920,height=1080, --stream-mmap=3 --stream-skip=4 --stream-to=./1920x1080_nv12.yuv --stream-count=5 --stream-poll
现象记录

测试条件1

在环宇上接入森云相机,使用以上命令,

结果1

可以捕获照片。

测试条件2

在环宇上不接入森云相机,使用以上命令,

结果2

显示超时

测试条件3

在TDA4VM上接入森云相机,使用以上命令

结果3

显示超时

原因分析

验证CSI2RX接收格式

修改csi2rx和max9286的格式

.format = {
            .width = 1920,
            .height = 1080,
            .code = MEDIA_BUS_FMT_UYVY8_2X8,
            .field = V4L2_FIELD_NONE,
            .colorspace = V4L2_COLORSPACE_SRGB,
            .ycbcr_enc = V4L2_YCBCR_ENC_601,
            .quantization = V4L2_QUANTIZATION_LIM_RANGE,
            .xfer_func = V4L2_XFER_FUNC_SRGB,
        },

结果:依然没有数据

在环宇上编译驱动,验证数据通路是否正常

参考:https://www.cnblogs.com/young525/p/5873717.html

将max9286的驱动文件在环宇上编译成ko文件,然后加载驱动,判断是否可以正常接收数据

由于环宇上的驱动是编译进内核的,无法排查本身驱动注册的影响。

此方向没有必要验证。

20230226

跟踪Failed to get frame synchronization
强制同步

现象

没有任何报错,数据流就是没有数据?

对比环宇上接同样的camera

环宇上没有yavta命令可以使用,所以两者都使用以下命令获取

v4l2-ctl -d /dev/video2 --set-fmt-video=width=1920,height=1080, --stream-mmap=3 --stream-skip=4 --stream-to=./1920x1080_nv12.yuv --stream-count=5 --stream-poll
现象记录

在环宇上接入相机,可以捕获照片。

在TDA4VM上显示连接超时。

如果将环宇上的相机插拔掉,也报同样的错误。

环宇media-ctl -p

刚好注册了8个pad:source,有对应的数据格式和图像信息。

TDA4VM的media-ctl -p

ticsi2rx

cdns_csi2rx

max9286

目前只有video2、video18可以打开

其余的videox都会出现以下错误

20230224

跟踪dphy-2的错误

基于imx390驱动,debugCDNS_CSI2RX驱动文件

启动配置后,fd 及 num_lanes

强写时钟

现象

基于max9286驱动,debugCDNS_CSI2RX驱动文件

强写BPP的值

输出

原因:检测链路的时候,无法使能links

BPP

像素速率和链路频率之间的乘数。每像素位数

强制写BPP,可避免外部DPHY配置错误问题

v4l2_get_frep即可正常返回,如下

启动max9286驱动,配置解串寄存器,获取数据流,结果如下:

max9286与CSI2RX的格式不同

总结:max9286与CSI2RX的格式对不上

修改max9286格式

static void max9286_init_format(struct v4l2_mbus_framefmt *fmt)
{
	fmt->width		= 640,
	fmt->height		= 480,
	fmt->code		= MEDIA_BUS_FMT_UYVY8_2X8;
	fmt->colorspace		= V4L2_COLORSPACE_SRGB;
	fmt->field		= V4L2_FIELD_NONE;
	fmt->ycbcr_enc		= V4L2_YCBCR_ENC_601;
	fmt->quantization	= V4L2_QUANTIZATION_LIM_RANGE;
	fmt->xfer_func		= V4L2_XFER_FUNC_SRGB;
}

总结:解决max9286与CSI2RX格式匹配问题

待解决新问题

Invalid cross-device link (18).

20230223

DPHY的配置错误

DPHY的配置错误

这是对VM上CSI的配置,理论上是框架自己需要处理的问题。

出现了两条CSI中线注册错误

是由于设备树没有关联CSI相关的信息描述

解决办法,使用原生的image拷贝到/boot目录下,然后启动

在boot中的uEnv.txt文件中添加

name_overlays=k3-j721e-fpdlink-cpb-fusion.dtbo k3-j721e-fpdlink-imx390-rcm-0-0.dtbo

最后加载ds960驱动,就可正常。

确认bus-type = <4>; /* CSI2 DPHY. */是那个总线

使用的是总线5,有ov5640验证得到。

使用ds90ub960验证

基于ds90ub960驱动

使用max9286验证

dphy报同样的错误,是数据流参数错误22?

使用ov5640验证

dphy报同样的错误,但是数据流是没有文件或目录2?

验证了总线bus是使用的D-PHY

使用imx390验证

dphy报同样的错误,但是数据流是没有文件或目录2?

以下源文件出现的报错

TI技术论坛请教

TDA4VM: camera - Processors forum - Processors - TI E2E support forums

跟踪dphy-2的错误

参考

SK-AM62: Failed to configure csi-2 DPHY on OVM9284 image sensor configuration with linux sdk - Processors forum - Processors - TI E2E support forums

TDA4VM: DPHY-RX can not receive data,maybe entry ULP state - Processors forum - Processors - TI E2E support forums

SK-TDA4VM: How to configure the CSI mipi speed based on linux camera driver in EdgeAI SDK. - Processors forum - Processors - TI E2E support forums

media-ctl --set-v4l2 "'ovm9284 4-0060':0 [fmt:SBGGR10_1X10/1280x800@1/60 field:none]"

gst-launch-1.0 v4l2src device="/dev/video0" ! video/x-raw ,width=1280, height=800, framerate=60/1 ! waylandsink

  • v4l2-ctl -d /dev/video0 --set-fmt-video=width=1280,height=800,pixelformat='Y10 '
  • v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=1 --stream-to=test.gray
原因

问题:TI的CSI2RX支持了外部DPHY的配置,导致报错。

定位源码

ENOENT为2;EINVAL为22

20230222

1、2、3使能后的内核镜像,添加设备树、添加max9286驱动

原生内核镜像,添加设备树、添加max9286驱动

总结:目前基于max9286调试,正在debug-DHY配置错误的问题。

1、2、3对应的模块驱动

CONFIG_PHY_CADENCE_DPHY

CONFIG_VIDEO_CADENCE_CSI2RX

CONFIG_VIDEO_TI_J721E_CSI2RX

总结:目前使用原生内核镜像,会自动加载这三个驱动模块。

基于ds960调试,出现一下问题

定位为CSI端口无效,或者没有绑定成功。

调试命令

Xilinx V4L2 MIPI CSI driver - Xilinx Wiki - Confluence

Zynq UltraScale+ MPSoC VCU TRD - Debugging - MIPI CSI-2 Rx Capture Pipeline - Xilinx Wiki - Confluence

v4l2

v4l2-ctl -d /dev/video0 -V

v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat='YUYV'

v4l2-ctl --list-devices

yavta

yavta /dev/video2 -c1 -n4 -s 640x480 -f UYVY -Fvideo.raw

yavta /dev/video2 -c60 -f YUYV -F 640x480_yuyv.yuv -s 640x480

yavta --no-query -l /dev/v4l-subdev0

查看 CSI2 Rx 子系统的 DMESG 输出

了解是否已加载驱动程序以及关联地址。

dmesg | grep -i csi2

查找设备 ID

列出设备并发现 MIPI CSI 输入为 。/dev/video1

v4l2-ctl --list-devices

查找媒体管道

ls /sys/class/video4linux/video3/device/ | grep -i media

更新 MIPI CSI-2 Rx 管道格式

#SONY IMX274 Sensor
media-ctl -d /dev/media7 -V "\"IMX274\":0  [fmt:SRGGB8_1X8/1920x1080 field:none]"
#MIPI CSI2-Rx Subsystem
media-ctl -d /dev/media7 -V "\"a00f0000.mipi_csi2_rx_subsystem\":0  [fmt:SRGGB8_1X8/1920x1080 field:none]"
media-ctl -d /dev/media7 -V "\"a00f0000.mipi_csi2_rx_subsystem\":1  [fmt:SRGGB8_1X8/1920x1080 field:none]"
#Demosaic IP
media-ctl -d /dev/media7 -V "\"a0250000.v_demosaic\":0  [fmt:SRGGB8_1X8/1920x1080 field:none]"
media-ctl -d /dev/media7 -V "\"a0250000.v_demosaic\":1  [fmt:RBG888_1X24/1920x1080 field:none]"
#Gamma LUT IP
media-ctl -d /dev/media7 -V "\"a0270000.v_gamma_lut\":0  [fmt:RBG888_1X24/1920x1080 field:none]"
media-ctl -d /dev/media7 -V "\"a0270000.v_gamma_lut\":1  [fmt:RBG888_1X24/1920x1080 field:none]"
#VPSS: Color Space Conversion (CSC) Only
media-ctl -d /dev/media7 -V "\"a0240000.v_proc_ss\":0  [fmt:RBG888_1X24/1920x1080 field:none]"
media-ctl -d /dev/media7 -V "\"a0240000.v_proc_ss\":1  [fmt:RBG888_1X24/1920x1080 field:none]"
#VPSS: Scaler Only with CSC
media-ctl -d /dev/media7 -V "\"a0200000.v_proc_ss\":0  [fmt:RBG888_1X24/1920x1080 field:none]"
media-ctl -d /dev/media7 -V "\"a0200000.v_proc_ss\":1  [fmt:VYYUYY8_1X24/1920x1080 field:none]"

验证 MIPI CSI2-Rx 管道是否正常工作

yavta -n 3 -c10 -f NV12 -s 1920x1080 --skip 7 -F /dev/video0 (capture 3 pictures)

yavta -n 3 -c10 -f NV12 -s 1920x1080 --skip 7 -F /dev/video1

这会将整个管道(通过 DMA)练习到内存中的分配缓冲区中,最后将生成的帧保存到 rootfs
中的文件中 请注意,这些是“热销”的原始文件,而不是 JPEG 或任何其他格式, 因此,无论是 RGB 数据还是 YUV,您都需要将它们转换为图像编辑器可以理解的内容。

节点格式

v4l2-ctl -d /dev/video2 --set-fmt-video=width=1920,height=1080,pixelformat='YUYV'

v4l2-ctl -d /dev/video2 -V

v4l2-ctl --list-formats -d /dev/video2

待确认是否可用捕获命名

fswebcam -S 5 -d /dev/video0 -p YUV420P -r 320x240 test.jpg

yavta -c60 -f YUYV -F vout_1280x800_yuyv.yuv -s 1280x800 /dev/video1

V4L2

资料

参考:linux驱动中如何自动生成设备文件节点?_eurphan_y的博客-CSDN博客_linux无法自动化创建节点文件

视频驱动V4L2子系统驱动架构-框架_lxllinux的博客-CSDN博客

linux video属性_Video4linux2一般操作流程_海Cha的博客-CSDN博客

linux V4L2子系统——v4l2的结构体(3)之v4l2_subdev_楓潇潇的博客-CSDN博客_struct v4l2_subdev

V4L2视频输入框架概述

【Linux开发】Linux V4L2驱动架构解析与开发导引 - ZhangPYi - 博客园

设备树节点

这里主要为传感器在设备树中添加对应的传感器节点

设备树资料整理

参考:Linux:设备树学习篇(1) - 腾讯云开发者社区-腾讯云

Linux 设备树(DTS)的深入理解 - 腾讯云开发者社区-腾讯云

Linux设备树语法详解 - 腾讯云开发者社区-腾讯云

Linux设备驱动模型-Device - 腾讯云开发者社区-腾讯云

Linux设备树是什么? - 腾讯云开发者社区-腾讯云

Linux笔记(22)| 设备树初探 - 腾讯云开发者社区-腾讯云

Linux笔记(21)| platform总线驱动分析

chosen node

chosen {

bootargs = “tegraid=40.0.0.00.00 vmalloc=256M video=tegrafb console=ttyS0,115200n8 earlyprintk”;

};

chosen node 主要用来描述由系统指定的runtime parameter,它并没有描述任何硬件设备节点信息。原先通过tag list传递的一些linux kernel运行的参数,可以通过chosen节点来传递。如command line可以通过bootargs这个property来传递。如果存在chosen node,它的parent节点必须为“/”根节点

aliases node

aliases {

i2c6 = &pca9546_i2c0;

i2c7 = &pca9546_i2c1;

i2c8 = &pca9546_i2c2;

i2c9 = &pca9546_i2c3;

};

aliases node用来定义别名,类似C++中引用。上面是一个在.dtsi中的典型应用,当使用i2c6时,也即使用pca9546_i2c0,使得引用节点变得简单方便。例:当.dts include 该.dtsi时,将i2c6的status属性赋值为okay,则表明该主板上的pca9546_i2c0处于enable状态;反之,status赋值为disabled,则表明该主板上的pca9546_i2c0处于disenable状态。如下是引用的具体例子:

&i2c6 {————–这里&i2c6到底是label还是alias???

status = “okay”;

};——————在*.dtsi中大多默认为设备为disable,然后在*.dts中将其enable,进行重写使能。

memory node

memory {

device_type = “memory”;

reg = <0x00000000 0x20000000>; /* 512 MB */

};

对于memory node,device_type必须为memory,由之前的描述可以知道该memory node是以0x00000000为起始地址,以0x20000000为结束地址的512MB的空间。

一般而言,在.dts中不对memory进行描述,而是通过bootargs中类似521M@0x00000000的方式传递给内核。

其他节点

由于其他设备节点依据属性进行描述,具有类似的形式。接下来的部分主要分析各种属性的含义及作用,并结合相关的例子进行阐述。

Reg属性

在device node 中,reg是描述memory-mapped IO register的offset和length。子节点的reg属性address和length长度取决于父节点对应的#address-cells和#size-cells的值。例:

设备节点的名称格式node-name@unit-address,节点名称用node-name唯一标识,为一个ASCII字符串。其中@unit-address为可选项,可以不作描述。unit-address的具体格式和设备挂载在哪个bus上相关。如:cpu的unit-address从0开始编址,以此加1;本例中,aips为0x70000000。

compatible属性

compatible属性为string list,用来将设备匹配对应的driver驱动,优先级为从左向右。本例中spba的驱动优先考虑“fsl,aips-bus”驱动;若没有“fsl,aips-bus”驱动,则用字符串“simple-bus”来继续寻找合适的驱动。

在.dts文件的每个设备,都有一个compatible属性,compatible属性用户驱动和设备的绑定。compatible 属性是一个字符串的列表,列表中的第一个字符串表征了结点代表的确切设备,形式为”<manufacturer>,<model>”,其后的字符串表征可兼容的其他设备。可以说前面的是特指,后面的则涵盖更广的范围。

注:对于“/”root节点,它也存在compatible属性,用来匹配machine type。具体说明将在后面给出。

interrupts属性

设备节点通过interrupt-parent来指定它所依附的中断控制器,当节点没有指定interrupt-parent时,则从parent节点中继承。

若子节点使用到中断(中断号、触发方法等等),则需用interrupt属性来指定,该属性的数值长度受中断控制器中#inrerrupt-controller值③控制,即interrupt属性<>中数值的个数为#inrerrupt-controller的值;本例中#inrerrupt-controller=<2>,因而④中interrupts的值为<0x3d 0>形式,具体每个数值的含义由驱动实现决定。

ranges属性

ranges属性为地址转换表,这在pcie中使用较为常见,它表明了该设备在到parent节点中所对用的地址映射关系。ranges格式长度受当前节点#address-cell、parent节点#address-cells、当前节点#size-cell所控制。顺序为ranges=<前节点#address-cell, parent节点#address-cells , 当前节点#size-cell。在本例中,当前节点#address-cell=<1>,对应于⑤中的第一个0x20000000;parent节点#address-cells=<1>,对应于⑤中的第二个0x20000000;当前节点#size-cell=<1>,对应于⑤中的0x30000000。即ahb0节点所占空间从0x20000000地址开始,对应于父节点的0x20000000地址开始的0x30000000地址空间大小。

注:对于相同名称的节点,dtc会根据定义的先后顺序进行合并,其相同属性,取后定义的那个。

拷贝编译好的设备树

参考:Linux笔记(23)| “插件”设备树 - 腾讯云开发者社区-腾讯云

Linux 运行时设备树 - 腾讯云开发者社区-腾讯云

这样我们的设备树文件就写好了,参照上一节的做法,我们修改完设备树文件,然后进行编译,将生成的dtb文件替换开发板原来的dtb文件,然后重启开发板即可。

这里需要注意的一点就是,我们使用cp命令进行拷贝的时候,拷贝完最好使用sync命令进行同步,sync的作用就是将缓冲区的内容写到磁盘上,如果没有使用sync就直接给开发板断电,可能会造成数据的丢失,到时可能因为无效的设备树文件导致系统启动不了。

因为我为了确保开发板的dtb文件是我新生成的,所以在拷贝之前,我把原来的删掉了,再进行拷贝,而如果拷贝失败,就会导致dtb文件缺失。如果不把原来的删除,而直接使用cp命令拷贝,即使拷贝失败,也不会因为dtb文件缺失而启动不了。另外,重启开发板可以断电重启,也可以使用reboot命令重启,使用reboot命令重启应该会更安全一些,不容易数据丢失。如果非要断电重启,最好在断电之前敲几次sync命令。

设备树文件写好了,接下来就是写驱动文件了。其实驱动文件和我们之前在Linux笔记(21)| platform总线驱动分析介绍的基本是一样的,唯一的不同就是资源获取方式不一样,之前是在设备文件中获取,现在是在设备树文件上获取。所以重点说一下这个部分,其他的就不赘述了。

但是这样还不够好,因为每次修改设备树文件,都要修改内核源码,然后编译、拷贝、重启开发板。这样还是挺不方便的。尤其像内核源码,不应该随随便便去修改,这样子是不太安全的。

所以可以使用动态加载的方法。动态加载的方法,首先也是写一个设备树文件,不过这个不是去内核源码修改,而是单独的一个文件,然后编译生成.dtbo文件。最后修改/boot/目录下的uEnv.txt文件,把dtbo文件加进去,最后reboot重启即可。关于这部分的详细操作,我们以后再介绍。

dts和dtsi

参考:Device Tree中的.dts和dtsi文件介绍_Orangehaswing的博客-CSDN博客

Linux设备树(Device Tree)机制 - 腾讯云开发者社区-腾讯云

*.dts文件是一种ASCII文本对Device Tree的描述,放置在内核的/arch/arm/boot/dts目录。一般而言,一个*.dts文件对应一个ARM的machine。

*.dtsi文件作用:由于一个SOC可能有多个不同的电路板,而每个电路板拥有一个 *.dts。这些dts势必会存在许多共同部分,为了减少代码的冗余,设备树将这些共同部分提炼保存在*.dtsi文件中,供不同的dts共同使用。*.dtsi的使用方法,类似于C语言的头文件,在dts文件中需要进行include *.dtsi文件。当然,dtsi本身也支持include 另一个dtsi文件。

DTC为编译工具,它可以将.dts文件编译成.dtb文件。DTC的源码位于内核的scripts/dtc目录,内核选中CONFIG_OF,编译内核的时候,主机可执行程序DTC就会被编译出来。 即scripts/dtc/Makefile中。

DTC编译*.dts生成的二进制文件(*.dtb),bootloader在引导内核时,会预先读取*.dtb到内存,进而由内核解析。

dtb和dtbo

参考:kernel dtb 与 dtbo

dtb是device tree binary的简称
binary,顾名思义,就是可以被bootloader直接读取执行的内容
它们在开机启动在早期阶段由bootloader解码,传递给内核,从而帮助内核完成启动过程

dtbo是device tree binary overlay的简称
在msm-4.9平台上,dtbo横空出世(准确来说是出厂搭载安卓9的要求)。device tree被拆分到了两个地方,一个是boot分区中的老位置,另一个则是dtbo分区。谷歌做这件事的初衷在于:希望分离芯片厂商和手机厂商的修改,芯片厂商只修改内核中的dtb,而手机厂商只修改dtbo分区,这样能够井井有条((但是事实是手机厂商也还在改内核的dtb)因此,就初衷而言,我们已经可以看出dtb和dtbo分区之间的关系

添加设备节点

在uboot中,使用env可以找到板子默认使用k3-j721e-common-proc-board.dtb

  1. 在启动期间,通过按任意键在u-boot提示符处停止并设置相机覆盖dtb:
setenv name_overlays k3-am625-sk-csi2-ov5640.dtbo 
boot

2、在boot的uEnv.txt文件中添加

name_overlays=k3-am625-sk-csi2-ov5640.dtbo

3、重置默认环境变量

env default -f -a
saveenv

在i2c-6添加具体传感器节点

  camera_sensor: camera@12 {
		compatible = "manufacturer,sensor-compatible";
		reg = <0x12>;
		/* Other sensor properties go here... */
		port {
			csi2_cam0: endpoint {
				remote-endpoint = <&csi2rx0_in_sensor>;
				clock-lanes = <0>;
				/*
					* This example sensor uses 2 lanes. Other sensors might use
					* 1, 2, 3, or 4 lanes. Populate this property accordingly.
					* See Documentation/devicetree/bindings/media/video-interfaces.yaml
					* for more info.
					*/
				data-lanes = <1 2>;
			};
		};
};

&csi0_port0 {
    status = "okay";
    csi2rx0_in_sensor: endpoint {
            remote-endpoint = <&csi2_cam0>;
            bus-type = <4>; /* CSI2 DPHY. */
            clock-lanes = <0>;
            data-lanes = <1 2>;
    };
};

内核调试

内核修改配置

在make menuconfig配置无法生效?

因为在SDK中使用了默认的tisdk_j7-evm_defconfig,如果要使配置生效,则需要根据具体需求将默认配置修改。

以下三个配置是官方指定的,但是编译完,使用内核两个video节点就不存在呢

CONFIG_PHY_CADENCE_DPHY=y

CONFIG_VIDEO_CADENCE_CSI2RX=y

CONFIG_VIDEO_TI_J721E_CSI2RX=y

如果只配置这两个参数,编译完,使用内核两个video节点就存在

CONFIG_PHY_CADENCE_DPHY=y

CONFIG_VIDEO_CADENCE_CSI2RX=y

如果只配置这一个参数呢,编译完,使用内核两个video节点就存在

CONFIG_PHY_CADENCE_DPHY=y

以下配置做参考,不需要编译到内核中

CONFIG_VIDEO_DS90UB960=y

CONFIG_I2C_ATR=y #ds90ub960依赖I2C_ATR模块

总结:CONFIG_VIDEO_TI_J721E_CSI2RX=影响编解码的video0和video1节点的创建

内核配置调试

这里的1、2、3分别指CONFIG_PHY_CADENCE_DPHY、CONFIG_VIDEO_CADENCE_CSI2RX、CONFIG_VIDEO_TI_J721E_CSI2RX的使能配置,编译到内核中的调试情况。

1、2、3使能

现象:csi2中的4504000、4514000都启动错误,且不能注册编解码的video节点。

1、2使能

现象:没有使能CONFIG_VIDEO_TI_J721E_CSI2RX,但是csi2中的4504000加载成功,且注册编解码两个节点。

使用原生内核,使用name_overlays

添加imx390-rcm-0-0.dtbo
没有出现新的video节点

在boot中的uEnv.txt文件中添加

name_overlays=k3-j721e-fpdlink-cpb-fusion.dtbo k3-j721e-fpdlink-imx390-rcm-0-0.dtbo

现象:只有960probe错误,但是CSI2并没有error。编解码两个节点正常

但是没有新的video节点出来,主要原因是因为没有加载成功ds960。

出现新的video节点

删除以下路径默认加载的ds90ub960.ko文件

重新编译内核修改后的ds90ub960.ko文件,再手动加载

insmod ds90ub960.ko

出现三十多个video节点

添加csi2-ov5640.dtbo

name_overlays=k3-j721e-sk-csi2-ov5640.dtbo

删除以下路径默认加载的ds90ub960.ko文件

重新编译内核修改后的ds90ub960.ko文件,再手动加载

insmod ds90ub960.ko

加载没有任何显示,且没有新的节点生成。

使用自己编译的dtb

没有新的video节点出现,是因为挂载的9-0012不能获取时钟,导致9-0012probe失败

基于k3-j721e-fpdlink-cpb-fusion.dts修改

基于原生镜像和设备树

1、使用k3-j721e-fpdlink-cpb-fusion.dts、k3-j721e-fpdlink-imx390-rcm-0-0.dts文件

2、在路径/lib/modules/5.10.153-g90c3a58fd2/kernel/drivers/media/i2c#更换重新编译好的ds90ub960.ko

重启设备,既可以生成32个video节点。

设置传感器节点的 1920x1080 @ 30fps UYVY 格式

media-ctl --set-v4l2 '"ds90ub960 9-003d":0 [fmt:UYVY8_2X8/1920x1080@1/30]'

调试

基于原生镜像和设备树

1、使用k3-j721e-fpdlink-cpb-fusion.dts

2、在路径/lib/modules/5.10.153-g90c3a58fd2/kernel/drivers/media/i2c#更换重新编译好的ds90ub960.ko

k3-j721e-fpdlink-cpb-fusion.dts关联k3-j721e-fpdlink-imx390-rcm-0-0.dts中ds90ub960_0_ports、ds90ub960_0_atr端口描述。

调试设备树是怎么生成video的

内核查看

查找内置模块列表

cat /lib/modules/$(uname -r)/modules.builtin

内核模块保存位置与模块保存文件

arch
与硬件相关的模块
crypto
#内核支持的加密技术的相关模块
drivers
#硬件的驱动程序模块,如显卡、网卡等
fs
#文件系统模块,如 fat、vfat、nfs等
lib
#函数库
net
#网络协议相关模块
sound
#音效相关模块

Linux 中所有的模块都存放在 /lib/modules/5.10.153-g90c3a58fd2/modules.dep 文件中,在安装模块时,依赖这个文件査找所有的模块,所以不需要指定模块所在位置的绝对路径,而且也依靠这个文件来解决模块的依赖性。

内核驱动调试

参考:加载内核模块-Unknown symbol错误分析 - 隔壁王叔叔a - 博客园

安装驱动错误 Unknown symbol __uio_register_device (err -2)

Linux下编写和加载 .ko 文件(驱动模块文件)_worthsen的博客-CSDN博客_ko文件

加载ds90ub960.ko内核驱动

cat /proc/kallsyms | grep "i2c_atr_delete"

如果内核中已经包含了这个符号,那么就会有相关的打印信息,否则不打印

/proc/kallsyms会显示内核中所有的符号,但是这些符号不是都能被其他模块引用的(绝大多数都不能),能被导出的是符号的类型是大写的那些(例如T,U)。

查看内核相关信息

确定模块依赖关系,再进一步确认符号调用。

依赖:i2c-atr

信息查询及验证

分析media设备节点的拓扑结构

media-ctl -p

media-ctl -p -d /dev/media1

设备树源

获取设备数使用文件名称

获取设备详细信息

v4l2-ctl -d /dev/video0 --all

验证camera数据流

抓取数据图片

v4l2-ctl -d /dev/video2 --set-fmt-video=width=1920,height=1080, --stream-mmap=3 --stream-skip=4 --stream-to=./1920x1080_nv12.yuv --stream-count=5 --stream-poll

获取数据流

yavta -c -Fcapture -s 640x480 -f UYVY /dev/video0

v4l2-ctl -d0 --set-fmt-video=width=1936,height=1100,pixelformat=RG12 --stream-mmap --verbose

相关资料

SD(mmcblk1)

EMMC(mmcblk0)

  • 25
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

踏马潜行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值