其他分享
首页 > 其他分享> > 高通msm-V4L2-Camera驱动浅析3-session

高通msm-V4L2-Camera驱动浅析3-session

作者:互联网

唠嗑

最近看了维神的《沙丘》,我觉得是真的好看,配乐精彩绝伦,构图美轮美奂,场景气势磅礴,但是不是适合所有人;在各种廉价爆米花电影充斥主流商业片的今天,还能看到这么一部如此古典叙事且代表着好莱坞最高制作水准的巨作,简直幸运!

##系列文章
高通msm-V4L2-Camera驱动浅析1-初识
高通msm-V4L2-Camera驱动浅析2-框架详解
高通msm-V4L2-Camera驱动浅析3-session
高通msm-V4L2-Camera驱动浅析4-stream
高通msm-V4L2-Camera驱动浅析5-buffer

一、session(会话)的设计思路

在微信聊天的时候,我们想要跟人沟通联系,就会创建一个session(会话),多个人单独聊天,就会有多个session;
每一个session负责管理所有的资源,比如表情包、图片、聊天记录等。

高通的思路也是如此:

二、一个session是如何创建的

2.1、session的数据结构

msm_session

struct msm_session {
	struct list_head list;

	/* session index */
	unsigned int session_id;

	/* event queue sent by imaging server */
	struct msm_event event_q;

	/* ACK by imaging server. Object type of
	 * struct msm_command_ack per open,
	 * assumption is application can send
	 * command on every opened video node
	 */
	struct msm_queue_head command_ack_q;

	/* real streams(either data or metadate) owned by one
	 * session struct msm_stream
	 */
	struct msm_queue_head stream_q;
	struct mutex lock;
	struct mutex lock_q;
	struct mutex close_lock;
	rwlock_t	stream_rwlock;
	struct kgsl_pwr_limit *sysfs_pwr_limit;
}

msm_event

/** msm_event:
 *
 *  event sent by imaging server
 **/
struct msm_event {
	struct video_device *vdev;
	atomic_t on_heap;
};

这里最重要的就是msm_event event_q,本质上就是一个video_device 实例。
另外还有cmd队列和stream队列比较重要。

2.2 session和video_device的关系


png)

2.3 video_device、v4l2_device和v4l2_subdev的关系

2.4 session的创建

struct msm_queue_head {
	struct list_head list;
	spinlock_t lock;
	int len;
	int max;
};
static struct msm_queue_head *msm_session_q;
static int msm_probe(struct platform_device *pdev)
{
···
    //申请内存
	msm_session_q = kzalloc(sizeof(*msm_session_q), GFP_KERNEL);
    //初始化
	msm_init_queue(msm_session_q);
···
}

在msm_probe时,msm_session_q队列就会申请内存,然后初始化。

int msm_create_session(unsigned int session_id, struct video_device *vdev)
{
	struct msm_session *session = NULL;
    //判断msm_session_q队列是否为空
	if (!msm_session_q) {
		pr_err("%s : session queue not available Line %d\n",
				__func__, __LINE__);
		return -ENODEV;
	}
    //根据session_id查找当前会话是否在全局session队列中
	session = msm_queue_find(msm_session_q, struct msm_session,
		list, __msm_queue_find_session, &session_id);
    //如果会话已经存在,直接返回
	if (session) {
		pr_err("%s: Session exist session_id=%d\n",
				__func__, session_id);
		return -EINVAL;
	}
    //申请内存空间
	session = kzalloc(sizeof(*session), GFP_KERNEL);
    //赋值session_id
	session->session_id = session_id;
    //赋值video_device设备
	session->event_q.vdev = vdev;
    //初始化cmd队列
	msm_init_queue(&session->command_ack_q);
    //初始stream队列
	msm_init_queue(&session->stream_q);
    //入队:将新建的session加入全局队列msm_session_q
	msm_enqueue(msm_session_q, &session->list);
	mutex_init(&session->lock);
	mutex_init(&session->lock_q);
	mutex_init(&session->close_lock);
	rwlock_init(&session->stream_rwlock);

	return 0;
}

会话的创建流程,上一篇文章有讲到:
rc = msm_create_session(pvdev->vdev->num, pvdev->vdev);
这里第一个参数是session_id = pvdev->vdev->num;
也就是对应我们video1/video2里的1和2;
即session_id = 1或者2

Stay Hungry,Stay Foolish!

标签:struct,浅析,queue,msm,session,id,event
来源: https://blog.csdn.net/justXiaoSha/article/details/122210035