一、应用简介

在RTOS的应用开发中,事件标志主要是用来进行任务之间的事件通知。例如有A和B两个任务,A任务负责接收消息,B任务负责对消息响应。当A任务接收到消息后设置响应标志,B任务监测到响应标志被设置就执行消息响应。事件标志没被设置的时候任务是不会占用CPU的,不用像裸机程序那样不断轮询事件的发生,使得CPU的利用率更高,这也是使用RTOS的优势之一。

二、API说明

下面列出使用事件标志组时常用的几个函数

1、创建事件标志组

描述:

该函数会创建一个包含32个事件标志的事件组(其实就是一个32bit的变量),组中的32个事件标志都被初始化为零,每个事件标志由一个Bit表示(bit位置1则表明该位代表的事件标志被设置)。

参数

group_ptr :指向事件标志组控件块的指针

name_ptr :指向事件标志组名称的指针

返回值

TX_SUCCESS (0x00) :成功创建事件组

TX_GROUP_ERROR (0x06) :无效的事件组指针,指针为NULL或事件组已创建

TX_CALLER_ERROR (0x13):该服务的调用者无效

UINT tx_event_flags_create(

TX_EVENT_FLAGS_GROUP *group_ptr,

CHAR *name_ptr);

2、删除事件标志组

描述

此服务会删除指定的事件标志组,所有等待该组事件的挂起线程将被恢复,并给出TX_DELETED返回状态。

在删除事件标志组之前,应用程序必须确保完成(或禁用)此事件标志组的通知回调。此外,应用程序必须禁止使用已删除的事件标志组。

参数

group_ptr :指向先前创建的事件标志组的指针

返回值

TX_SUCCESS (0x00):成功删除事件标志组

TX_GROUP_ERROR (0x06):无效的事件标志组指针

TX_CALLER_ERROR (0x13):该服务的调用者无效

UINT tx_event_flags_delete(TX_EVENT_FLAGS_GROUP *group_ptr);

3、获取事件标志

描述

此服务从指定的事件标志组检索事件标志。每个事件标志组包含32个事件标志。每个标志由一个位表示。此服务可以检索由输入参数选择的各种事件标志组合。

参数

group_ptr:指向先前创建的事件标志组的指针

requested_flags:表示请求的事件标志

get_option:请求事件标志的选项(TX_AND (0x02):指定的事件标志必须全部有效;TX_OR (0x00):指定的事件部分部分有效即可;TX_AND_CLEAR (0x03):指定的事件标志必须都被设置且清除相应的事件标志;TX_OR_CLEAR (0x01):指定的事件标志部分被设置就满足条件且清除相应的事件标志)

actual_flags_ptr:指向放置检索到的事件标志的指针。请注意,获得的实际标志可能包含未被请求的标志。

wait_option:所选事件标志未被设置时服务的行为(TX_NO_WAIT (0x00000000) :不等待立即返回;TX_WAIT_FOREVER(0xFFFFFFFF):一直挂起等待直到事件标志被设置;(0x00000001 到 0xFFFFFFFE):等待的心跳节拍数,例如设置心跳是1KHZ那单位就是ms)

返回值

TX_SUCCESS(0x00)成功获得事件标志。

TX_DELETED(0x01)线程挂起时,事件标志组已删除。

TX_NO_EVENTS(0x07)服务无法在指定的等待时间内获取指定的事件。

TX_WAIT_ABORTED(0x1A)被另一个线程、计时器或中断服务打断。

TX_GROUP_ERROR(0x06)无效的事件标志组指针。

TX_PTR_ERROR(0x03)实际事件标志的无效指针。

TX_WAIT_ERROR(0x04)在非线程调用中指定了TX_NO_WAIT以外的等待选项。

TX_OPTION_ERROR(0x08)指定了无效的获取选项。

UINT tx_event_flags_get(

TX_EVENT_FLAGS_GROUP *group_ptr,

ULONG requested_flags,

UINT get_option,

ULONG *actual_flags_ptr,

ULONG wait_option);

4、设置事件标志

描述

此服务根据指定的选项设置或清除事件标志组中的事件标志。 所有请求被设置事件标志的线程将从挂起状态恢复运行态。

参数

group_ptr:指向先前创建的事件标志组控制块的指针

flags_to_set:根据选择的设置选项指定要设置或清除的事件标志

set_option:将指定的事件标志与该组的当前事件标志进行“与”或“或”运算(TX_AND(0x02)、TX_OR(0x00));选择TX_AND将指定的事件标志与该组中的当前事件标志进行“与”运算。 此选项通常用于清除组中的事件标志。选择TX_OR,则将指定的事件标志与组中的当前事件进行“或”运算。

