RTOS Earlyinit及TTFF/TTCL说明
REVISION HISTORY¶
Revision No. | Description |
Date |
---|---|---|
1.0 | 06/05/2024 |
1. 概述¶
Earlyinit是指将Sensor的初始化动作在系统启动的较早阶段提前实现。将Sensor的InitTable填写在CMDQ中,CMDQ是Sstar的一个独立的硬件,可以不依赖CPU执行一些简单的操作。使Sensor的初始化和系统的启动能并行处理。本文档主要介绍在RTOS阶段做Sensor Earlyinit,该做法界面相对简单及比较灵活。
2.RTOS Earlyinit流程¶
图1-1 RTOS Earlyinit流程图
RTOS启动后,会根据earlyinit使用flash情况,在不同阶段去启动Sensor earlyinit,上图所述的是在RTOS运行较早阶段启动Earlyinit的流程。
RTOS Earlyinit流程:
1、首先会初始化Sensor Interface相关的IO Padmux和注册earlyinit的sensor driver。
2、然后从json/header解析sensor earlyinit的相关参数(fps、shutter、gain等等)。
3、从XXX_init_table.h取得操作命令表,然后将要操作的命令(例powerdown/reset/delay)和I2C初始化表转换为实际的寄存器操作指令。根据上述解析到的earlyinit参数,替换在CMDQ操作指令中,转换完毕后存放在CMDQ申请好的内存中。然后trig CMDQ。
4、Earlyinit的操作是直接由CMDQ操作的,完成之后,就把操作Sensor的权限交回CPU->RTOS->I2C driver->Sensor。后续的例如AE/filp/mirror/fps就回到Driver的接口通过I2C设定给Sensor。
5、RTOS在跑完系统task后会去串流,对应到rtos_preload.c,RtosAppMainEntry -> MI_PreloadTask -> MI_PreloadMiPipe ->Test_vif_vpe_venc。创建MI Pipeline时,在MI_SNR_Enable接口中会检查Earlyinit是否完成,如果完成了就不会重复再下相关设定。APP设定的Sensor相关参数,需要与Earlyinit配置的一致。
3. RTOS Earlyinit Bootflow及分区介绍¶
该节主要讲述的是 RTOS sensor earlyinit 模式下的启动细节,会提到如何让 TTFF 的时机尽可能的快,还会提到目前的分区配置。
3.1 BOOT Flow 细节展示¶
如果需要了解详细的启动流程,请参考文档《启动流程》。
首先对启动中的部分细节进行展开:
启动方式一:(TTFF 会稍微晚一点,但 Sensor EarlyInit 支持吃flash 中的动态参数)
如上图所示,CPU 的 core0 会在 load 完 RTOS 之后,会唤醒 core1,然后再进入WFE 休眠状态。Core1 被 core0 唤醒之后,会进入 RTOS,紧接着是 初始化OS驱动以及其它外设驱动,然后再去将 Sensor EarlyInit 叫起来,这个做法可以让 Sesor EarlyInit 支持访问 flash的配置文件,缺点就是出流时机会稍微晚一点。
启动方式二:(TTFF 出流时机更短,但 Sensor EarlyInit 无法吃flash 中的动态参数)
如上图所示,CPU 的 core0 会在 load 完 RTOS 之后,会唤醒 core1,然后再进入WFE 休眠状态。Core1 被 core0 唤醒之后,会进入 RTOS,紧接着是 初始化OS驱动,然后立刻进入 Sensor EarlyInit,最后再进行 其它外设驱动 的初始化。
上述流程涉及到的接口:
接口 | 主要用途 |
---|---|
void drv_dualos_boot_richos_suspend(void); | 声明 RTOS 将 flash 占用的状态,core0 还是保持 WFE 状态 |
void drv_dualos_boot_richos_resume(void); | 释放 RTOS 将 flash 占用的状态,并且唤醒 core0 加载 linux 的流程 |
void earlyinit_main(void); | 执行 Sensor EarlyInit 的流程 |
CONFIG_EARLYINIT_SETTING_FS | project 下通过make menuconfig 进行配置: 1、开启此项,Sensor EarlyInit 将支持动态参数,走流程一 2、关闭此项,Sensor EarlyInit 不支持动态参数,走流程二 |
3.2 文件分区介绍¶
使用中的文件系统
-
FWFS
该文件系统支持读写操作,但缺点是读写大文件的速度很慢
-
LWFS
该文件系统只支持读取操作,不支持写入操作,优点是速度较快
目前存在两个文件分区:
挂载点 | 分区名 | 文件系统类型 | 描述 |
---|---|---|---|
/misc | MISC | fwfs | 用于存放可读写的配置文件,例如:modparam.json |
/rofiles | RO_FILES | lwfs | 仅支持读取的大配置文件,例如:IPU 模型 |
删除RO_FILES分区的方法
对应alkaid config 的分区配置文件 CONFIG_IMAGE_CONFIG 需要将 rofiles 分区删减。
示例alkaid config:
ipc-rtos_iford.nor.uclibc-9.1.0-ramdisk.ssc029c.128.qfn128_ddr3_fwfsonly_demo_aov_defconfig
对应的分区配置文件为:
nor-ramdisk.fwfsonly.rtos.partition.config
4. RTOS Earlyinit Setting说明¶
基于快启时间的考虑,通常的做法会将sensor的初始化参数hardcode定义在某个.c中来实现sensor earlyinit,但是这样做不方便修改和扩展。基于扩展性和兼容快启时间,sigmastar设计了一套 setting 界面:
- setting 文件为 json 格式,编译时转成 header file built-in 到 rtos,既保证的读取参数的时间,又保证了参数设定界面清晰明了。
- 支援 single sensor frame/realtime mode,dual sensor frame/realtime mode 等界面设置,[dual sensor realtime mode暂未support]。
- 在 rtos sensor earlyinit场景,还能支援 fs 去读取 json 更新设定,这种runtime读取的方式会影响快启时间,需要用户主动配置。
相关代码路径:
$SourceCode/rtos/proj/sc/customer/earlyinit_setting
earlyinit setting的json文件路径:
$SourceCode/project/board/rtos/earlyinit_setting/$(CHIP)
4.1 earlyinit setting 界面¶
$SourceCode/project
目录下先make xxx_defconfig
,再执行 make menuconfig
,进入 Rtos->Earlyinit Options,即可看到 earlyinit setting 相关选项:
Rtos ---> Earlyinit Options ---> (single_sensor_realtime.json) Set Earlyinit Setting Default Json Name () Set Earlyinit Setting Built-in Json Name List [ ] Support Dynamically Load Earlyinit Setting From File System (0x01) Bitmap for early init enable
1. Set Earlyinit Setting Default Json Name
设置要转成 header 的 json 名字,并且作为默认的 earlyinit setting,json需要在对应路径中有定义:
$SourceCode/project/board/rtos/earlyinit_setting/$(CHIP)
2. Set Earlyinit Setting Built-in Json Name List
设置要转成 header 的 json 名字列表,以空格隔开。
bootargs_rtos 添加 earlyinit_json=$(your_json_name)
,其中 $(your_json_name)
为对应的 json name。
3. Support Dynamically Load Earlyinit Setting From File System
决定是否要从文件系统读取 json 更新 earlyinit setting,即修改 /misc/earlyinit_setting.json 后 reboot 生效。
4. Bitmap for early init enable
earlyinit需要enable的sensor pad,与chmap参数类似,二进制bitmask,bit0对应pad0,bit1对应pad1。
4.2 earlyinit setting public api¶
public api 定义于 earlyinit_setting.h,具体如下:
EARLYINIT_SETTING_SNR_INFO_t *earlyinit_setting_get_snr_info(int dev, int chn); EARLYINIT_SETTING_PWM_INFO_t *earlyinit_setting_get_pwm_info(int dev, int chn); EARLYINIT_SETTING_VIF_INFO_t *earlyinit_setting_get_vif_info(int dev, int chn);
这三支API对应解析目前earlyinit json文件中的SNR、PWM、VIF三组栏位的参数,具体可参考earlyinit_customer.c的解析实现。
4.3 earlyinit json参数说明¶
以single_sensor_realtime.json为例,当前已定义SNR、PWM、VIF三组栏位的参数,
SNR栏位参数 | 说明 |
---|---|
SNR_ID | Sensor pad |
SNR_PLANE_MODE | Sensor Plane模式,Hdr Mode时为1,Linear mode时为0 |
SNR_RES_ID | drv_earlyinit_xxx.c对应的uPresetId,选择sensor的ResId |
SNR_FPSx1000 | Sensor Earlyinit的帧率 |
SNR_SHUTTER_US_LEF | Sensor Earlyinit的长曝光 |
SNR_GAINx1024_LEF | Sensor Earlyinit的长曝通道的gain值 |
SNR_SHUTTER_US_MEF | Sensor Earlyinit的中曝光 |
SNR_GAINx1024_MEF | Sensor Earlyinit的中曝通道的gain值 |
SNR_SHUTTER_US_SEF | Sensor Earlyinit的短曝光 |
SNR_GAINx1024_SEF | Sensor Earlyinit的短曝通道的gain值 |
SNR_MIRROR | Sensor Earlyinit的水平翻转 |
SNR_FLIP | Sensor Earlyinit的垂直翻转 |
SNR_STREAM_ON_OFF | Sensor Earlyinit初始化完成后,是否要streamon。 |
MIPI_LANE_NUM | sensor的lane num(暂未使用,预留参数) |
MIPI_HDR_MODE | mipi hdr mode(暂未使用,预留参数) |
PWM栏位参数(预留参数) | 说明 |
---|---|
PWM_ID | PWM HW ID(暂未使用,预留参数) |
PWM_CTRL_VSYNC | 是否需要用PWM control sensor的vsync,用于双sensor realtime控制vsync。(暂未使用,预留参数) |
VIF栏位参数 | 说明 |
---|---|
SNR_ID | VIF Group对应的sensor pad |
BIND_TYPE | VIF和ISP的绑定模式 |
VIF_DEV | VIF Dev ID |
VIF_PLANE_ID | vif plane id(暂未使用,预留参数) |
VIF_HDR_TYPE | vif HDR类型(暂未使用,预留参数) |
VIF_CROP_X | vif裁剪区域x坐标(暂未使用,预留参数) |
VIF_CROP_Y | vif裁剪区域y坐标(暂未使用,预留参数) |
VIF_CROP_W | vif裁剪区域宽度(暂未使用,预留参数) |
VIF_CROP_H | vif裁剪区域高度(暂未使用,预留参数) |
VIF_PIXEL_BITS | pixel格式(暂未使用,预留参数) |
4.4 静态更新参数¶
查看menuconfig中Set Earlyinit Setting Default Json Name参数,根据参数修改路径下
$SourceCode/project/board/rtos/earlyinit_setting/$(CHIP)
对应的json文件参数。
进入$SourceCode/project
,执行下面命令,重新编译:
make rtos -j32 make rtos_release -j32 make image-fast-nocheck -j32 #重新烧录image或rtos即可。
编译时会输出earlyinit setting parse json参数的结果。
4.5 动态更新参数¶
menuconfig中打开Support Dynamically Load Earlyinit Setting From File System选项。
运行在板端时,修改 /misc/earlyinit_setting.json 后 reboot 生效。
5. RTOS Earlyinit Customer界面¶
Earlyinit相关driver路径:
$SourceCode/rtos/proj/sc/driver/sysdriver/earlyinit_impl/* ==》earlyinit driver内部实现部分 $SourceCode/rtos/proj/sc/driver/sysdriver/earlyinit_rtos_api/* ==》earlyinit相关接口部分 $SourceCode/rtos/proj/sc/driver/sysdriver/earlyinit_main/* ==》earlyinit入口entry
用户可参考earlyinit_main部分实现,客制化实现Sensor earlyinit。
. ├── earlyinit_main.mak └── entry ├── cust │ ├── earlyinit_cust.mak │ └── src │ ├── earlyinit_customer.c ==》earlyinit customer扩展接口 │ └── earlyinit_drv_lightsensor.c ==》earlyinit阶段读取光敏的界面参考 ├── ipl //IPL earlyinit入口函数,无需关心 │ └── src │ ├── earlyinit_entry.S │ └── earlyinit_main.c ├── pub │ ├── drv_ipl_lightsensor.h │ ├── earlyinit_customer.h │ ├── earlyinit_initcall.h │ └── std_types.h └── rtos //RTOS earlyinit 入口函数 └── src └── earlyinit_main.c
Sensor Earlyinit实现参考以下几点:
-
earlyinit_main.c不需要修改;
1.1 hal_earlyinitSetPad()接口是调用底层parse sysdesc文件,设定sensor相关padmux;
1.2 rtk_earlyinit_prepare()是注册earlyinit的sensor driver,具体的sensor类型由alkid defconfig/menuconfig的CONFIG_SENSOR[X]指定,并根据CONFIG_SENSOR[X]_OPT中的chmap参数指定sensor挂载到哪一个sensor pad上,[x]为0/ 1/ 2/ 3。
1.3 CustomerEarlyinit_Rtos_run调用customer earlyinit接口。
-
earlyinit_customer.c,主要是实现CustomerEarlyinit_Rtos_run接口。
CONFIG_SENSOR_EARLYINIT_ENABLE的配置参数为上述menuconfig界面中提到的Bitmap for early init enable参数,用于决定多少个sensor pad跑earlyinit。
2.1 首先调用earlyinit_setting接口parse相应的earlyinit参数。
2.2 根据sensor pad调用hal_earlyinitSetI2c()/hal_earlyinitSetPin()接口设定i2c和sensor pin相关padmux。
2.3 传入earlyinit参数调用rtk_sensor_early_init_ex3()接口,调用到底层做cmdq table转换和trigger cmdq。
6. Sensor Driver文件说明¶
Sensor Driver会有两部分,分为Earlyinit和通用的Driver,使用上与Purelinux基本无差异。
相应的可参考IMX415或是SC4336P的实现,具体描述如下:
表1-1 Sensor Driver描述
文件 | 路径 | 描述 |
---|---|---|
drv_ss_cus_XXX_MIPI.c | sdk/driver/SensorDriver/drv/src | 通用的Driver文件,和Purelinux下用的完全一致。里面注册的函数会被MI_SNR/MI_VIF的接口调用到。 |
rtk_sensor_module_init.c | sdk/driver/SensorDriver/rtk | 在DualOS下Sensor Driver的Module Init文件,新增Driver在该文件下添加对应的Init Function |
drv_earlyinit_XXX.c earlyinit 文件 |
sdk/driver/SensorDriver/earlyinit/drv/src | xxxEarlyInitHandle: 注册Earlyinit driver的handle,定义相应回调函数的实现和默认的sensor earlyinit table |
xxxEarlyInitShutterAndFps: 回调函数。函数传参的shutter、fps、经过此函数后返回的I2C寄存器值,应该要和drv_ss_cus_XXX_MIPI.c中的pCus_SetFPS、pCus_SetAEUSecs转换的一致。不然是异常的。 |
||
xxxEarlyInitGain: 回调函数。函数传参的gain、经过此函数后返回的I2C寄存器值,应该要和drv_ss_cus_XXX_MIPI.c中的pCus_setAEGain转换的一致。不然是异常的。 |
||
xxxEarlySelResId: 回调函数。实现选择Earlyinit driver对应的Inittable和info handle。 |
||
xxxEarlyInitSelOrientEx: 回调函数。函数传参的mirror和flip、经过此函数后返回的I2C寄存器值,应该要和drv_ss_cus_XXX_MIPI.c中的pCus_setOrien转换的一致。不然是异常的。 |
||
xxxEarlyInitSelStreamOnoff: 回调函数。实现Sensor的StreamOn/Off,用于指定Sensor Inittable设定完成后,是否需要将sensor的stream on打开。同时需要实现drv_ss_cus_XXX_MIPI.c中的pCus_StreamOn接口。不然是异常的。 |
||
sensor_early_init.mak | sdk/driver/SensorDriver/earlyinit | 在DualOS下earlyinit的makefile文件,新增earlyinit在该文件下添加对应的.c文件 |
XXX_init_table.h | sdk/driver/SensorDriver/drv/inc | 该文件定义Sensor_init_table,包括了sensor从上电(powerdown/delay/reset)到I2C初始化到设定sensor寄存器表的所有操作。 后面lib中会将这个table转换为CMDQ可以操作的寄存器指令,交给CMDQ去操作。 其中的sensor初始化表的部分,应该要和drv_ss_cus_XXX_MIPI.c后续preload app设定inittable的完全一致,【通过resolution id选择到同一组】。 其中的SNR_SHUTTER_FPS_2A1D、SNR_GAIN_2A1D、SNR_ORIENTATION_2A1D、SNR_STREAM_ONOFF_2A1D,这几行CMD用于占位,后面才会跑到drv_earlyinit_XXX.c中的回调函数,实现sensor inittable可根据用户外部传参决定shutter、fps、gain、mirror、flip、streamon。 |
其实drv_earlyinit_XXX.c和XXX_init_table.h相应设定是来自于drv_ss_cus_XXX_MIPI.c。所以当用户只要有调好的drv_ss_cus_XXX_MIPI.c,就可以自己整理Earlyinit的部分。
7. Preload APP开发注意事项¶
APP设定的Sensor相关设定需与Earlyinit中对应,包含Sensor的Resolution Index、Fps、Hdr mode等;并且需要将shutter、gain参数通过ISP接口设定EarlyinitParam。preload APP支持通过接口获取Earlyinit的设定参数,可参考如下:
#if defined(CONFIG_SENSOR_EARLYINIT_SUPPORT) || defined(CONFIG_SENSOR_IPL_EARLYINIT_SUPPORT) unsigned char earlyinit_enable = 0; const EarlyInitPreloadCfg_t *pearlyinit_cfg = NULL; int i = 0; pearlyinit_cfg = DrvEarlyInitGetPreloadCfg(); CamOsPrintf("[earlyinit] snr num:%u. magic %u\n", pearlyinit_cfg->u32NumSnr, pearlyinit_cfg->u64Magic); for(i = 0; i < pearlyinit_cfg->u32NumSnr; ++i) { earlyinit_enable |= DrvEarlyInitForPreloadIsEnabled(i); } for(i = 0; i < 2; ++i) { CamOsPrintf("[earlyinit] pad %u, en:%u\n" "[earlyinit] u8ResIdx %u, bMirror:%u, bFlip %u\n" "[earlyinit] fps %u, bHDREn:%u, eWorkMode %u\n" "[earlyinit] Shutter LEF:%u, MEF:%u, SEF:%u\n" "[earlyinit] SensorGain LEF: %u, MEF:%u, SEF:%u\n" "[earlyinit] IspGain LEF: %u, MEF:%u, SEF:%u\n", pearlyinit_cfg->ChCfg[i].u8SnrPad, DrvEarlyInitForPreloadIsEnabled(i), pearlyinit_cfg->ChCfg[i].u8ResIdx, pearlyinit_cfg->ChCfg[i].bMirror, pearlyinit_cfg->ChCfg[i].bFlip, pearlyinit_cfg->ChCfg[i].u32SensorFrameRate, pearlyinit_cfg->ChCfg[i].bHDREn, pearlyinit_cfg->ChCfg[i].eWorkMode, pearlyinit_cfg->ChCfg[i].u32ShutterLEF, pearlyinit_cfg->ChCfg[i].u32ShutterMEF, pearlyinit_cfg->ChCfg[i].u32ShutterSEF, pearlyinit_cfg->ChCfg[i].u32SensorGainLEFx1024, pearlyinit_cfg->ChCfg[i].u32SensorGainMEFx1024, pearlyinit_cfg->ChCfg[i].u32SensorGainSEFx1024, pearlyinit_cfg->ChCfg[i].u32IspGainLEFx1024, pearlyinit_cfg->ChCfg[i].u32IspGainMEFx1024, pearlyinit_cfg->ChCfg[i].u32IspGainSEFx1024); } for(i = 0; i < 2; ++i) { CamOsPrintf("[earlyinit] u16SnrEarlyFlicker:%u, streamon %u\n",pearlyinit_cfg->ChCfg[i].u16SnrEarlyFlicker, pearlyinit_cfg->ChCfg[i].bStreamOnoff); } #endif
完整的Preload APP开发可参考rtos_preload.c文件。
8. TTFF及TTCL说明¶
TTFF(Time To First Frame)是指开机到输出第一帧出图时间,与Sensor的上电时序和APP初始化Pipeline到ready的时间有关系,不同Sensor和APP的行为差异可能会导致TTFF有差异。
TTCL(Time To Command Line)是指开机到命令行的时间,与所使用的Flash型号、RTOS Size、RTOS访问flash时间、Kernel Size、Kernel ramdisk Size相关,如要确保快速开机进入命令行,首先需要做的就是裁剪Size。
Sigmastar公版使用XM - XM25QH128A(ID:20-70-18)快启nor-Flash和os04d10 sensor的timestamp如下:
/ # cat /sys/class/sstar/msys/booting_time IPL (13 records) 000 time: 10969, diff: 0, IPL+, 0 001 time: 16906, diff: 5937, LD:SMF+, 0 002 time: 16912, diff: 6, LD:SMF-, 0 003 time: 16914, diff: 2, LD:CUST+, 0 004 time: 17366, diff: 452, LD:CUST-, 0 005 time: 17453, diff: 87, OSJMP:0x20000400+, 0 006 time: 17515, diff: 62, CUST+, 0 007 time: 17573, diff: 58, LD:RTK+, 0 008 time: 34860, diff: 17287, LD:RTK-, 0 //IPL_CUST load RTOS时间 009 time: 137401, diff: 102541, LD:KERNEL+, 0 //RTOS使用完成flash,唤醒IPL_CUST开始load kernel的时间 010 time: 170138, diff: 32737, LD:KERNEL-, 0 //IPL_CUST load kernel的时间 011 time: 170140, diff: 2, LD:RAMFS+, 0 012 time: 172737, diff: 2597, LD:RAMFS-, 0 //IPL_CUST load kernel ramfs的时间 Total cost: 161768(us) RTOS (26 records) 000 time: 37708, diff: 0, Rtos Premain Start //RTOS start run时间 001 time: 37892, diff: 184, Rtos Sensor Early Init Start //earlyinit start时间 002 time: 49275, diff: 11383, MI_SYS_IMPL_Init 003 time: 50997, diff: 1722, MI_SYS_IMPL_Init end 004 time: 51205, diff: 208, ST_BasePipelineInit Start 005 time: 53659, diff: 2454, MI_SENSOR_IMPL_Init 006 time: 54023, diff: 364, MI_VIF_IMPL_Init 007 time: 54994, diff: 971, MI_SENSOR_IMPL_Enable 008 time: 55706, diff: 712, MI_VENC_IMPL_Init 009 time: 65846, diff: 10140, PreloadFile Start 010 time: 67326, diff: 1480, pad0 Sensor Enabled //earlyinit check done时间 011 time: 77833, diff: 10507, MI_SENSOR_IMPL_Enable end 012 time: 105811, diff: 27978, VIF ch0 int 0 //vif出流第一帧时间 013 time: 108518, diff: 2707, ST_BasePipelineInit Done 014 time: 118415, diff: 9897, Vif_FirstUnmask //pipeline ready等接收frame的时间 015 time: 137399, diff: 18984, PreloadFile end //RTOS释放flash使用权的时间 016 time: 172390, diff: 34991, E_MHAL_SCL_IRQ_VSYNC 017 time: 172416, diff: 26, VIF ch0 int 1 //vif出流第二帧时间 018 time: 173039, diff: 623, VIF_FirstFrameDone 019 time: 201008, diff: 27969, RPMSG SHM init 020 time: 235064, diff: 34056, Isp_FirstFrameDone //isp第一帧完成时间,可通过该时间减去一帧处理时间计算真实TTFF 021 time: 235455, diff: 391, _MI_VENC_IMPL_MhalVencEncodeOne 022 time: 271432, diff: 35977, adaptor announce 023 time: 271479, diff: 47, dualos announce 024 time: 272402, diff: 923, VENC_FirstFrameDone 025 time: 376949, diff: 104547, Ready to Linux Total cost: 339241(us) LINUX (11 records) 000 time: 173677, diff: 0, start_kernel+, 853 //kernel start run的时间 001 time: 177806, diff: 4129, setup_arch-, 874 002 time: 197838, diff: 20032, kernel_init+, 1429 003 time: 199706, diff: 1868, do_basic_setup+, 1328 004 time: 200866, diff: 1160, do_initcalls+, 1306 005 time: 201016, diff: 150, rpmsg_shm_linkup, 699 006 time: 201039, diff: 23, rpmsg_shm_init, 733 007 time: 278588, diff: 77549, dualos_announce_recv, 960 008 time: 300905, diff: 22317, adaptor_announce_recv, 2176 009 time: 346243, diff: 45338, do_basic_setup-, 1337 010 time: 346815, diff: 572, ramdisk_execute_command+, 1456 //TTCL时间,启动到console的时间 Total cost: 173138(us)
8.1 TTFF分析¶
从上述timestamp分析:
TTFF时间为172ms --> 017 time: 172416, diff: 26, VIF ch0 int 1
由于需要pipeline ready才可以真正的开始接收图像,pipeline ready的时间戳为【014 time: 118415, diff: 9897, Vif_FirstUnmask】;此时间后的第一个frame start才是真正能接收到的图像,所以上述的TTFF时间是从VIF的第二帧开始算。
为了适配不同sensor、不同帧率和不同APP 初始化行为的差异,Sigmastar支持在Earlyinit完成后不做sensor的stream on的动作,等到pipeline ready后再做stream on的动作,这样只需要等一个曝光时间就可以使sensor出流(不同sensor stream on到出流会有相应的行为差异)。避免刚好错过一帧,需要等一帧的时间才能出流,相对而言时间有优化。
下面这种timestamp的时序,就是错过了一帧,需要等一帧的间隔时间才能接收真实的第一帧图像。假如 Vif_FirstUnmask 在 VIF chn0 int 0 之前,则接收到第一帧;假如**Vif_FirstUnmask** 在 VIF chn0 int 0 之后,则错过第一帧。
012 time: 105811, diff: 27978, VIF ch0 int 0 //vif出流第一帧时间 013 time: 108518, diff: 2707, ST_BasePipelineInit Done 014 time: 118415, diff: 9897, Vif_FirstUnmask //pipeline ready等接收frame的时间 015 time: 137399, diff: 18984, PreloadFile end //RTOS释放flash使用权的时间 016 time: 172390, diff: 34991, E_MHAL_SCL_IRQ_VSYNC 017 time: 172416, diff: 26, VIF ch0 int 1 //vif出流第二帧时间
假如使出现第一帧图像丢失需要改成等到pipeline ready后再做stream on的方式,可以参考下述方式实验打开:
- 修改earlyinit setting的json文件,SNR一栏的"SNR_STREAM_ON_OFF"参数,由1改为0,
- 确保drv_earlyinit_XXX.cearlyinit.c文件已经实现fpStreamOnoffParserEx的回调函数,并且XXX_init_table.h中的sensor stream on动作由SNR_STREAM_ONOFF_2A1D这一个CMD替换放置最后。
- 确保drv_ss_cus_XXX_MIPI.c文件实现了pCus_sensor_streamon的回调函数。
- 在APP做完Pipeline初始化后,再调用MI_VIF_EnablePort接口(后续该动作会收到内部)。
8.2 TTCL分析¶
从上述timestamp分析:
TTCL时间为346ms --> 010 time: 346815, diff: 572, ramdisk_execute_command+, 1456
TTCL时间与RTOS code size,Linux code size有直接关系,并且在RTOS使用完成flash后才能继续load kernel。所以参考以下几个时间点可以分析哪一阶段的时间不符合预期:
007 time: 17573, diff: 58, LD:RTK+, 0 008 time: 34860, diff: 17287, LD:RTK-, 0 //load RTOS消耗17.2ms 009 time: 137401, diff: 102541, LD:KERNEL+, 0 010 time: 170138, diff: 32737, LD:KERNEL-, 0 //load kernel消耗32.7ms 011 time: 170140, diff: 2, LD:RAMFS+, 0 012 time: 172737, diff: 2597, LD:RAMFS-, 0 //load ramfs消耗2.5ms ----- 015 time: 137399, diff: 18984, PreloadFile end //RTOS释放flash使用权的时间点
- 假如load时间差异比较大,需要确认flash速率问题。
- 假如开始load kernel的时间点比较晚,需要确认RTOS释放flash使用权的时间点是否正确。