RTOS Earlyinit及TTFF/TTCL说明


REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 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 文件分区介绍

    使用中的文件系统

    1. FWFS

      该文件系统支持读写操作,但缺点是读写大文件的速度很慢

    2. 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 界面:

    1. setting 文件为 json 格式,编译时转成 header file built-in 到 rtos,既保证的读取参数的时间,又保证了参数设定界面清晰明了。
    2. 支援 single sensor frame/realtime mode,dual sensor frame/realtime mode 等界面设置,[dual sensor realtime mode暂未support]。
    3. 在 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实现参考以下几点:

    1. 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接口。

    2. 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_FirstUnmaskVIF 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的方式,可以参考下述方式实验打开:

    1. 修改earlyinit setting的json文件,SNR一栏的"SNR_STREAM_ON_OFF"参数,由1改为0,
    2. 确保drv_earlyinit_XXX.cearlyinit.c文件已经实现fpStreamOnoffParserEx的回调函数,并且XXX_init_table.h中的sensor stream on动作由SNR_STREAM_ONOFF_2A1D这一个CMD替换放置最后。
    3. 确保drv_ss_cus_XXX_MIPI.c文件实现了pCus_sensor_streamon的回调函数。
    4. 在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使用权的时间点
    
    1. 假如load时间差异比较大,需要确认flash速率问题。
    2. 假如开始load kernel的时间点比较晚,需要确认RTOS释放flash使用权的时间点是否正确。