返回值

TX_SUCCESS(0x00)事件标志成功设置。

TX_GROUP_ERROR(0x06)指向事件标志组指针无效。

TX_OPTION_ERROR(0x08)指定了无效的设置选项。

UINT tx_event_flags_set(

TX_EVENT_FLAGS_GROUP *group_ptr,

ULONG flags_to_set,

UINT set_option);

三、实例说明

该实例创建一个事件标志组和三个任务。标志组中包含了两个事件标志,任务1检测按键1的运行,任务2检测按键2的运行,任务3执行对应的按键响应,任务之间的通知采用事件标志的方式。

#include "main.h"

#include "usart.h"

#include "gpio.h"

#include "tx_api.h"

#define DEMO_STACK_SIZE (2 * 1024)

#define DEMO_BYTE_POOL_SIZE (32 * 1024)

/*事件标志*/

#define TX_EVENT_FLAG_KEY1(1 << 0)

#define TX_EVENT_FLAG_KEY2(1 << 1)

TX_THREAD thread_0;

TX_THREAD thread_1;

TX_THREAD thread_2;

TX_BYTE_POOL byte_pool_0;

UCHAR memory_area[DEMO_BYTE_POOL_SIZE];

/*事件标志组*/

TX_EVENT_FLAGS_GROUP tx_event_flags;

void thread_0_entry(ULONG thread_input);

void thread_1_entry(ULONG thread_input);

void thread_2_entry(ULONG thread_input);

int main(void)

{

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();

MX_USART1_UART_Init();

tx_kernel_enter();

while (1)

{

}

}

void tx_application_define(void *first_unused_memory)

{

CHAR *pointer = TX_NULL;

/* Create a byte memory pool from which to allocate the thread stacks. */

tx_byte_pool_create(&byte_pool_0, "byte pool 0", memory_area, DEMO_BYTE_POOL_SIZE);

/* 创建事件标志组 */

tx_event_flags_create(&tx_event_flags, "my_event_group_name");

/* Allocate the stack for thread 0. */

tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

/* Create the main thread. */

tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,

pointer, DEMO_STACK_SIZE,

1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);

/* Allocate the stack for thread 1. */

tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

/* Create threads 1 */

tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0,

pointer, DEMO_STACK_SIZE,

2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);

/* Allocate the stack for thread 2. */

tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

/* Create threads 1 */

tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0,

pointer, DEMO_STACK_SIZE,

3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);

}

void thread_0_entry(ULONG thread_input)

{

uint8_t key_cnt = 0;

while(1)

{

if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) != GPIO_PIN_RESET)

{

key_cnt++;

}

else

{

if (key_cnt > 2)

{

/* 按键1触发,设置事件标志 */

tx_event_flags_set(&tx_event_flags, TX_EVENT_FLAG_KEY1, TX_OR);

}

key_cnt = 0;

}

tx_thread_sleep(20);

}

}

void thread_1_entry(ULONG thread_input)

{

uint8_t key_cnt = 0;

while(1)

{

if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) != GPIO_PIN_RESET)

{

key_cnt++;

}

else

{

if (key_cnt > 2)

{

/* 按键2触发,设置事件标志 */

tx_event_flags_set(&tx_event_flags, TX_EVENT_FLAG_KEY2, TX_OR);

}

key_cnt = 0;

}

tx_thread_sleep(20);

}

}

void thread_2_entry(ULONG thread_input)

{

UINT status;

ULONG actual_events;

while(1)

{

/* 等待事件标志:任意按键触发都有效 */

status = tx_event_flags_get(&tx_event_flags, TX_EVENT_FLAG_KEY1 | TX_EVENT_FLAG_KEY2, TX_OR_CLEAR, &actual_events, TX_WAIT_FOREVER);

if (TX_SUCCESS == status)

{

if (TX_EVENT_FLAG_KEY1 == (actual_events & TX_EVENT_FLAG_KEY1))

{

HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);

printf("key1 is pressed, actual_events:0x%x\r\n", (int)actual_events);

}

if (TX_EVENT_FLAG_KEY2 == (actual_events & TX_EVENT_FLAG_KEY2))

{

HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);

printf("key2 is pressed, actual_events:0x%x\r\n", (int)actual_events);

}

}

}

}

效果如下:

