13
13
14
14
use core:: ffi:: c_uint;
15
15
use core:: fmt;
16
+ use core:: mem;
16
17
17
18
use crate :: {
18
- error:: { Result , to_result_void } ,
19
- object:: { StaticKernelObject , Wrapped } ,
19
+ error:: { to_result_void , Result } ,
20
+ object:: { Fixed , StaticKernelObject , Wrapped } ,
20
21
raw:: {
21
- k_sem,
22
- k_sem_init,
23
- k_sem_take,
24
- k_sem_give,
25
- k_sem_reset,
26
- k_sem_count_get,
22
+ k_sem, k_sem_count_get, k_sem_give, k_sem_init, k_sem_reset, k_sem_take
27
23
} ,
28
24
time:: Timeout ,
29
25
} ;
@@ -33,7 +29,7 @@ pub use crate::raw::K_SEM_MAX_LIMIT;
33
29
/// A zephyr `k_sem` usable from safe Rust code.
34
30
pub struct Semaphore {
35
31
/// The raw Zephyr `k_sem`.
36
- item : * mut k_sem ,
32
+ item : Fixed < k_sem > ,
37
33
}
38
34
39
35
/// By nature, Semaphores are both Sync and Send. Safety is handled by the underlying Zephyr
@@ -42,6 +38,20 @@ unsafe impl Sync for Semaphore {}
42
38
unsafe impl Send for Semaphore { }
43
39
44
40
impl Semaphore {
41
+ /// Create a new semaphore.
42
+ ///
43
+ /// Create a new dynamically allocated Semaphore. This semaphore can only be used from system
44
+ /// threads. The arguments are as described in [the
45
+ /// docs](https://docs.zephyrproject.org/latest/kernel/services/synchronization/semaphores.html).
46
+ #[ cfg( CONFIG_RUST_ALLOC ) ]
47
+ pub fn new ( initial_count : c_uint , limit : c_uint ) -> Result < Semaphore > {
48
+ let item: Fixed < k_sem > = Fixed :: new ( unsafe { mem:: zeroed ( ) } ) ;
49
+ unsafe {
50
+ to_result_void ( k_sem_init ( item. get ( ) , initial_count, limit) ) ?;
51
+ }
52
+ Ok ( Semaphore { item } )
53
+ }
54
+
45
55
/// Take a semaphore.
46
56
///
47
57
/// Can be called from ISR if called with [`NoWait`].
@@ -52,7 +62,7 @@ impl Semaphore {
52
62
{
53
63
let timeout: Timeout = timeout. into ( ) ;
54
64
let ret = unsafe {
55
- k_sem_take ( self . item , timeout. 0 )
65
+ k_sem_take ( self . item . get ( ) , timeout. 0 )
56
66
} ;
57
67
to_result_void ( ret)
58
68
}
@@ -63,7 +73,7 @@ impl Semaphore {
63
73
/// permitted count.
64
74
pub fn give ( & self ) {
65
75
unsafe {
66
- k_sem_give ( self . item )
76
+ k_sem_give ( self . item . get ( ) )
67
77
}
68
78
}
69
79
@@ -75,7 +85,7 @@ impl Semaphore {
75
85
/// [`take`]: Self::take
76
86
pub fn reset ( & mut self ) {
77
87
unsafe {
78
- k_sem_reset ( self . item )
88
+ k_sem_reset ( self . item . get ( ) )
79
89
}
80
90
}
81
91
@@ -84,7 +94,7 @@ impl Semaphore {
84
94
/// Returns the current count.
85
95
pub fn count_get ( & mut self ) -> usize {
86
96
unsafe {
87
- k_sem_count_get ( self . item ) as usize
97
+ k_sem_count_get ( self . item . get ( ) ) as usize
88
98
}
89
99
}
90
100
}
@@ -114,7 +124,7 @@ impl Wrapped for StaticKernelObject<k_sem> {
114
124
k_sem_init ( ptr, arg. 0 , arg. 1 ) ;
115
125
}
116
126
Semaphore {
117
- item : ptr,
127
+ item : Fixed :: Static ( ptr) ,
118
128
}
119
129
}
120
130
}
0 commit comments