打印

事件驱动中,信号量的处理

[复制链接]
1565|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Simon21ic|  楼主 | 2015-8-23 16:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Simon21ic 于 2015-8-23 16:12 编辑

之前说过,在一些特定的使用情况下,目标进程无法立即处理事件的时候,作为事件的缓冲。

那么在事件驱动下,如果使用信号量呢?
这里举例说明,如果要实现一个USB Hub的USB设备端驱动,端口上的变化,需要通过中断传输,发送notification给USB主机。发送notification的时候,会先写数据到相应的USB端点,然后等到数据发送完成,再看是否有其他notification需要发送。那么在等待USB发送完成的时候,就无法处理notification事件,所以就需要用到信号来缓冲。

第一种比较简单的方式,PT线程:
vsf_err_t vsfusbd_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
{
    struct vsfusbd_HUB_param_t *param =
            (struct vsfusbd_HUB_param_t *)sm->user_data;
    struct vsfusbd_device_t *device = param->device;
    uint8_t notification;

    vsfsm_pt_begin(pt);

    vsfsm_sem_init(param->sem, 0, VSFUSBD_HUB_EVT_CHANGE);
    while (1)
    {
        if (vsfsm_sem_pend(param->sem, sm))
        {
            vsfsm_pt_wfe(pt, VSFUSBD_HUB_EVT_CHANGE);
        }

        notification = 1;
        device->drv->ep.write_IN_buffer(param->ep_in, notification, 1);
        device->drv->ep.set_IN_count(param->ep_in, 1);
        vsfsm_pt_wfe(pt, VSFUSBD_HUB_EVT_INOK);
    }

    vsfsm_pt_end(pt);
    return VSFERR_NONE;
}

这里,device->drv->ep是控制USB端点的接口,写入数据后,当发送完成后,会发送VSFUSBD_HUB_EVT_INOK事件。所以,写端口后,就可以直接简单等待这个事件就行。
vsfsm_sem_init用于初始化信号量,并且设置事件为VSFUSBD_HUB_EVT_CHANGE,主循环里,就试图获取信号量(vsfsm_sem_pend),如果得到的话返回0,就发送notification,否则返回非0,等待VSFUSBD_HUB_EVT_CHANGE事件。
其他代码发送了信号后,信号量发现有任务在等待,就发送相应的事件。
PT的代码简单明了,类似阻塞的代码方式,一看就明白。

用事件驱动的方式的话,就会相对麻烦一些,不过也很有意思:
static struct vsfsm_state_t *
vsfusbd_evt_handler(struct vsfsm_t *sm, vsfsm_evt_t evt)
{
    struct vsfusbd_HUB_param_t *param =
            (struct vsfusbd_HUB_param_t *)sm->user_data;
    struct vsfusbd_device_t *device = param->device;
    uint8_t notification;

    switch (evt)
    {
    case VSFSM_EVT_INIT:
        vsfsm_sem_init(param->sem, 0, VSFUSBD_HUB_EVT_CHANGE);
    case VSFUSBD_HUB_EVT_INOK:
        if (vsfsm_sem_pend(param->sem, sm))
        {
            break;
        }
    case VSFUSBD_HUB_EVT_CHANGE:
        notification = 1;
        device->drv->ep.write_IN_buffer(param->ep_in, notification, 1);
        device->drv->ep.set_IN_count(param->ep_in, 1);
        break;
    }
    return NULL;
}
INIT为初始化事件,初始化信号,然后马上等待信号,这里一定等待不到,所以之后有信号后,系统会发送VSFUSBD_HUB_EVT_CHANGE事件。
收到VSFUSBD_HUB_EVT_CHANGE事件后(信号量会把本线程从等待列表中去掉,除非再次调用sem_pend,否则不会收到CHANGE事件),写USB端口,之后USB模块会发送VSFUSBD_HUB_EVT_INOK事件
VSFUSBD_HUB_EVT_INOK事件里,继续等待信号量,是不是很简单?


相关帖子

