cyclic.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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 <sr@denx.de>
  9. */
  10. #include <common.h>
  11. #include <command.h>
  12. #include <cyclic.h>
  13. #include <div64.h>
  14. #include <malloc.h>
  15. #include <linux/delay.h>
  16. struct cyclic_demo_info {
  17. uint delay_us;
  18. };
  19. static void cyclic_demo(void *ctx)
  20. {
  21. struct cyclic_demo_info *info = ctx;
  22. /* Just a small dummy delay here */
  23. udelay(info->delay_us);
  24. }
  25. static int do_cyclic_demo(struct cmd_tbl *cmdtp, int flag, int argc,
  26. char *const argv[])
  27. {
  28. struct cyclic_demo_info *info;
  29. struct cyclic_info *cyclic;
  30. uint time_ms;
  31. if (argc < 3)
  32. return CMD_RET_USAGE;
  33. info = malloc(sizeof(struct cyclic_demo_info));
  34. if (!info) {
  35. printf("out of memory\n");
  36. return CMD_RET_FAILURE;
  37. }
  38. time_ms = simple_strtoul(argv[1], NULL, 0);
  39. info->delay_us = simple_strtoul(argv[2], NULL, 0);
  40. /* Register demo cyclic function */
  41. cyclic = cyclic_register(cyclic_demo, time_ms * 1000, "cyclic_demo",
  42. info);
  43. if (!cyclic)
  44. printf("Registering of cyclic_demo failed\n");
  45. printf("Registered function \"%s\" to be executed all %dms\n",
  46. "cyclic_demo", time_ms);
  47. return 0;
  48. }
  49. static int do_cyclic_list(struct cmd_tbl *cmdtp, int flag, int argc,
  50. char *const argv[])
  51. {
  52. struct cyclic_info *cyclic;
  53. struct hlist_node *tmp;
  54. u64 cnt, freq;
  55. hlist_for_each_entry_safe(cyclic, tmp, cyclic_get_list(), list) {
  56. cnt = cyclic->run_cnt * 1000000ULL * 100ULL;
  57. freq = lldiv(cnt, timer_get_us() - cyclic->start_time_us);
  58. printf("function: %s, cpu-time: %lld us, frequency: %lld.%02d times/s\n",
  59. cyclic->name, cyclic->cpu_time_us,
  60. lldiv(freq, 100), do_div(freq, 100));
  61. }
  62. return 0;
  63. }
  64. static char cyclic_help_text[] =
  65. "demo <cycletime_ms> <delay_us> - register cyclic demo function\n"
  66. "cyclic list - list cyclic functions\n";
  67. U_BOOT_CMD_WITH_SUBCMDS(cyclic, "Cyclic", cyclic_help_text,
  68. U_BOOT_SUBCMD_MKENT(demo, 3, 1, do_cyclic_demo),
  69. U_BOOT_SUBCMD_MKENT(list, 1, 1, do_cyclic_list));