当前位置:   article > 正文

RV1126开发调试记录_rv1126 mipicsi 调试

rv1126 mipicsi 调试

双摄

硬件方案: 双12M IMX577
分辨率 4048x3040
bayer 大约18MB(视频处理中会多次以该大小分配内存块)

IMX577驱动

imx577 sensor 驱动可从rk3588中移植修改来用。
主要修改以下3点:
1.
把RKMODULE_GET_CHANNEL_INFO宏定义及struct rkmodule_channel_info定义拷过来
2.
实现imx577_g_mbus_config函数,
其中config->type = V4L2_MBUS_CSI2_DPHY;
改为config->type = V4L2_MBUS_CSI2;
3.
把函数挂到v4l2_subdev_video_ops结构体(注意不是v4l2_subdev_pad_ops)

dts修改:

channel 1( sensor -> vicap -> isp):
sensor -> csi_dphy0 -> mipi_csi2 -> rkcif_mipi_lvds
rkcif_mipi_lvds_sditf-> rkisp_vir0
channel 2( sensor -> isp):
sensor -> csi_dphy1 -> rkisp_vir1

排错分析

此时运行ispserver并访问video节点kernel会崩溃:

Unable to handle kernel paging request at virtual address ecc00000

[   21.439757] [<b011ba40>] (v7_dma_clean_range) from [<b0116d54>] (__map_sg_chunk+0x268/0x3b8)
[   21.440541] [<b0116d54>] (__map_sg_chunk) from [<b01170c8>] (__iommu_map_sg+0x224/0x238)
[   21.441264] [<b01170c8>] (__iommu_map_sg) from [<b0117114>] (arm_iommu_map_sg+0x18/0x20)
[   21.441982] [<b0117114>] (arm_iommu_map_sg) from [<b07d7c40>] (vb2_dma_sg_dmabuf_ops_map+0xd0/0x14c)
[   21.442789] [<b07d7c40>] (vb2_dma_sg_dmabuf_ops_map) from [<b0683f88>] (dma_buf_map_attachment+0x24/0x48)
[   21.443668] [<b0683f88>] (dma_buf_map_attachment) from [<b07974a4>] (vb2_dma_sg_map_dmabuf+0x28/0x9c)
[   21.444488] [<b07974a4>] (vb2_dma_sg_map_dmabuf) from [<b07d91d0>] (rkispp_event_handle+0x1e0/0x4d8)
[   21.445292] [<b07d91d0>] (rkispp_event_handle) from [<b07d4904>] (bridge_ioctl+0x1cc/0x5cc)
[   21.446029] [<b07d4904>] (bridge_ioctl) from [<b07def24>] (rkispp_start_streaming+0x228/0x56c)
[   21.446820] [<b07def24>] (rkispp_start_streaming) from [<b0791010>] (vb2_start_streaming+0x5c/0x150)
[   21.447629] [<b0791010>] (vb2_start_streaming) from [<b0792698>] (vb2_core_streamon+0x11c/0x15c)
[   21.448412] [<b0792698>] (vb2_core_streamon) from [<b077da30>] (__video_do_ioctl+0x1c8/0x3a0)
[   21.449162] [<b077da30>] (__video_do_ioctl) from [<b07811e0>] (video_usercopy+0x21c/0x650)
[   21.449921] [<b07811e0>] (video_usercopy) from [<b0277a94>] (do_vfs_ioctl+0xac/0x798)
[   21.450645] [<b0277a94>] (do_vfs_ioctl) from [<b02781b4>] (ksys_ioctl+0x34/0x58)
[   21.451310] [<b02781b4>] (ksys_ioctl) from [<b0101000>] (ret_fast_syscall+0x0/0x4c)
[   21.451988] Exception stack(0xda85dfa8 to 0xda85dff0)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

kernel启动打印内存布局如下:

