第16讲 CRM之Session和Link是什么

2024年11月05日 第16讲 CRM之Session和Link是什么 极客笔记

本讲是Camera KMD ISP子系统专题的第16讲,我们讲解Camera KMD ISP子系统CRM之Session和Link。

更多资源:

资源 描述
在线课程 极客笔记在线课程
知识星球 星球名称:深入浅出Android Camera
星球ID: 17296815
Wechat 极客笔记圈

Session

session之间关系

crm session与umd关系

  1. 一个crm session对应一个camx session
  2. 一个crm session对应一个虚拟session, 例如eeprom在camx session创建之前就需要读取eeprom数据,这时会创建一个virtual session对应底层一个crm session

crm session在umd代理

CSLHwsession g_CSLHwInstance.sessionList[256]

crm session在kmd存在形式

struct cam_req_mgr_core_session {
    int32_t                       session_hdl;//crm session句柄
    uint32_t                      num_links;//有多少个crm link
    struct cam_req_mgr_core_link *links[MAXIMUM_LINKS_PER_SESSION];//crm link数组
    struct list_head              entry;//链表节点串联多个crm session
    struct mutex                  lock;
    int32_t                       force_err_recovery;//标志是否需要强制error恢复
    int32_t                       sync_mode;//多摄时同步模式
};
list_add(&cam_session->entry, &g_crm_core_dev->session_head);

Virtual session创建过程

Camx session创建过程

Crm session创建过程KMD部分

static long cam_private_ioctl(struct file *file, void *fh, bool valid_prio, unsigned int cmd, void *arg)
{
    switch (k_ioctl->op_code) {
        case CAM_REQ_MGR_CREATE_SESSION: {
            cam_req_mgr_create_session(&ses_info);
        }
        break;
}
int cam_req_mgr_create_session(struct cam_req_mgr_session_info *ses_info)
{
    //在kmd分配一个crm session
    struct cam_req_mgr_core_session *cam_session = kzalloc(sizeof(*cam_session), GFP_KERNEL);
    session_hdl = cam_create_session_hdl((void *)cam_session);//为crm session创建一个handle
    ses_info->session_hdl = session_hdl;//session handle返回到umd
    cam_session->session_hdl = session_hdl;//session handle保存到kmd
    list_add(&cam_session->entry, &g_crm_core_dev->session_head);//保存创建的crm session到全局链表session_head中
}

Link

Link 是什么

  • Link是crm用于精准控制实时设备的重要数据结构,里面维护了所有的实时设备句柄
  • Link与umd的pipeline不是一一对应关系,上层realtime pipeline会在crm创建一个link与之对应

Link 结构体

struct cam_req_mgr_core_link {
    int32_t link_hdl;//link句柄
    int32_t num_devs;//有多少个rt设备
    struct cam_req_mgr_core_workq       *workq;//用于异步任务的工作队列
    int32_t                              pd_mask;//标志有哪些pipeline delay的设备
    struct cam_req_mgr_connected_device *l_dev;//保存所有的rt设备
    struct cam_req_mgr_req_data          req;//request data管理,例如in_q
    struct cam_req_mgr_timer            *watchdog;//监控sof freeze的看门狗
    void                                *parent;//属于哪个crm session
}

Link 创建流程UMD部分

Link 创建流程KMD部分

static long cam_private_ioctl(struct file *file, void *fh, bool valid_prio, unsigned int cmd, void *arg)
{
    switch (k_ioctl->op_code) {
        case CAM_REQ_MGR_LINK_V2: {
            cam_req_mgr_link_v2(&ver_info);
        }
        break;
}
int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info)
{
    1. 为session预留一个link
    link = __cam_req_mgr_reserve_link(cam_session);
    2. 为link创建唯一的句柄
    link->link_hdl = cam_create_device_hdl(&root_dev);
    3. 为所有的rt devices分配内存,由link->l_dev记录
    __cam_req_mgr_create_subdevs(&link->l_dev, link_info->u.link_info_v2.num_devices);
    4. 使用各个device ops 查询所有的rt device获得设备信息,初始化in_q和request tables等
    __cam_req_mgr_setup_link_info(link, link_info)
}
__cam_req_mgr_reserve_link(cam_session)
{
    link = &g_links[i];//从全局g_links数组中取出一个未占用的Link
    //为link->req.in_q分配一个in_q
    in_q = kzalloc(sizeof(struct cam_req_mgr_req_queue),GFP_KERNEL);
    link->req.in_q = in_q;
    //关联crm session和link
    link->parent = (void *)session;
    session->num_links++;
}
__cam_req_mgr_setup_link_info(link, link_info)
{
    //初始化link->req.in_q
    __cam_req_mgr_setup_in_q(&link->req);
    //获取rt device的设备信息,例如pipeline delay
    for (i=0; i<num_devices; i++)
    {
        dev->ops->get_dev_info(&dev->dev_info);
    }
    //为不同pipeline delay创建request table,并通知设备link_setup
    for (i=0; i<num_devices; i++)
    {
        pd_tbl = __cam_req_mgr_create_pd_tbl(dev->dev_info.p_delay);
        __cam_req_mgr_add_tbl_to_link(&link->req.l_tbl, pd_tbl);
    }
    //刚启动时,pd 1的 table不需要遍历,会忽略一次。这里需要手动设置一下
    __cam_req_mgr_tbl_set_all_skip_cnt(&link->req.l_tbl);
}

本文链接:http://so.lmcjl.com/news/17096/

展开阅读全文