Skip to main content

task_define/
lib.rs

1//! task 任务定义
2#![no_std]
3
4use core::{
5    mem::offset_of,
6    sync::atomic::{AtomicU32, AtomicUsize, Ordering},
7};
8
9/// task base 定义
10///
11/// 汇编必须有一些需要访问的变量,因此该结构用于导出必要的变
12#[derive(Default)]
13#[repr(C)]
14pub struct TaskBase {
15    // 任务内核栈起始地址
16    stack: AtomicUsize,
17    // 任务线程地址上限限制
18    thread_addr_limit: AtomicUsize,
19    // 线程 flags
20    thread_flags: AtomicU32,
21    // 线程抢占计数
22    thread_preempt: AtomicU32,
23}
24
25impl TaskBase {
26    /// 构造 task base
27    pub const fn new() -> Self {
28        Self {
29            stack: AtomicUsize::new(0),
30            thread_addr_limit: AtomicUsize::new(0),
31            thread_flags: AtomicU32::new(0),
32            thread_preempt: AtomicU32::new(0),
33        }
34    }
35
36    /// 设置任务栈基址
37    pub fn set_stack(&self, stack_base: usize) {
38        self.stack.store(stack_base, Ordering::Relaxed);
39    }
40
41    /// 任务栈基地址
42    #[inline(always)]
43    pub fn stack(&self) -> usize {
44        self.stack.load(Ordering::Relaxed)
45    }
46
47    /// 设置任务抢占计数
48    #[inline(always)]
49    pub fn set_preempt(&self, val: u32) {
50        self.thread_preempt.store(val, Ordering::Relaxed);
51    }
52
53    /// 获取任务抢占计数
54    #[inline(always)]
55    pub fn preempt(&self) -> u32 {
56        self.thread_preempt.load(Ordering::Relaxed)
57    }
58
59    /// 增加任务抢占计数
60    #[inline(always)]
61    pub fn preempt_add(&self, val: u32) {
62        self.thread_preempt.fetch_add(val, Ordering::Relaxed);
63    }
64
65    /// 减少任务抢占计数
66    #[inline(always)]
67    pub fn preempt_sub(&self, val: u32) {
68        self.thread_preempt.fetch_sub(val, Ordering::Relaxed);
69    }
70
71    /// 设置任务flags
72    #[inline(always)]
73    pub fn set_flags(&self, flags: u32) {
74        self.thread_flags.store(flags, Ordering::Relaxed);
75    }
76
77    /// 设置任务falgs bit
78    #[inline(always)]
79    pub fn set_flags_bit(&self, bit: u32) {
80        self.thread_flags.fetch_or(1 << bit, Ordering::Relaxed);
81    }
82
83    /// 获取任务flags
84    #[inline(always)]
85    pub fn flags(&self) -> u32 {
86        self.thread_flags.load(Ordering::Relaxed)
87    }
88
89    /// 测试任务flags bit是否设置
90    #[inline(always)]
91    pub fn test_flags_bit(&self, bit: u32) -> bool {
92        self.thread_flags.load(Ordering::Relaxed) & (1 << bit) != 0
93    }
94}
95
96/// `TSK_STACK`
97pub const TSK_STACK: usize = offset_of!(TaskBase, stack);
98/// `TSK_TI_ADDR_LIMIT`
99pub const TSK_TI_ADDR_LIMIT: usize = offset_of!(TaskBase, thread_addr_limit);
100/// `TSK_TI_FLAGS`
101pub const TSK_TI_FLAGS: usize = offset_of!(TaskBase, thread_flags);
102/// `TSK_TI_PREEMPT`
103pub const TSK_TI_PREEMPT: usize = offset_of!(TaskBase, thread_preempt);
104
105#[cfg(test)]
106mod test {
107    use super::*;
108
109    #[test]
110    fn test() {
111        assert_eq!(TSK_STACK, 0);
112        assert_eq!(TSK_TI_ADDR_LIMIT, 8);
113        assert_eq!(TSK_TI_FLAGS, 16);
114        assert_eq!(TSK_TI_PREEMPT, 20);
115    }
116}