事件集的工作机制
事件集也是线程间同步的机制之一,一个事件集可以包含多个事件,利用事件集可以完成一对多,多对多的线程间同步。
1)事件只与线程相关,事件间相互独立:每个线程可拥有 32 个事件标志,采用一个 32 bit 无符号整型数进行记录,每一个 bit 代表一个事件;
2)事件仅用于同步,不提供数据传输功能;
第一步:首先通过stm32cubeMX移植了threadx(参考第一篇文章)。
第二步:创建事件集。在
int tx_application_define(VOID *first_unused_memory)里面创建事件集。
/* 初始化事件对象 */
status = tx_event_flags_create(&EventGroup, "event");
if (status != TX_SUCCESS)
{
debug("init event failed.\r\n");
return -1;
}
第二步:创建事件任务。
#define APP_CFG_TASK_event_PRIO 7u
#define APP_CFG_TASK_event_STK_SIZE 4096u
static TX_THREAD AppTaskeventTCB;
static uint64_t AppTaskeventStk[APP_CFG_TASK_event_STK_SIZE/8];
static void AppTaskevent(ULONG thread_input);
#define EVENT_FLAG3 (1 << 3)
#define EVENT_FLAG5 (1 << 5)
//创建事件标志组
TX_EVENT_FLAGS_GROUP EventGroup;
tx_thread_create(&AppTaskUARTTCB, /* 任务控制块地�?? */
"App Task UART", /* 任务�?? */
AppTaskUART, /* 启动任务函数地址 */
0, /* 传�?�给任务的参�?? */
&AppTaskUARTStk[0], /* 堆栈基地�?? */
APP_CFG_TASK_UART_STK_SIZE, /* 堆栈空间大小 */
APP_CFG_TASK_UART_PRIO, /* 任务优先�??*/
APP_CFG_TASK_UART_PRIO, /* 任务抢占�??�?? */
TX_NO_TIME_SLICE, /* 不开启时间片 */
TX_AUTO_START); /* 创建后立即启�?? */
tx_thread_create(&AppTaskeventTCB, /* 任务控制块地�?? */
"App Task event", /* 任务�?? */
AppTaskevent, /* 启动任务函数地址 */
0, /* 传�?�给任务的参�?? */
&AppTaskeventStk[0], /* 堆栈基地�?? */
APP_CFG_TASK_event_STK_SIZE, /* 堆栈空间大小 */
APP_CFG_TASK_event_PRIO, /* 任务优先�??*/
APP_CFG_TASK_event_PRIO, /* 任务抢占�??�?? */
TX_NO_TIME_SLICE, /* 不开启时间片 */
TX_AUTO_START); /* 创建后立即启�?? */
第三步:编写任务函数。
static void AppTaskUART(ULONG thread_input)
{
uint32_t e;
/* 第一次接收事件,事件 3 或事件 5 任意一个可以触发线程 1,接收完后清除事件标志 */
ULONG actual_events;
if (tx_event_flags_get(&EventGroup, (EVENT_FLAG3 | EVENT_FLAG5),
TX_OR | TX_OR_CLEAR,
&actual_events,
TX_WAIT_FOREVER))
{
debug("thread1: OR recv event 0x%lx\r\n", actual_events);
}
debug("thread1: delay 1s to prepare the second event\r\n");
tx_thread_sleep(1000);
/* 第二次接收事件,事件 3 和事件 5 均发生时才可以触发线程 1,接收完后清除事件标志 */
if (tx_event_flags_get(&EventGroup, (EVENT_FLAG3 | EVENT_FLAG5),
TX_AND | TX_AND_CLEAR,
&actual_events,
TX_WAIT_FOREVER))
{
debug("thread1: AND recv event 0x%lx\r\n", actual_events);
}
debug("thread1 leave.\r\n");
}
static void AppTaskevent(ULONG thread_input)
{
debug("thread2: send event3\r\n");
tx_event_flags_set(&EventGroup, EVENT_FLAG3,TX_OR);
tx_thread_sleep(200);
debug("thread2: send event5\r\n");
tx_event_flags_set(&EventGroup, EVENT_FLAG5,TX_AND);
tx_thread_sleep(200);
debug("thread2: send event3\r\n");
tx_event_flags_set(&EventGroup, EVENT_FLAG3,TX_AND);
debug("thread2 leave.\r\n");
}
第四步:编译下载。