全部文档
OneOS简介 硬件支持 编译构造工具 API参考文档 高级语言 用户编程手册 应用笔记 FAQ

事件


简介

事件是任务间同步的一种机制。多个事件可以通过一个32位无符号整形数据表示,其中每一个bit代表一个事件,可以通过“逻辑或”或者“逻辑与”将多个事件关联起来,形成事件集合,任务等待该事件集合满足条件之后,才会被唤醒。“逻辑或”指任务等到集合中的任意一个事件即可被唤醒,而“逻辑与”需要等到集合中的所有事件才会被唤醒。

一个事件仅用一个bit表示,仅用于同步,无法传输数据;如果多次向任务发送同一事件,且任务还没有来得及读走该事件,则该事件只会被当成一次处理。


重要定义及数据结构

枚举

enum os_event_option
{
    OS_EVENT_OPTION_AND               = 0x01,
    OS_EVENT_OPTION_OR                = 0x02,
    OS_EVENT_OPTION_CLEAR             = 0x04
};
定义 说明
OS_EVENT_OPTION_AND 逻辑与,接收事件的任务收到集合中的所有事件才会被唤醒
OS_EVENT_OPTION_OR 逻辑或,接收事件的任务收到集合中的任一事件即可被唤醒
OS_EVENT_OPTION_CLEAR 清除事件

结构体

struct os_event
{
    os_ipc_object_t parent;                 /* inherit from ipc_object */
    os_uint32_t     set;                    /* event set */
};
struct os_event重要参数 说明
set 事件的集合

API列表

接口 说明
os_event_init 以静态方式初始化事件,即事件对象的空间由使用者提供
os_event_deinit 反初始化事件,与os_event_init()匹配使用
os_event_create 以动态方式创建并初始化事件,即事件对象的空间采用动态申请内存的方式获得
os_event_destroy 销毁事件,与os_event_create()匹配使用
os_event_send 发送事件
os_event_recv 接收事件
os_event_control 控制或更改事件的行为属性

os_event_init

该函数以静态方式初始化事件,事件对象的内存空间由使用者提供,函数原型如下:

os_err_t os_event_init(os_event_t *event, const char *name, os_ipc_flag_t flag);
参数 说明
event 事件句柄
name 事件名字
flag 标志,可以取OS_IPC_FLAG_FIFO和OS_IPC_FLAG_PRIO;当取值为OS_IPC_FLAG_FIFO时,等待的任务将按照先进先出的方式排队,先进入的任务先被唤醒;当取值为OS_IPC_FLAG_PRIO时,等待的任务将按照任务优先级排队,优先级高的任务先被唤醒
返回 说明
OS_EOK 初始化成功

os_event_deinit

该函数用于反初始化事件,与os_event_init()配合使用,函数原型如下:

os_err_t os_event_deinit(os_event_t *event);
参数 说明
event 事件句柄
返回 说明
OS_EOK 反初始化成功

os_event_create

该函数以动态方式创建并初始化事件,事件对象的内存空间采用动态申请的方式获得,函数原型如下:

os_event_t *os_event_create(const char *name, os_ipc_flag_t flag);
参数 说明
name 事件名字
flag 标志,可以取OS_IPC_FLAG_FIFO和OS_IPC_FLAG_PRIO;当取值为OS_IPC_FLAG_FIFO时,等待的任务将按照先进先出的方式排队,先进入的任务先被唤醒;当取值为OS_IPC_FLAG_PRIO时,等待的任务将按照任务优先级排队,优先级高的任务先被唤醒
返回 说明
非OS_NULL 创建成功,返回事件句柄
OS_NULL 创建失败

os_event_destroy

该函数用于销毁事件,与os_event_create()配合使用,函数原型如下:

os_err_t os_event_destroy(os_event_t *event);
参数 说明
event 事件句柄
返回 说明
OS_EOK 销毁成功

os_event_send

该函数用于发送事件,函数原型如下:

os_err_t os_event_send(os_event_t *event, os_uint32_t set);
参数 说明
event 事件句柄
set 事件的集合
返回 说明
OS_EOK 发送成功
OS_ERROR 发送错误

os_event_recv

该函数用于接收事件,若暂时没有满足条件的事件,且设定了超时时间,则当前任务会阻塞,函数原型如下:

os_err_t os_event_recv(os_event_t   *event,
                       os_uint32_t  interested_set,
                       os_uint8_t   option,
                       os_tick_t    timeout,
                       os_uint32_t  *recved_set);
