吉利项目工作总结:
一: 中配 rtc 缺陷导致 倒车图像卡住不动问题
调查发现 如果Android开机时迅速进入显示倒车影像,此时如果调用alarm_set_rtc 设置系统时间时,倒车影像会
卡在 drvier/media/video/mxc/output/mxc_vout.c 函数setup_buf_timer里面。
因为倒车影像overlay显示,是靠设置hrtimer 定时器,不断显示每一帧图像(mxc_vout.c里面东西)。 hrtimer 的设置和激活跟 系统时间相关,如果在hrtimer 工作的时候,去调用alarm_set_rtc设置下系统时间,hrtimer的工作会受到干扰,导致下来设置的定时器不能正常工作。
问题原因在于imx6 3.0.35 这一版内核时间机制 有点缺陷,不仅影响了倒车图像,还影响了导航芯片正常上报数据。
本来期望的解决方法是:
NXP 给出patch,Android起来后,车机不可避免要去调用 alarm_set_rtc同步下系统时间。而如果此时在倒车影像工作状态下,倒车影像显示就会受到干扰。NXP 应该做些完善措施,能否加把锁,或者对mxc_vout.c里面hrtimer的使用做些完善工作, 避免受到 alarm_set_rtc 的干扰。
但是NXP 没法提供有效帮助,我这边做了work around。
Work around 措施:
当检测到alarm_set_rtc 往底层去设置系统时间时,我就在设置完后,再次对图像帧获取的基准时间做次更新,就是把基准时间赋值为再次获取更新后的系统时间。
二:倒车雷达声音问题
按照吉利车载机需求说明,雷达报警音之前存在以下问题:
1:车机启动后,雷达报警音第一声 和往后的几声不正常。
原因:雷达音量突然从0 到 正常播报的增大瞬间,会造成声音不太自然。
解决措施:让雷达音量 缓缓 地 从0 增大 到正常音量。这样该问题可以得到解决。
2:acc off/on 时,雷达音误报问题。
原因:acc off/on时,mcu 给MPU 发送的can 报文报 不正确,因为错误的can 报文包,导致错误的时间,播报雷达音。
举例:acc off 时,MCU 没有给MPU 发送 alarm off报文报,导致ACC OFF 时,雷达报警音依然工作。 再次acc on时,如果障碍物距离没有变化的话,MCU 也不会给MPU 发送 alarm on 报文报。
所以 需要MPU 这边 关注ACC OFF/ON 的状态 对雷达报警音 的影响。
ACC OFF,MPU这边检测 到ACC OFF报文包时,及时关闭雷达报警音。
ACC ON时,MPU这边检测 到ACC ON报文包时,再次给MCU 发送请求雷达CAN 报文状态,这个时候MCU 才能继续发送车上雷达 can 报文报,MPU才有可能继续播报雷达报警音。
3:按键音 对 雷达报警音的干扰
由于按键音播放 和雷达报警音 走的同一个audio codec 音频通道(chime 音通道)。所以雷达报警音响起后,按键音出来时,雷达报警音会接下来永远停止工作了。
解决措施: 增加判断 雷达报警音 有无工作的属性文件,当雷达报警音工作时,这个时候按键时,就不会有按键音的发声。具体是按键时,检测该属性文件值,如果判断出雷达报警音正在工作,就不再按键音发声。
三:动态辅助线 图片问题
1:图片切换卡顿。
吉利中配 车机的客户需求要求 司机打方向盘时,动态辅助线切换流畅,不卡顿。
经测试发现 车机刚启动时,动态辅助线切换时,会比较卡顿。
原因:我们的动态辅助线 采用贴图方式,70多张图片(代表不同角度的动态辅助线)要在 一秒左右瞬间来回切换完毕。由于每张图片是PNG 格式,并且是RGBA8888,容量为2MB。车机要在瞬间读大量图片从flash 到内存中显示出来,这增加CPU负荷。所以车机刚刚启动时,在CPU 工作繁忙的时候,图片切换比较卡顿。
解决方法:因为图片切换耗时工作在于从flash 到内存的读图片比较耗CPU。所以采用大数组的方式,抽取每张图片的 代表动态辅助线的若干像素位置坐标,然后用每张图片对应一个数组,每个数组都保存有图片的动态辅助线 位置信息坐标值。然后具体在动态辅助线切换时,只需要这些数组信息就行了,不再需要原始图片信息了。具体切换时, 有了数组信息后,可以直接用opengl 画线的方式来表达 各个动态辅助线信息就可以了。
这样省去了 图片加载内存的工作(倒车程序启动起来后,数组信息直接被加载到了内存中),并且用opengl 画图,可以省去CPU 的工作负担,opengl 硬件加速画图的方式 渲染速度也比较快。
2: 动态辅助线变色及锯齿问题
吉利客户发现动态辅助线 在某些车机场景下,会色彩退化。比如本来线条应该是绿色,结果变成了白绿色。
原因:采用opengl 画点的方式 描绘动态辅助线时,如果点过于密集的话,色彩就有可能失真。
但是如果点稀松的话,线条锯齿就出来了。
解决方法:
本来想采用方法1:抛弃opengl 画动态辅助线,把每个图片的像素坐标位置信息都抽取出来,在fb1上用原始的修改内存的方式,直接把动态辅助线的各个像素直接描绘出来。然后用fb1 去和 fb0 进行图像混合显示。
但是这样做的话,有缺陷:
1:造成我们的倒车程序整体架构不好,我们的倒车程序架构 是 fb0上显示各种倒车辅助信息的图片,fb1 上显示倒车图像。这样做的话,fb1 增加了负担,还得显示动态辅助线。虽然fb0上不用显示动态辅助线了。这样 各个模块干的工作 有点混淆了。倒车程序的整体架构就不清晰了。
2:这一点也是最主要的。据我观察,直接在原始 framebuffer上用描绘像素的方式画动态辅助线,线条的锯齿现象比较严重,客户估计接受不了。Opengl 画几何图形,可以有一些接口配置,减缓线条的锯齿现象。
所以不得不采用方法2:不再画点,直接用opengl 画线的方式 去描绘动态辅助线。但是采用opengl 画线,不得不做一个工作,就是把每个图片的两条动态辅助线 想办法拆开出来,分别调用opengl 画线两次,单独画出两条线。因为如果一张图片,调用opengl 一次,画两条线的话,两条线容易连在一起。
还有就是 画线,可以抽取比较稀疏的像素坐标信息。这样降低了opengl 画线的坐标信息量,加快了 画线速度。
四 cvbs图像质量问题
图像锯齿问题:
Cvbs 由于是隔行信号 进入CPU(imx6) csi 接口的,所以imx6那边 多了个必须实时的隔行转换成逐行工作。由于中配车机屏的显示分辨率也比较高,为1024*600,所以动态图像锯齿问题只能减缓,不能完全根除的。
图像锯齿分成两大类:
1:N制静态图像锯齿
这个可以根除掉,之前我的中配项目中遇到了N制摄像头的静态图像锯齿问题。这个问题咨询飞思卡尔FAE,他也不上心。最后在我耐心追问下,终于得知是场同步(奇偶场)顺序不对。就是 cvbs 图像中有两个参数top,left. Top 参数的调整 可以影响到奇偶场的顺序。
这个静态图像锯齿具体反映在 cvbs 摄像头静止放在桌子上,车机显示屏显示出的图像有锯齿纹。
具体修改是把top 值由13 修改成14.该N制静态锯齿问题就可以解决了。P制静态图像不存在这个问题。
2:动态图像锯齿
这个问题根本原因在于imx6 里面图像处理模块过于简单,没有ISP。所以需要cpu IPU 共同参与把隔行图像转换成逐行图像。这样,如果移动cvbs 摄像头速度比较快时,能看到车机显示屏上还有锯齿残影的。如果用标准的信号发生器作为测试源输入的话,该问题更容易发现。
该问题解决方法:
Imx6 Android代码包有个demo mxc-v4l2-tvin 程序。该程序有个参数 –m ,缺省值是0,这个时候,没有对动态图像锯齿有优化。当该参数赋值1或者2时,开始对动态图像锯齿做优化了。实际在车机上可以看到 图像锯齿纹已经有明显的改善。
苏州ZH摄像头厂商用信号发生器测试我们的车机图像质量,发现的锯齿纹问题。不仅要配置-m参数,而且还有设置 图像显示帧率为60fps. 要两个措施都做,才能消除这个锯齿纹。
图像发黄问题:
吉利中配车机 图像黄问题,其实做到最后,发现camera端 和 车机端都是可以优化的。车机端图像发黄,我用抓图像帧工具在 cpu 输入端抓到的图像就发黄,从而排除了 跟cpu 的关系。然后最后在adv7182 FAE的指导下,其实可以用示波器 在 adv7182 的输入端进行排查。车机的具体优化吉利项目没有做。
最后图像发黄问题是camera端ZH解决的。Camera端 不断修改他们的固件,调整他们的图像参数,以适配我们的7182输入端的硬件特性。最后该问题由ZH解决了。
五: 吉利车机开机慢 底层问题
吉利反馈车机开机慢,然后根据测试反馈,旧emmc 卡(8de4的)比 新emmc卡(emmc5.1的卡)开机快。
然后我用dd命令 对比测试新旧emmc所在车机,发现dd测试顺序读结果,新卡比旧卡慢了快20秒。
然后观察意外掉电重启,发现新卡挂载文件系统时间比旧卡普通慢400-500ms.
目前解决措施:
闪迪厂商的建议下,修改3.0.35版内核 为close-end模式,该版内核本来为open-end模式。
Close-end 模式介绍:
Open-end 为 emmc host端,先发读命令,然后不停地从emmc卡读数据出来,然后不需要数据时,host会发送stop 命令,停止本次传输。
Close-end 为emmc host端, 先发CMD23 命令,即发送本次需要读多少数据块的命令给emmc卡,
然后发送具体的读命令,启动本次传输。这样就是说提前让emmc卡得知 host端需要多少数据量。
需要注意imx6 3.0.35 并无开启close-end传输,还是open-end传输。Imx6 android 6上的Linux内核已经默认开启了 close-end传输,但是是跟adma 配置使用的。
3.0.35上开启close-end传输后,还可以选择是否最后再发送stop命令停止本次数据传输。
我的优化工作:
在3.0.35上开启了close-end 传输,然后dd 顺序读测试对比新旧卡性能,发现已经接近一样了。
然后新卡开机慢的问题,经过自己的对比测试,比之前open-end传输,要快了一秒多。但是和旧卡比起来,还是慢点。
3.0.35上开启close-end传输的风险调查:
闪迪原厂即使回复没有风险,也要追问emmc host端,nxp,看看为啥在3.0.35版内核上没有开启close-end.
然后nxp 在Android 6 的内核中开启了close-end,但是是和adma 传输捆绑使用的。3.0.35上同样没有开启adma传输,开启的是普通dma 传输。所以要问问3.0.35上开启close end传输,是否还要开启其他东西,比如adma传输。
我尝试在3.0.35上开启了adma传输+close-end后,经过测试(测试开机时间)发现和只开启close-end传输的开机时间是一样的,都比旧卡慢。
闪迪原厂FAE 之前给我电话会议,也默认 close-end 传输只有优化新卡和旧卡的速度差异,但是不是从根本上解决问题的方法。该开机慢的根本原因在于 闪迪在新卡上 并未重视 ddr50 这一传输速度的优化,在ddr50传输速度上闪迪算法做的还不行,和旧卡相比。
Ddr50 为emmc卡支持的一种传输速率。在clock 每个时钟脉冲上升沿和下降沿各采集一次 数据,我们的车机是每次采集8位数据,然后close 频率为50MHZ。采集频率,即emmc 理论传输速率为100M b/s。