沙发
Simon21ic|  楼主 | 2015-8-23 17:54 | 只看该作者
本帖最后由 Simon21ic 于 2015-8-23 18:08 编辑
yyy71cj 发表于 2015-8-23 16:57
在我的印象中……
        关于信号量这个概念,我一直以为这是一个不切实的叫法,也不知道到底是命名的问 ...
任何编程,不都只是一个方法吗?还能是什么?
C#里废除的话,那是不是指C和C++里有?
在ANSI C标准里有不?我去研究研究

使用特权

评论回复
板凳
Simon21ic|  楼主 | 2015-8-23 18:04 | 只看该作者
我在百度里搜索到很多C#利用信号量的**,信号量一般是操作系统提供的东西,不明白和C#有什么关系

使用特权

评论回复
地板
李冬发| | 2015-8-24 02:18 | 只看该作者
:lol

使用特权

评论回复
5
keer_zu| | 2015-8-24 09:52 | 只看该作者
yyy71cj 发表于 2015-8-23 16:57
在我的印象中……
        关于信号量这个概念,我一直以为这是一个不切实的叫法,也不知道到底是命名的问 ...

信号量和语言有关系?这是知道面向对象语言里,类和类之间有类似消息这样的机制。

使用特权

评论回复
6
Simon21ic|  楼主 | 2015-8-24 10:14 | 只看该作者
yyy71cj 发表于 2015-8-24 07:07
信号量是早期多线程编程中的一个都有的概念和同步线程的方法,其实即使没有这个概念,我们编程时也会用到 ...

信号量确实和系统有关,和语言无关,C#里本来就没有信号量,.Net里的System.Threading里有Samephore。其他语言里,也没有信号量,信号量在系统的头文件里。或者,在你的构架里,信号量是一个变量,但这个都无法阻止信号量的存在。
我倒觉得以后这种构架化的开发方式会越来越流行,因为芯片资源越来越多
明年会有高资源ARM不到1美金,就市场角度而言,ARM还没到没落的时候

使用特权

评论回复
7
keer_zu| | 2015-8-24 10:32 | 只看该作者
Simon21ic 发表于 2015-8-24 10:14
信号量确实和系统有关,和语言无关,C#里本来就没有信号量,.Net里的System.Threading里有Samephore。其 ...

是的,信号量不是语言层次的东西。语言本身没有实体的概念,不关注实体之间的通信协调。所实现的“功能库”里面或许有类似概念,但是库不是语言本身的东西。

使用特权

评论回复
8
m564522634| | 2015-8-24 16:38 | 只看该作者
yyy71cj 发表于 2015-8-23 16:57
在我的印象中……
        关于信号量这个概念,我一直以为这是一个不切实的叫法,也不知道到底是命名的问 ...

这应该不是一个编程语言的概念吧,是操作系统中的一个概念。 只能过对事件的响应与处理分开的一种方法了。和linux的上下级中断一样的作用了。

使用特权

评论回复
9
keer_zu| | 2015-8-24 16:45 | 只看该作者
m564522634 发表于 2015-8-24 16:38
这应该不是一个编程语言的概念吧,是操作系统中的一个概念。 只能过对事件的响应与处理分开的一种方法了 ...

是共享资源的一种手段吧,和事件响应处理有什么关系?linux没有上下级中断的概念,是上半部,下半部,是完成不同响应速度和级别的。:L

使用特权

评论回复
10
m564522634| | 2015-8-24 16:49 | 只看该作者
keer_zu 发表于 2015-8-24 16:45
是共享资源的一种手段吧,和事件响应处理有什么关系?linux没有上下级中断的概念,是上半部,下半部,是 ...

想了下,你是对的, 谢谢指正学习了。

使用特权

评论回复
11
keer_zu| | 2015-8-24 17:11 | 只看该作者
m564522634 发表于 2015-8-24 16:49
想了下,你是对的, 谢谢指正学习了。

呵呵,不客气,相互学习。欢迎常来讨论。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:www.versaloon.com --- under construction

266

主题

2597

帖子

104

粉丝