参数 说明
event 事件句柄
interested_set 接收任务感兴趣的事件集合
option 选项,可取值OS_EVENT_OPTION_AND和OS_EVENT_OPTION_OR;若取值OS_EVENT_OPTION_AND,任务在接收到所有的事件时才会被唤醒;若取值OS_EVENT_OPTION_OR,任务在接收到任一事件就会被唤醒;OS_EVENT_OPTION_AND或者OS_EVENT_OPTION_OR可与OS_EVENT_OPTION_CLEAR取“逻辑或”,表明接收到事件后会清除相应事件
timeout 接收事件所等待的超时时间;若为OS_IPC_WAITING_NO,则直接返回OS_ETIMEOUT;若为OS_IPC_WAITING_FOREVER,则会永久等待直到收到事件;若为其它值,则会等待超时时间或者接收到事件为止
recved_set 接收到的事件集合
返回 说明
OS_EOK 接收成功
OS_ETIMEOUT 超时未接收到事件
OS_ERROR 其它错误

os_event_control

该函数用于控制或者改变事件的属性,函数原型如下:

os_err_t os_event_control(os_event_t *event, os_ipc_cmd_t cmd, void *arg);
参数 说明
event 事件句柄
cmd 控制命令,目前支持OS_IPC_CMD_RESET,该命令会将事件清除,并唤醒所有等待此事件的任务。
arg 暂未使用
返回 说明
OS_EOK 控制或改变成功
OS_ERROR 控制或改变失败

使用示例

静态事件使用示例

本例用静态的方式初始化了一个事件对象,接收事件的任务采用“逻辑或”的方式接收多个事件,只要接收到一个事件,就会被唤醒

#include <oneos_config.h>
#include <os_dbg.h>
#include <os_errno.h>
#include <os_task.h>
#include <shell.h>
#include <os_event.h>

#define TEST_TAG        "TEST"
#define TASK_STACK_SIZE 1024
#define TASK_PRIORITY   15
#define TASK_TIMESLICE  10

#define EVENT_FLAG_0 (1 << 0)
#define EVENT_FLAG_1 (1 << 1)
#define EVENT_FLAG_2 (1 << 2)

static os_event_t event_static;

void task_entry(void *para)
{
    os_uint32_t recv_event;

    while (1)
    {        
        if (os_event_recv(&event_static, (EVENT_FLAG_0 | EVENT_FLAG_1 | EVENT_FLAG_2),
                          OS_EVENT_OPTION_OR | OS_EVENT_OPTION_CLEAR,
                          OS_IPC_WAITING_FOREVER, &recv_event) == OS_EOK)
        {
            LOG_W(TEST_TAG, "task: OR recv event:0x%x", recv_event);
        }
    }
}

void event_static_sample(void)
{
    os_task_t *task = OS_NULL;

    os_event_init(&event_static, "event_static", OS_IPC_FLAG_FIFO);

    task = os_task_create("task_event", 
                           task_entry, 
                           OS_NULL, 
                           TASK_STACK_SIZE, 
                           TASK_PRIORITY, 
                           TASK_TIMESLICE);
    if (task)
    {
        os_task_startup(task);
    }

    LOG_W(TEST_TAG, "event_static_sample: send event:0x%x", EVENT_FLAG_0);
    os_event_send(&event_static, EVENT_FLAG_0);
    os_task_sleep(400);

    LOG_W(TEST_TAG, "event_static_sample: send event:0x%x", EVENT_FLAG_1);
    os_event_send(&event_static, EVENT_FLAG_1);
    os_task_sleep(400);

    LOG_W(TEST_TAG, "event_static_sample: send event:0x%x", EVENT_FLAG_2);
    os_event_send(&event_static, EVENT_FLAG_2);
    os_task_sleep(400);

    LOG_W(TEST_TAG, "event_static_sample: send event:0x%x", EVENT_FLAG_0);
    os_event_send(&event_static, EVENT_FLAG_0);
    os_task_sleep(400);

    LOG_W(TEST_TAG, "event_static_sample: send event:0x%x", EVENT_FLAG_1);
    os_event_send(&event_static, EVENT_FLAG_1);
    os_task_sleep(400);

    LOG_W(TEST_TAG, "event_static_sample: send event:0x%x", EVENT_FLAG_2);
    os_event_send(&event_static, EVENT_FLAG_2);
    os_task_sleep(400);
}

