事件
概述
事件提供了一种任务间实现同步和信息传递的机制。一般来说,一个事件中包含了一个旗标,这个旗标的每一位表示一个“事件”。
一个任务可以等待一个或者多个“事件”的发生,其他任务在一定的业务条件下可以通过写入特定“事件”唤醒等待此“事件”的任务,实现一种类似信号的编程范式。
API讲解
编程实例
1、在tos_config.h中,配置事件组件开关TOS_CFG_EVENT_EN:
#define TOS_CFG_EVENT_EN 1u
2、编写main.c示例代码:
#include "tos.h" #include "mcu_init.h" #define STK_SIZE_TASK_LISTENER 512 #define STK_SIZE_TASK_TRIGGER 512 k_stack_t stack_task_listener1[STK_SIZE_TASK_LISTENER]; k_stack_t stack_task_listener2[STK_SIZE_TASK_LISTENER]; k_stack_t stack_task_trigger[STK_SIZE_TASK_TRIGGER]; k_task_t task_listener1; k_task_t task_listener2; k_task_t task_trigger; extern void entry_task_listener1(void *arg); extern void entry_task_listener2(void *arg); extern void entry_task_trigger(void *arg); const k_event_flag_t event_eeny = (k_event_flag_t)(1 << 0); const k_event_flag_t event_meeny = (k_event_flag_t)(1 << 1); const k_event_flag_t event_miny = (k_event_flag_t)(1 << 2); const k_event_flag_t event_moe = (k_event_flag_t)(1 << 3); k_event_t event; void entry_task_listener1(void *arg) { k_event_flag_t flag_match; k_err_t err; while (K_TRUE) { // 此任务监听四个事件,因为使用了TOS_OPT_EVENT_PEND_ALL选项,因此必须是四个事件同时到达此任务才会被唤醒 err = tos_event_pend(&event, event_eeny | event_meeny | event_miny | event_moe, &flag_match, TOS_TIME_FOREVER, TOS_OPT_EVENT_PEND_ALL | TOS_OPT_EVENT_PEND_CLR); if (err == K_ERR_NONE) { printf("entry_task_listener1:\n"); printf("eeny, meeny, miny, moe, they all come\n"); } } } void entry_task_listener2(void *arg) { k_event_flag_t flag_match; k_err_t err; while (K_TRUE) { // 此任务监听四个事件,因为使用了TOS_OPT_EVENT_PEND_ANY选项,因此四个事件任意一个到达(包括四个事件同时到达)任务就会被唤醒 err = tos_event_pend(&event, event_eeny | event_meeny | event_miny | event_moe, &flag_match, TOS_TIME_FOREVER, TOS_OPT_EVENT_PEND_ANY | TOS_OPT_EVENT_PEND_CLR); if (err == K_ERR_NONE) { printf("entry_task_listener2:\n"); // 有事件到达,判断具体是哪个事件 if (flag_match == event_eeny) { printf("eeny comes\n"); } if (flag_match == event_meeny) { printf("meeny comes\n"); } if (flag_match == event_miny) { printf("miny comes\n"); } if (flag_match == event_moe) { printf("moe comes\n"); } if (flag_match == (event_eeny | event_meeny | event_miny | event_moe)) { printf("all come\n"); } } } } void entry_task_trigger(void *arg) { int i = 1; while (K_TRUE) { if (i == 2) { printf("entry_task_trigger:\n"); printf("eeny will come\n"); // 发送eeny事件,task_listener2会被唤醒 tos_event_post(&event, event_eeny); } if (i == 3) { printf("entry_task_trigger:\n"); printf("meeny will come\n"); // 发送eeny事件,task_listener2会被唤醒 tos_event_post(&event, event_meeny); } if (i == 4) { printf("entry_task_trigger:\n"); printf("miny will come\n"); // 发送eeny事件,task_listener2会被唤醒 tos_event_post(&event, event_miny); } if (i == 5) { printf("entry_task_trigger:\n"); printf("moe will come\n"); // 发送eeny事件,task_listener2会被唤醒 tos_event_post(&event, event_moe); } if (i == 6) { printf("entry_task_trigger:\n"); printf("all will come\n"); // 同时发送四个事件,因为task_listener1的优先级高于task_listener2,因此这里task_listener1会被唤醒 tos_event_post(&event, event_eeny | event_meeny | event_miny | event_moe); } tos_task_delay(1000); ++i; } } int main(void) { board_init(); tos_knl_init(); tos_event_create(&event, (k_event_flag_t)0u); // 这里task_listener1的优先级比task_listener2高,因此在task_trigger发送所有事件时,task_listener1会被唤醒 // 读者可以尝试将task_listener1优先级修改为5(比task_listener2低),此设置下,在task_trigger发送所有事件时,task_listener2将会被唤醒。 (void)tos_task_create(&task_listener1, "listener1", entry_task_listener1, NULL, 3, stack_task_listener1, STK_SIZE_TASK_LISTENER, 0); (void)tos_task_create(&task_listener2, "listener2", entry_task_listener2, NULL, 4, stack_task_listener2, STK_SIZE_TASK_LISTENER, 0); (void)tos_task_create(&task_trigger, "trigger", entry_task_trigger, NULL, 4, stack_task_trigger, STK_SIZE_TASK_TRIGGER, 0); tos_knl_start(); }
运行效果
entry_task_trigger: eeny will come entry_task_listener2: eeny comes entry_task_trigger: meeny will come entry_task_listener2: meeny comes entry_task_trigger: miny will come entry_task_listener2: miny comes entry_task_trigger: moe will come entry_task_listener2: moe comes entry_task_trigger: all will come entry_task_listener1: eeny, meeny, miny, moe, they all come
[实例代码](./code/2.3.3 event/main.c)