zoukankan      html  css  js  c++  java
  • RT-thread内核之事件

    一、事件控制块:在include/rtdef.h中

    #ifdef RT_USING_EVENT
    /**
     * flag defintions in event
     */
    #define RT_EVENT_FLAG_AND               0x01            /**< logic and */
    #define RT_EVENT_FLAG_OR                0x02            /**< logic or */
    #define RT_EVENT_FLAG_CLEAR             0x04            /**< clear flag */
    
    /*
     * event structure
     */
    struct rt_event
    {
        struct rt_ipc_object parent;                        /**< inherit from ipc_object *///从IPC对象派生
    
        rt_uint32_t          set;                           /**< event set */              //保存接收到的事件集
    };
    typedef struct rt_event *rt_event_t;
    #endif

    二、事件相关接口:在src/ipc.c中

    创建事件:
    rt_event_t rt_event_create(const char *name, rt_uint8_t flag);
    调用该函数接口时,系统会从动态内存堆中分配事件对象,然后进行对象的初始化,IPC对象初始化,并把set设置成0。
    
    删除事件:
    rt_err_t rt_event_delete(rt_event_t event);
    在调用rt_event_delete函数删除一个事件对象时,应该确保该事件不再被使用。在删除前会唤醒所有挂起在该事件上的线程(线程的返回值是-RT_ERROR),然后释放事件对象占用的内存块
    初始化事件:
    rt_err_t rt_event_init(rt_event_t event, const char *name, rt_uint8_t flag);
    调用该接口时,需指定静态事件对象的句柄(即指向事件控制块的指针),然后系统会初始化事件对象,并加入到系统对象容器中进行管理。
    
    脱离事件:
    rt_err_t rt_event_detach(rt_event_t event);
    系统首先唤醒所有挂在该事件等待队列上的线程(线程的返回值是- RT_ERROR ),然后将该事件从内核对象管理器中删除
    发送事件:
    rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set);
    通过发送事件服务,可以发送一个或多个事件。使用该函数接口时,通过参数set指定的事件标志来设定event对象的事件标志值,然后遍历等待在event事件对象上的等待线程链表,判断是否有线程的事件激活要求与当前event对象事件标志值匹配,如果有,则唤醒该线程。
    发送事件首先会将事件集set保存到事件控制内部,然后遍历事件控制块内所有因等待事件的接收线程,如果条件符合则唤醒它 接收事件: rt_err_t rt_event_recv(rt_event_t
    event, //事件对象的句柄 rt_uint32_t set, //接收线程感兴趣的事件 rt_uint8_t option, //接收选项 rt_int32_t timeout, //指定超时时间 rt_uint32_t *recved); //指向收到的事件 内核使用32位的无符号整型数来标识事件,它的每一位代表一个事件,因此一个事件对象可同时等待接收32个事件,内核可以通过指定选择参数“逻与”或“逻辑或”来选择如何激活线程,使用“逻辑与”参数表示只有当所有等待的事件都发生时才激活线程,而使用“逻辑或”参数则表示只要有一个等待的事件发生就激活线程。 当用户调用这个接口时,系统首先根据set参数和接收选项来判断它要接收的事件是否发生,如果已经发生,则根据参数option上是否设置有RT_EVENT_FLAG_CLEAR来决定是否重置事件的相应标志位,然后返回(其中recved参数返回收到的事件); 如果没有发生,则把等待的set和option参数填入线程本身的结构中,然后把线程挂起在此事件对象上,直到其等待的事件满足条件或等待时间超过指定的超时时间。如果超时时间设置为零,则表示当线程要接受的事件没有满足其要求时就不等待,而直接返回-RT_TIMEOUT。
    接收事件比较简单,如果接收到事件则判断它是否为它关心的事件,如果是,则保存事件,如果不是,则当没有接收到事件情况一起处理。接下来就是没有事件到达的情况,还是老规矩,先判断时间参数是否为0,如果是则直接返回超时,如果不是,则设置一定时器然后启动它,接着重新调度线程,然后根据当前线程的error值是否为RT_EOK来判断是否有新的并且符合条件的事件到达,如果不是,则返回错误码,如果是,则保存事件,最终返回OK。
    控制事件:
    rt_err_t rt_event_control(rt_event_t event, rt_uint8_t cmd, void *arg);
    只支持RT_IPC_CMD_RESET这个命令,表示复位事件,将事件集set清0。
  • 相关阅读:
    Django之Form组件
    随笔——python截取http请求报文响应头
    django文件上传
    django框架(View)
    s15day14 ssh秘钥远程连接
    Python开发【第十九篇】:Python操作MySQL
    s15day12作业:MySQL练习题参考答案
    python+django+wusgi+nginx安装部署
    Python之路【第二十四篇】:Python学习路径及练手项目合集
    gideros-with-zerobrane
  • 原文地址:https://www.cnblogs.com/King-Gentleman/p/4315443.html
Copyright © 2011-2022 走看看