Expand description
§XWOS RUST:事件标志
事件标志使用位图来管理一组事件,位图中的每个位代表一个事件, 当一个或多个事件状态发生变化时,事件对应的位也会发生变化,并唤醒正在等待的线程。 线程唤醒后,就可从事件位图中获取事件的状态。
- 线程可以等待位图中的事件位被置 1 ,也可以等待事件位被清 0 。
- 线程可以等待位图中的事件位同时被置 1 (事件与事件之间是逻辑 与 的关系),也可以等待其中任意一个位被置 1 (事件与事件之间是逻辑 或 的关系)。
- 线程可以等待位图中的事件位同时被清 0 (事件与事件之间是逻辑 与 的关系),也可以等待其中任意一个位被清 0 (事件与事件之间是逻辑 或 的关系)。
- 线程可以选择是否 消费 事件。 消费 事件是指,当事件到来,线程被唤醒时,可以选择是否 清除 事件。
- 线程可以等待事件标志位发生 翻转 , 翻转 是指事件标志位由 1 变为 0 ,或由 0 变为 1 。
§创建
XWOS RUST的事件标志可使用 Flg::new()
创建。
- 可以创建具有静态生命周期
static
约束的全局变量:
use xwrust::xwos::sync::flg::*;
static GLOBAL_FLG: Flg<8> = Flg::new();
- 也可以使用
alloc::sync::Arc
在heap中创建:
extern crate alloc;
use alloc::sync::Arc;
use xwrust::xwos::sync::flg::*;
pub fn xwrust_example_flg() {
let flg = Arc::new(Flg::<8>::new());
}
§初始化
无论以何种方式创建的事件标志,都必须在使用前调用 Flg::init()
进行初始化:
pub fn xwrust_example_flg() {
GLOBAL_FLG.init();
flg.init();
}
§产生事件
Flg::s1m()
同时设置多个事件标志位Flg::s1i()
设置单个事件标志位Flg::c0m()
同时清除多个事件标志位Flg::c0i()
清除单个事件标志位Flg::x1m()
同时翻转多个事件标志位Flg::x1i()
翻转单个事件标志位
产生事件的方法,除了会修改事件标志位图的状态,还会通过 广播 唤醒所有正在等待的线程。 然后,线程通过比对位图状态,确定事件是否已经满足触发条件。 若满足触发条件,就退出等待;若未满足触发条件,重新进入阻塞等待状态。
§等待事件的方法
Flg::wait()
可用于等待事件。Flg::wait_to()
可用于限时等待事件。Flg::trywait()
可用于检测事件。
§事件的触发条件
等待事件时,可通过参数 tg
指明事件的触发条件。事件的触发条件分为两类。
§电平触发
电平触发 源于数字电路,是一种类比概念,是指事件位图的特定状态( 1 或 0 )所产生的触发事件,包括:
Trigger::SetAll
所有事件位被置 1 触发Trigger::SetAny
任意事件位被置 1 触发Trigger::ClearAll
所有事件位被清 0 触发Trigger::ClearAny
任意事件位被清 0 触发
电平触发 时,可在线程读取事件位图后,清除 事件触发条件。
§边沿触发
边沿触发 源于数字电路,是一种类比概念,是指事件状态发生改变( 1 变 0 或 0 变 1 )时产生的唤醒信号,包括:
Trigger::SetAll
所有事件位发生翻转触发Trigger::SetAny
任意事件位发生翻转触发
边沿触发 时,事件的触发条件不需要清除。 边沿触发 时,必须要有一个初始状态,就像数字电路一样:
- 当位的初始值为 0 (低电平),然后跳变到 1 (高电平)的瞬间被称为上升沿。此时触发的事件被称为上升沿触发。
- 当位的初始值为 1 (高电平),然后跳变到 0 (低电平)的瞬间被称为下降沿。此时触发的事件被称为下降沿触发。
§清除事件
- 当采用 电平触发 时,需要在读取事件位图后 清除 事件标志位,否则事件会一直处于触发状态。
可以在调用等待事件的方法时,指定参数
action
为Action::Consumption
。 清除 的含义是:- 当线程等待的是位图中的事件位被置 1 , 清除 是指将这些位清 0 ;
- 当线程等待的是位图中的事件位被清 0 , 清除 是指将这些位置 1 ;
- 当采用 边沿触发 时,不需要 清除 事件的触发条件。
§读取事件
用户可以通过方法 Flg::read()
直接读取事件的位图状态。此函数立即返回,不会阻塞。
§获取事件标志中事件槽的数量
可以通过方法 Flg::get_num()
获取事件标志中事件槽的数量。
§绑定到信号选择器
事件标志是 同步对象 ,可以通过方法 Flg::bind()
将事件标志绑定到信号选择器 Sel<M>
上,通过 Sel<M>
,单一线程可以同时等待多个不同的 同步对象 。
事件标志采用 非独占 的方式进行绑定。
§示例
Structs§
- 事件标志对象结构体
- 事件标志的选择子
Enums§
- 触发后的动作
- 事件标志的错误码
- 触发条件
Constants§
- XWOS事件标志对象占用的内存大小