SH_CMD_EXPORT(static_event, event_static_sample, "test staitc event");

运行结果如下:

sh />static_event
W/TEST: event_static_sample: send event:0x1
W/TEST: task: OR recv event:0x1
W/TEST: event_static_sample: send event:0x2
W/TEST: task: OR recv event:0x2
W/TEST: event_static_sample: send event:0x4
W/TEST: task: OR recv event:0x4
W/TEST: event_static_sample: send event:0x1
W/TEST: task: OR recv event:0x1
W/TEST: event_static_sample: send event:0x2
W/TEST: task: OR recv event:0x2
W/TEST: event_static_sample: send event:0x4
W/TEST: task: OR recv event:0x4

动态事件使用示例

本例用动态的方式创建并初始化了一个事件对象,接收事件的任务采用“逻辑与”的方式接收多个事件,在多个事件都接收到之后,才会被唤醒

#include <oneos_config.h>
#include <os_dbg.h>
#include <os_errno.h>
#include <os_task.h>
#include <shell.h>
#include <os_event.h>

#define TEST_TAG        "TEST"
#define TASK_STACK_SIZE 1024
#define TASK_PRIORITY   15
#define TASK_TIMESLICE  10

#define EVENT_FLAG_0 (1 << 0)
#define EVENT_FLAG_1 (1 << 1)
#define EVENT_FLAG_2 (1 << 2)

static os_event_t *event_dynamic = OS_NULL;

void task_entry(void *para)
{
    os_uint32_t recv_event;

    while (1)
    {        
        if (os_event_recv(event_dynamic, (EVENT_FLAG_0 | EVENT_FLAG_1 | EVENT_FLAG_2),
                          OS_EVENT_OPTION_AND | OS_EVENT_OPTION_CLEAR,
                          OS_IPC_WAITING_FOREVER, &recv_event) == OS_EOK)
        {
            LOG_W(TEST_TAG, "task: AND recv event:0x%x", recv_event);
        }
    }
}

void event_dynamic_sample(void)
{
    os_task_t *task = OS_NULL;

    event_dynamic = os_event_create("event_dynamic", OS_IPC_FLAG_FIFO);
    if (!event_dynamic)
    {
        LOG_E(TEST_TAG, "event_dynamic_sample: event create err");
        return;
    }

    task = os_task_create("task_event", 
                           task_entry, 
                           OS_NULL, 
                           TASK_STACK_SIZE, 
                           TASK_PRIORITY, 
                           TASK_TIMESLICE);
    if (task)
    {
        os_task_startup(task);
    }

    LOG_W(TEST_TAG, "event_dynamic_sample: send event:0x%x", EVENT_FLAG_0);
    os_event_send(event_dynamic, EVENT_FLAG_0);
    os_task_sleep(400);

    LOG_W(TEST_TAG, "event_dynamic_sample: send event:0x%x", EVENT_FLAG_1);
    os_event_send(event_dynamic, EVENT_FLAG_1);
    os_task_sleep(400);

    LOG_W(TEST_TAG, "event_dynamic_sample: send event:0x%x", EVENT_FLAG_2);
    os_event_send(event_dynamic, EVENT_FLAG_2);
    os_task_sleep(400);

    LOG_W(TEST_TAG, "event_dynamic_sample: send event:0x%x", EVENT_FLAG_0);
    os_event_send(event_dynamic, EVENT_FLAG_0);
    os_task_sleep(400);

    LOG_W(TEST_TAG, "event_dynamic_sample: send event:0x%x", EVENT_FLAG_1);
    os_event_send(event_dynamic, EVENT_FLAG_1);
    os_task_sleep(400);

    LOG_W(TEST_TAG, "event_dynamic_sample: send event:0x%x", EVENT_FLAG_2);
    os_event_send(event_dynamic, EVENT_FLAG_2);
    os_task_sleep(400);
}

SH_CMD_EXPORT(dynamic_event, event_dynamic_sample, "test dynamic event");

运行结果如下:

sh />dynamic_event
W/TEST: event_dynamic_sample: send event:0x1
W/TEST: event_dynamic_sample: send event:0x2
W/TEST: event_dynamic_sample: send event:0x4
W/TEST: task: AND recv event:0x7
W/TEST: event_dynamic_sample: send event:0x1
W/TEST: event_dynamic_sample: send event:0x2
W/TEST: event_dynamic_sample: send event:0x4
W/TEST: task: AND recv event:0x7

results matching ""

    No results matching ""

    返回顶部