赞
踩
硬件方案: 双12M IMX577
分辨率 4048x3040
bayer 大约18MB(视频处理中会多次以该大小分配内存块)
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)
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)
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)
可知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得到下面两行信息获得:
[ 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
可知该cam-isp范围在0x2DC00000 ~ 0x3DC00000
通过内存布局可知lowmem在0xB0000000 ~ 0xECC00000
# 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; } 。。。 }
以上代码可知,在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空间使问题恶化。
既然问题是cma空间布局跟lowmem存在不协调风险,那么分配时能够控制start,end主动与既知lowmem区域协调最好不过。
# rv1126_xxxx.dts
&isp_reserved {
alloc-ranges = <0x10000000 0x10000000>;
size = <0x10000000>;
};
以上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;
}
......
}
以上源码可知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>;
...
};
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
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没问题。
修改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
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中关闭即可
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。