Stefan Roese | 00275f5 | 2022-09-02 13:57:53 +0200 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0+ |
| 2 | |
| 3 | Cyclic functions |
| 4 | ================ |
| 5 | |
| 6 | The cyclic function execution infrastruture provides a way to periodically |
| 7 | execute code, e.g. every 100ms. Examples for such functions might be LED |
| 8 | blinking etc. The functions that are hooked into this cyclic list should |
| 9 | be small timewise as otherwise the execution of the other code that relies |
| 10 | on a high frequent polling (e.g. UART rx char ready check) might be |
Weizhao Ouyang | 9e51164 | 2023-10-07 10:52:36 +0000 | [diff] [blame] | 11 | delayed too much. To detect cyclic functions with an excessive execution |
| 12 | time, the Kconfig option `CONFIG_CYCLIC_MAX_CPU_TIME_US` was introduced. |
| 13 | It defines the maximum allowable execution time for such a cyclic function. The |
| 14 | first time the execution of a cyclic function exceeds this interval, a warning |
| 15 | will be displayed indicating the problem to the user. |
Stefan Roese | 00275f5 | 2022-09-02 13:57:53 +0200 | [diff] [blame] | 16 | |
| 17 | Registering a cyclic function |
| 18 | ----------------------------- |
| 19 | |
| 20 | To register a cyclic function, use something like this:: |
| 21 | |
Rasmus Villemoes | 008c4b3 | 2024-05-21 10:46:52 +0200 | [diff] [blame] | 22 | struct donkey { |
| 23 | struct cyclic_info cyclic; |
| 24 | void (*say)(const char *s); |
| 25 | }; |
| 26 | |
| 27 | static void cyclic_demo(struct cyclic_info *c) |
Stefan Roese | 00275f5 | 2022-09-02 13:57:53 +0200 | [diff] [blame] | 28 | { |
Rasmus Villemoes | 008c4b3 | 2024-05-21 10:46:52 +0200 | [diff] [blame] | 29 | struct donkey *donkey = container_of(c, struct donkey, cyclic); |
| 30 | |
| 31 | donkey->say("Are we there yet?"); |
Stefan Roese | 00275f5 | 2022-09-02 13:57:53 +0200 | [diff] [blame] | 32 | } |
Rasmus Villemoes | 008c4b3 | 2024-05-21 10:46:52 +0200 | [diff] [blame] | 33 | |
| 34 | int donkey_init(void) |
Stefan Roese | 00275f5 | 2022-09-02 13:57:53 +0200 | [diff] [blame] | 35 | { |
Rasmus Villemoes | 008c4b3 | 2024-05-21 10:46:52 +0200 | [diff] [blame] | 36 | struct donkey *donkey; |
| 37 | |
| 38 | /* Initialize donkey ... */ |
| 39 | |
Stefan Roese | 00275f5 | 2022-09-02 13:57:53 +0200 | [diff] [blame] | 40 | /* Register demo cyclic function */ |
Rasmus Villemoes | 008c4b3 | 2024-05-21 10:46:52 +0200 | [diff] [blame] | 41 | cyclic_register(&donkey->cyclic, cyclic_demo, 10 * 1000, "cyclic_demo"); |
Stefan Roese | 00275f5 | 2022-09-02 13:57:53 +0200 | [diff] [blame] | 42 | |
| 43 | return 0; |
| 44 | } |
| 45 | |
| 46 | This will register the function `cyclic_demo()` to be periodically |
| 47 | executed all 10ms. |
| 48 | |
| 49 | How is this cyclic functionality integrated / executed? |
| 50 | -------------------------------------------------------- |
| 51 | |
| 52 | The cyclic infrastructure integrates the main function responsible for |
| 53 | calling all registered cyclic functions cyclic_run() into the common |
| 54 | WATCHDOG_RESET macro. This guarantees that cyclic_run() is executed |
| 55 | very often, which is necessary for the cyclic functions to get scheduled |
| 56 | and executed at their configured periods. |