You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> State transition is achieved by using the primitives provided by `<stdatomic.h>`.
6
+
7
+
```mermaid
8
+
stateDiagram-v2
9
+
[*] --> init: gptimer_new_timer
10
+
init --> enable: gptimer_enable
11
+
enable --> init: gptimer_disable
12
+
enable --> run: gptimer_start*
13
+
run --> enable: gptimer_stop*
14
+
init --> [*]: gptimer_del_timer
15
+
```
16
+
17
+
Other functions won't change the driver state. The functions above labeled with `*` are allowed to be used in the interrupt context.
18
+
19
+
## Concurrency
20
+
21
+
There might be race conditions when the user calls the APIs from a thread and interrupt at the same time. e.g. a Task is just running the `gptimer_start`, and suddenly an interrupt occurs, where the user calls `gptimer_stop` for the same timer handle. Which is possible to make a "stopped" timer continue to run if the interrupt is returned before the Task.
22
+
23
+
```mermaid
24
+
stateDiagram-v2
25
+
state Race-Condition {
26
+
Thread --> gptimer_start
27
+
state gptimer_start {
28
+
state is_enabled <<choice>>
29
+
[*] --> is_enabled: Enabled?
30
+
is_enabled --> run_wait: yes
31
+
is_enabled --> [*] : no
32
+
run_wait --> run: call HAL/LL functions to start timer
33
+
}
34
+
--
35
+
Interrupt --> gptimer_stop
36
+
state gptimer_stop {
37
+
state is_running <<choice>>
38
+
[*] --> is_running: Running?
39
+
is_running --> enable_wait: yes
40
+
is_running --> [*] : no
41
+
enable_wait --> enable: call HAL/LL functions to stop timer
42
+
}
43
+
}
44
+
```
45
+
46
+
By introducing a "middle" state like `run_wait` and `enable_wait`, we make sure that the timer is in a safe state before we start/stop it. And if the state is invalid, it can return an error code to the user.
* @note usually the timer resolution is same as what you configured in the `gptimer_config_t::resolution_hz`, but for some unstable clock source (e.g. RC_FAST), which needs a calibration, the real resolution may be different from the configured one.
100
+
* @note usually the timer resolution is same as what you configured in the `gptimer_config_t::resolution_hz`,
101
+
* but some unstable clock source (e.g. RC_FAST) will do a calibration, the real resolution can be different from the configured one.
100
102
*
101
103
* @param[in] timer Timer handle created by `gptimer_new_timer`
102
104
* @param[out] out_resolution Returned timer resolution, in Hz
* @note This function will transit the timer state from init to enable.
186
+
* @note This function will transit the timer state from "init" to "enable".
183
187
* @note This function will enable the interrupt service, if it's lazy installed in `gptimer_register_event_callbacks`.
184
188
* @note This function will acquire a PM lock, if a specific source clock (e.g. APB) is selected in the `gptimer_config_t`, while `CONFIG_PM_ENABLE` is enabled.
185
189
* @note Enable a timer doesn't mean to start it. See also `gptimer_start` for how to make the timer start counting.
0 commit comments