threadx 信号量 应用_ThreadX——IPC应用之事件标志相关推荐

  1. FreeRTOS基于任务通知的信号量 事件标志组 消息邮箱

    FreeRTOS创建的任务都有一个任务控制块. 任务控制块本质上是一个结构体变量,用于记录任务的相关的消息. 结构体变量中有一个专门用于任务通知的32位变量ulNotifiedValue. ulNot ...

  2. 【IoT】STM32 系统级开发之 ucosIII 或 freeRTOS 事件标志组详解

    1.轻型操作系统同步的方案详解 1)信号量 假设有两个任务 Task1 和 Task2,第一个任务进行按键的扫描,第二个任务进行LED灯的点亮 需求: 扫描到按键按下后点亮 LED 灯,也就是说第二个 ...

  3. FreeRTOS 任务计数信号量,任务二值信号量,任务事件标志组,任务消息邮箱

    以下基础内容转载自安富莱电子: http://forum.armfly.com/forum.php 本章节为大家讲解 FreeRTOS 计数信号量的另一种实现方式----基于任务通知(Task Not ...

  4. 互斥量、临界区、信号量、事件标志组和消息邮箱

    为了好的理解互斥量.临界区.信号量.事件标志组和消息邮箱,下面一些知识对初学者来说很重要: 为了实现各任务之间的合作和无冲突的运行,在有关联的任务之间必须建立一些制约关系.这些制约关系主要有两种:直接 ...

  5. 互斥量、临界区、信号量、事件标志组和消息邮箱(转)

    互斥量.临界区.信号量.事件标志组和消息邮箱          为了好的理解互斥量.临界区.信号量.事件标志组和消息邮箱,下面一些知识对初学者来说很重要: 为了实现各任务之间的合作和无冲突的运行,在有 ...

  6. FreeRTOS记录(七、FreeRTOS信号量、事件标志组、邮箱和消息队列、任务通知的关系)

    我们在前面单独介绍过FreeRTOS的任务通知和消息队列, 但是在FreeRTOS中任务间的通讯还有信号量,邮箱,事件组标志等可以使用 这篇文章就这些成员与消息队列和任务通知的关系进行说明分析 ..增 ...

  7. 事件标志组/信号量区别_sdchguyi_新浪博客

    ucos看了也有一周多了,索性源码都能开得懂,并且能去理解.昨天一开始看事件标志组的时候确实不知道怎么回事,后来百度一下,明白了事件标志组的作用以后,再去看书上的讲解和原码就清晰多了,很容易就明白了他 ...

  8. 事件标志组解决任务间资源共享问题

    文章目录 1 事件标志组解决任务间资源共享问题 1.1 工作原理 1.2 分析 1 事件标志组解决任务间资源共享问题 1.1 工作原理 tinyOS的事件标志组实现: 代码: /*** @brief ...

  9. 事件标志组的等待与通知

    文章目录 1 事件标志组的等待与通知 1.1 设计需求 1.2 设计实现 1 事件标志组的等待与通知 1.1 设计需求 当事件标志位发生时: 没有任务等待,设置相应的事件标志. 有任务等待时,唤醒等待 ...

最新文章

  1. 文本去重之MinHash算法——就是多个hash函数对items计算特征值,然后取最小的计算相似度...
  2. Designing GANs:又一个GAN生产车间
  3. wxWidgets:wxRearrangeDialog类用法
  4. 社区 正式发布了跨平台的 CoreWCF 0.2.0
  5. Spring 使用事务
  6. 基于Redis的用户发微博
  7. 如果/否则列表理解?
  8. php字符是汉字还是字符,php判断字符串中是否包含中文汉字和获得字符串中的汉字...
  9. Elasticsearch2.4.X 搜索引擎框架 安装配置
  10. 正则表达式-2-正则表达式实战1
  11. 电磁攻击方法与能量攻击方法的对比
  12. css制作自动旋转的钟表
  13. Protocol handler initialization failed
  14. 笔记 | 笨方法学Python
  15. 【转载】html转义字符
  16. 计算机教室灭火器配置标准,计算机教室与多媒体教室安装场地基本要求.doc
  17. 【深入理解Hadoop原理】Hadoop 参数配置 详解
  18. uniapp中拨打电话
  19. C/C++ BeaEngine 反汇编引擎
  20. CSS深度学习 - 文本方向 direction 和 dir

热门文章

  1. 94. 二叉树的中序遍历(迭代)
  2. uva-10400-搜索
  3. AI犯错谁之过?切勿盲目相信之
  4. 动力节点Java培训告诉你Java线程的多功能用法
  5. Document对象内容集合
  6. (转)失败和拒绝,也是一种肯定
  7. javascript图片浏览器的核心——图片预加载
  8. .NET基础示例系列之六:委托及事件
  9. PCIe知识学习 (转载)
  10. 转换图像分辨率c++代码_哈工大等提出轻量级盲超分辨模型LESRCNN,代码已开源...