]>
Commit | Line | Data |
---|---|---|
1f865ee0 SR |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * A general-purpose cyclic execution infrastructure, to allow "small" | |
4 | * (run-time wise) functions to be executed at a specified frequency. | |
5 | * Things like LED blinking or watchdog triggering are examples for such | |
6 | * tasks. | |
7 | * | |
8 | * Copyright (C) 2022 Stefan Roese <[email protected]> | |
9 | */ | |
10 | ||
11 | #include <common.h> | |
12 | #include <command.h> | |
13 | #include <cyclic.h> | |
14 | #include <div64.h> | |
15 | #include <malloc.h> | |
16 | #include <linux/delay.h> | |
17 | ||
18 | struct cyclic_demo_info { | |
19 | uint delay_us; | |
20 | }; | |
21 | ||
22 | static void cyclic_demo(void *ctx) | |
23 | { | |
24 | struct cyclic_demo_info *info = ctx; | |
25 | ||
26 | /* Just a small dummy delay here */ | |
27 | udelay(info->delay_us); | |
28 | } | |
29 | ||
30 | static int do_cyclic_demo(struct cmd_tbl *cmdtp, int flag, int argc, | |
31 | char *const argv[]) | |
32 | { | |
33 | struct cyclic_demo_info *info; | |
34 | struct cyclic_info *cyclic; | |
35 | uint time_ms; | |
36 | ||
37 | if (argc < 3) | |
38 | return CMD_RET_USAGE; | |
39 | ||
40 | info = malloc(sizeof(struct cyclic_demo_info)); | |
41 | if (!info) { | |
42 | printf("out of memory\n"); | |
43 | return CMD_RET_FAILURE; | |
44 | } | |
45 | ||
46 | time_ms = simple_strtoul(argv[1], NULL, 0); | |
47 | info->delay_us = simple_strtoul(argv[2], NULL, 0); | |
48 | ||
49 | /* Register demo cyclic function */ | |
50 | cyclic = cyclic_register(cyclic_demo, time_ms * 1000, "cyclic_demo", | |
51 | info); | |
52 | if (!cyclic) | |
53 | printf("Registering of cyclic_demo failed\n"); | |
54 | ||
55 | printf("Registered function \"%s\" to be executed all %dms\n", | |
56 | "cyclic_demo", time_ms); | |
57 | ||
58 | return 0; | |
59 | } | |
60 | ||
61 | static int do_cyclic_list(struct cmd_tbl *cmdtp, int flag, int argc, | |
62 | char *const argv[]) | |
63 | { | |
28968394 RV |
64 | struct cyclic_info *cyclic; |
65 | struct hlist_node *tmp; | |
1f865ee0 SR |
66 | u64 cnt, freq; |
67 | ||
28968394 | 68 | hlist_for_each_entry_safe(cyclic, tmp, cyclic_get_list(), list) { |
1f865ee0 SR |
69 | cnt = cyclic->run_cnt * 1000000ULL * 100ULL; |
70 | freq = lldiv(cnt, timer_get_us() - cyclic->start_time_us); | |
71 | printf("function: %s, cpu-time: %lld us, frequency: %lld.%02d times/s\n", | |
72 | cyclic->name, cyclic->cpu_time_us, | |
73 | lldiv(freq, 100), do_div(freq, 100)); | |
74 | } | |
75 | ||
76 | return 0; | |
77 | } | |
78 | ||
3616218b | 79 | U_BOOT_LONGHELP(cyclic, |
8ba4eae0 | 80 | "demo <cycletime_ms> <delay_us> - register cyclic demo function\n" |
3616218b | 81 | "cyclic list - list cyclic functions\n"); |
1f865ee0 SR |
82 | |
83 | U_BOOT_CMD_WITH_SUBCMDS(cyclic, "Cyclic", cyclic_help_text, | |
84 | U_BOOT_SUBCMD_MKENT(demo, 3, 1, do_cyclic_demo), | |
85 | U_BOOT_SUBCMD_MKENT(list, 1, 1, do_cyclic_list)); |