Q群:
电话:
邮箱:
地址:
事件是任务间同步的一种机制。多个事件可以通过一个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 | 事件的集合 |
接口 | 说明 |
---|---|
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_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_init()配合使用,函数原型如下:
os_err_t os_event_deinit(os_event_t *event);
参数 | 说明 |
---|---|
event | 事件句柄 |
返回 | 说明 |
OS_EOK | 反初始化成功 |
该函数以动态方式创建并初始化事件,事件对象的内存空间采用动态申请的方式获得,函数原型如下:
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_create()配合使用,函数原型如下:
os_err_t os_event_destroy(os_event_t *event);
参数 | 说明 |
---|---|
event | 事件句柄 |
返回 | 说明 |
OS_EOK | 销毁成功 |
该函数用于发送事件,函数原型如下:
os_err_t os_event_send(os_event_t *event, os_uint32_t set);
参数 | 说明 |
---|---|
event | 事件句柄 |
set | 事件的集合 |
返回 | 说明 |
OS_EOK | 发送成功 |
OS_ERROR | 发送错误 |
该函数用于接收事件,若暂时没有满足条件的事件,且设定了超时时间,则当前任务会阻塞,函数原型如下:
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_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