[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xed000000 - 0xff800000   ( 296 MB)
[    0.000000]     lowmem  : 0xb0000000 - 0xecc00000   ( 972 MB)
[    0.000000]     pkmap   : 0xafe00000 - 0xb0000000   (   2 MB)
[    0.000000]     modules : 0xaf000000 - 0xafe00000   (  14 MB)
[    0.000000]       .text : 0x(ptrval) - 0x(ptrval)   (12256 kB)
[    0.000000]       .init : 0x(ptrval) - 0x(ptrval)   (1024 kB)
[    0.000000]       .data : 0x(ptrval) - 0x(ptrval)   ( 699 kB)
[    0.000000]        .bss : 0x(ptrval) - 0x(ptrval)   ( 310 kB)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

可知vb2_start_streaming过程中在v7_dma_clean_range函数错误访问了lowmem的up边界。
崩溃堆栈可知该崩溃发生在rkispp驱动的attachment dma_buf中
但实际该dma_buf是rkisp_rkispp_bridge驱动在isp中分配通过bridge挂接到rkispp中共用。
追查发现rkisp分配的dma_buf采用的videobuf2-rdma-sg.c分配器,该分配器alloc会从cma-isp(dts中的isp_reserved)中分配连续内存,没有充分利用上scatter/gather机制,通过的dts可知cma-isp仅在VICAP及isp/ispp驱动中被使用,内存使用比较一致,垃圾碎片问题应当不会严重,即便碎片致使分配不到整块大内存也该报错而非分配成功使用崩溃。

整理思路继续分析

deconfig中打开CONFIG_CMA_DEBUGFS=y
此命令会在debugfs中导出cma信息供调试
编译烧写启动系统
 cat /sys/kernel/debug/cma/cma-isp/base_pfn
	发现base_pfn基址在187,392,左移12位正好0x2DC00000,有dts的isp_reserved可知该cma大小为256MB,此信息也可通过执行dmesg|grep Reserved得到下面两行信息获得:
  • 1
  • 2
  • 3
  • 4
  • 5
[    0.000000] Reserved memory: created CMA memory pool at 0x3f800000, size 8 MiB
[    0.000000] Reserved memory: created CMA memory pool at 0x2dc00000, size 256 MiB
  • 1
  • 2
可知该cam-isp范围在0x2DC00000 ~ 0x3DC00000
通过内存布局可知lowmem在0xB0000000 ~ 0xECC00000
  • 1
  • 2
# cma.c
	for (;;) {
		mutex_lock(&cma->lock);
		bitmap_no = bitmap_find_next_zero_area_off(cma->bitmap,
				bitmap_maxno, start, bitmap_count, mask,
				offset);
		if (bitmap_no >= bitmap_maxno) {
			mutex_unlock(&cma->lock);
			break;
		}
		bitmap_set(cma->bitmap, bitmap_no, bitmap_count);
		/*
		 * It's safe to drop the lock here. We've marked this region for
		 * our exclusive use. If the migration fails we will take the
		 * lock again and unmark it.
		 */
		mutex_unlock(&cma->lock);

		pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit);
		if (cma->inactive) {
			ret = 0;
			page = pfn_to_page(pfn);
			break;
		}
		。。。
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

以上代码可知,在cma->inactive为True时cma分配内存直接简单映射到lowmem,inactive在dts默认被设置故成立(取消设置影响较大,不建议),而追踪cma 区域初始化代码发现cma的start地址总是在有效物理内存区域top_down而分配,且未考虑vmalloc对lowmem的挤压。
综合考虑两个内存范围:
cma-isp phys 0x2DC00000 ~ 0x3DC00000
lowmem virtual 0xB0000000 ~ 0xECC00000
故cma分配的物理内存可能超出lowmem高址16MB,即cma在尾端认为尚有足够内存分配,然而在lowmem却越界,故而崩溃。

结论

cma空间布局仅考虑物理内存可用空间优先高址分配,映射到lowmem使用,而32bit linux系统lowmem通常涵盖不完物理内存,导致cma分配的内存在lowmem存在映射越zone的风险,同时vmalloc也会挤压lowmem空间使问题恶化。
  • 1

解决

解决方案一

既然问题是cma空间布局跟lowmem存在不协调风险,那么分配时能够控制start,end主动与既知lowmem区域协调最好不过。

# rv1126_xxxx.dts
&isp_reserved {
	alloc-ranges = <0x10000000 0x10000000>;
	size = <0x10000000>;
};
  • 1
  • 2
  • 3
  • 4
  • 5

以上dts配置控制cma分配区域,避免与lowmem出现差集。
该方案依然使用cma,保留性能优势,然而cma也存在使内存利用不充分的弊端。

解决方案二

直接使用系统内存配合sg机制

# driver/media/platform/rockchip/isp/hw.c
static int rkisp_hw_probe(struct platform_device *pdev) {
	......
	if (is_mem_reserved) {
		/* reserved memory using rdma_sg */
		hw_dev->mem_ops = &vb2_rdma_sg_memops;
		hw_dev->is_dma_sg_ops = true;
	} else if (hw_dev->is_mmu) {
		hw_dev->mem_ops = &vb2_dma_sg_memops;
		hw_dev->is_dma_sg_ops = true;
	} else {
		hw_dev->mem_ops = &vb2_dma_contig_memops;
	}
	......
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

以上源码可知rkisp/hw驱动可通过is_mem_reserved控制使用哪个分配器,默认的vb2_rdma_sg_memops会从预留的cma分配连续物理/虚拟空间, 其中vb2_dma_sg_memops分配器可凭借list方式从系统内存分散申请dma空间,不要求连续,理论性能弱于cma但实际视频处理帧率并未有明显变化,该方式能更充分利用内存资源。
至于is_mem_reserved,追踪源码即知可通过dts的rkisp节点的memory-region字段有无间接被设置。
以下为具体修改:

# rv1126.dtsi
rkisp {
	...
	# memory-region = <&isp_reserved>;
	...
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

双摄时间戳

lidar缘故,期望双摄时间戳能够准确反应曝光时刻,默认是eof(end of frame,帧传输结束中断时刻),改用sof(start of frame 帧传输开始中断时刻)
rv1126 双路link关系:
sensor0->csi_dphy0->csi2->vicap->isp0->ispp0
sensor1->csi_dphy1->isp1->ispp1
第一路时间戳修改:
kernel/drivers/media/platform/rockchip/cif/hw.c: rkcif_irq_handler
isr_hdl 指针,指向kernel/drivers/media/platform/rockchip/cif/dev.c: rkcif_irq_handler
kernel/drivers/media/platform/rockchip/cif/capture.c: rkcif_irq_pingpong, 此函数有第一路sof中断,在此记录时间戳,后续frame_end修改之
frame_end 即 kernel/drivers/media/platform/rockchip/cif/capture.c:rkcif_buf_done_prepare逻辑,也在rkcif_irq_pingpong中断调用

第二路时间戳修改:
drivers/media/platform/rockchip/isp/hw.c: mipi_irq_hdl
drivers/media/platform/rockchip/isp/capture_v20.c: rkisp_mipi_v20_isr, 此函数中RAW0_Y_STATE,RAW1_Y_STATE,RAW2_Y_STATE即为sof中断,rkisp_csi_sof中会发送type为V4L2_EVENT_FRAME_SYNC的v4l2_event
mi_frame_end 中修改ts
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

usb虚拟网卡(rndis)开启及配置

rv1126 bsp已经默认开启了usb_gadget/usb_rndis相关kernel配置
关键配置流程在/etc/init.d/S50usbdevice脚本,该脚本主要做以下事情:
1. 该脚本会自挂载/sys/kernel/config目录(configfs),并在该目录下创建usb_gadget目录
2. 读取/etc/init.d/.usb_confg目录根据里面内容填充usb_gadget目录相关字段,以提供对应usb_gadget功能(包括rndis)
由此可知只需要修改.usb_confg文件即可开启rndis功能,即向.usb_confg追加usb_rndis_en即可。
问题: 当前adb rndis同时配置在windows10出现rndis网卡设备叹号无法使用现象,linux没问题,去掉adb单独配rndis没问题。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

开启dhcp server

修改rv1126_linux_220224/buildroot/configs/rockchip_rv1126_rv1109_xxx_defconfig文件
追加以下两行
BR2_PACKAGE_DHCP=y
BR2_PACKAGE_DHCP_SERVER=y
修改设备/etc/dhcp/dhcpd.conf文件
追加以下三行:
subnet 192.168.3.0 netmask 255.255.255.0 {
	range 192.168.3.10 192.168.3.20;
}
修改设备/etc/network/interfaces,追加以下行,配置静态ip
auto usb0
iface usb0 inet static
  address 192.168.3.1
  netmask 255.255.255.0
至此,基础配置完成,但是由于服务启动顺序还会存在问题,当前启动顺序如下
 /etc/init.d/S40network			#配置usb0 ip为192.168.3.1
 /etc/init.d/S50usbdevice		#配置otg gadget为rndis,出现usb0
 /etc/init.d/S80dhcp-server	#启动dhcp-server
 第一步跟第二步顺序跟依赖相反导致usb0无法配置成192.168.3.1导致dhcp启动失败,
 可以在自己业务流程S99xxxx中重新调度第一步跟第三步解决
  /etc/init.d/S40network	restart
   /etc/init.d/S80dhcp-server restart
会当pc通过usb连接设备时便会自动分配的到192.168.3.10 192.168.3.20范围内的ip
注意,如果pc的ubuntu系统装过nvidia jetson的sdkmanager开发工具会自动在系统中将usb0配置成192.168.55.100导致dhcp失效,可以修改/etc/NetworkManager/system-connections/usb0.nmconnection文件删除下面一行解决:
address1=192.168.55.100/24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

RV1126 双摄拼接

SDK: rv1126_rv1109_linux_ipc_240321
此sdk支持拼接功能,但完成度不高,无buildroot,只有最基本的busybox
支持拼接关键两点:
1. librkaiq.so(无源码,无ispserver) 支持isp camera group模式(双sensor统一曝光,验证实际是根据第一路两路统计同时一致配置两路sensor曝光参数
2. 引入AVS模块 (不必须,可后处理)

SDK问题:
1.
sdk demo默认开启LDCH模式,isp中LDCH开启则报内存错误(isp single/group 模式下均报错)
RK_GET_LDCH_BY_FILE模式且不提供mesh文件则有图像数据但画面全黑,此模式提供文件或其他模式均报内存错误
RK_GET_LDCH_BY_BUFF 不确定
原因:
sample_common_isp.cp中即使RK_NONE_LDCH模式也会使能,RK_GET_LDCH_BY_FILE模式而不提供mesh文件反而会因为找不到文件关闭LDCH
解决:
真正关闭LDCH即可,isp group模式不依赖于此
2.
isp 出图全黑
跟HDRTMO冲突,iqfiles或rkaiq中关闭即可

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/877728
推荐阅读
相关标签
  

闽ICP备14008679号