clock_time_example.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * Copyright (c) 2006-2024, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-12-04 RT-Thread clock_time usage examples
  9. */
  10. /**
  11. * @file clock_time_example.c
  12. * @brief Examples demonstrating the unified clock_time subsystem
  13. *
  14. * This file contains various examples showing how to use the clock_time
  15. * subsystem for different time-related tasks.
  16. */
  17. #include <rtthread.h>
  18. #include <rtdevice.h>
  19. #ifdef RT_USING_CLOCK_TIME
  20. /**
  21. * @brief Example 1: Basic time information
  22. *
  23. * Demonstrates how to get clock frequency, resolution, and current counter.
  24. */
  25. static void clock_time_info_example(void)
  26. {
  27. rt_kprintf("\n=== Clock Time Info Example ===\n");
  28. /* Get clock frequency */
  29. rt_uint64_t freq = rt_clock_time_getfreq();
  30. rt_kprintf("Clock frequency: %u Hz\n", (rt_uint32_t)freq);
  31. /* Get clock resolution (in nanoseconds * RT_CLOCK_TIME_RESMUL) */
  32. rt_uint64_t res = rt_clock_time_getres();
  33. rt_kprintf("Clock resolution: %u ns (scaled)\n",
  34. (rt_uint32_t)(res / RT_CLOCK_TIME_RESMUL));
  35. /* Get current counter value */
  36. rt_uint64_t cnt = rt_clock_time_getcnt();
  37. rt_kprintf("Current counter: %u\n", (rt_uint32_t)cnt);
  38. /* Get device info */
  39. struct rt_clock_time_device *dev = rt_clock_time_get_default();
  40. if (dev)
  41. {
  42. rt_kprintf("Device name: %s\n", dev->parent.parent.name);
  43. rt_kprintf("Capabilities: ");
  44. if (dev->caps & RT_CLOCK_TIME_CAP_CLOCKSOURCE)
  45. rt_kprintf("CLOCKSOURCE ");
  46. if (dev->caps & RT_CLOCK_TIME_CAP_CLOCKEVENT)
  47. rt_kprintf("CLOCKEVENT ");
  48. rt_kprintf("\n");
  49. }
  50. }
  51. MSH_CMD_EXPORT(clock_time_info_example, Show clock time information);
  52. /**
  53. * @brief Example 2: Boottime tracking
  54. *
  55. * Demonstrates how to get system uptime in different formats.
  56. */
  57. static void clock_boottime_example(void)
  58. {
  59. struct timespec ts;
  60. struct timeval tv;
  61. time_t t;
  62. rt_kprintf("\n=== Boottime Example ===\n");
  63. /* Get boottime in nanoseconds */
  64. rt_clock_time_boottime_ns(&ts);
  65. rt_kprintf("Boottime (ns): %d.%09d seconds\n",
  66. (rt_uint32_t)ts.tv_sec, (rt_uint32_t)ts.tv_nsec);
  67. /* Get boottime in microseconds */
  68. rt_clock_time_boottime_us(&tv);
  69. rt_kprintf("Boottime (us): %d.%06d seconds\n",
  70. (rt_uint32_t)tv.tv_sec, (rt_uint32_t)tv.tv_usec);
  71. /* Get boottime in seconds */
  72. rt_clock_time_boottime_s(&t);
  73. rt_kprintf("Boottime (s): %d seconds\n", (rt_uint32_t)t);
  74. }
  75. MSH_CMD_EXPORT(clock_boottime_example, Show system boottime);
  76. /**
  77. * @brief Example 3: Time conversion
  78. *
  79. * Demonstrates conversion between counter ticks and time units.
  80. */
  81. static void clock_conversion_example(void)
  82. {
  83. rt_kprintf("\n=== Time Conversion Example ===\n");
  84. /* Convert 1 second to counter ticks */
  85. unsigned long cnt_1s = (unsigned long)rt_clock_time_ms_to_cnt(1000);
  86. rt_kprintf("1 second = %u counter ticks\n", cnt_1s);
  87. /* Convert back to time units */
  88. rt_uint64_t ms = rt_clock_time_cnt_to_ms(cnt_1s);
  89. rt_uint64_t us = rt_clock_time_cnt_to_us(cnt_1s);
  90. rt_uint64_t ns = rt_clock_time_cnt_to_ns(cnt_1s);
  91. rt_kprintf(" = %u ms\n", (rt_uint32_t)ms);
  92. rt_kprintf(" = %u us\n", (rt_uint32_t)us);
  93. rt_kprintf(" = %u ns\n", (rt_uint32_t)ns);
  94. }
  95. MSH_CMD_EXPORT(clock_conversion_example, Show time conversion);
  96. /**
  97. * @brief Example 4: High-precision delay
  98. *
  99. * Demonstrates using high-precision delay functions.
  100. */
  101. static void clock_delay_example(void)
  102. {
  103. rt_kprintf("\n=== High-Precision Delay Example ===\n");
  104. /* Measure delay accuracy */
  105. unsigned long start_cnt = (unsigned long)rt_clock_time_getcnt();
  106. rt_kprintf("Delaying 100 microseconds...\n");
  107. rt_clock_udelay(100);
  108. unsigned long end_cnt = (unsigned long)rt_clock_time_getcnt();
  109. unsigned long delta_cnt = end_cnt - start_cnt;
  110. rt_uint64_t actual_us = rt_clock_time_cnt_to_us(delta_cnt);
  111. rt_kprintf("Actual delay: %u us (target: 100 us)\n", (rt_uint32_t)actual_us);
  112. /* Millisecond delay */
  113. start_cnt = (unsigned long)rt_clock_time_getcnt();
  114. rt_kprintf("Delaying 10 milliseconds...\n");
  115. rt_clock_mdelay(10);
  116. end_cnt = (unsigned long)rt_clock_time_getcnt();
  117. delta_cnt = end_cnt - start_cnt;
  118. rt_uint64_t actual_ms = rt_clock_time_cnt_to_ms(delta_cnt);
  119. rt_kprintf("Actual delay: %u ms (target: 10 ms)\n", (rt_uint32_t)actual_ms);
  120. }
  121. MSH_CMD_EXPORT(clock_delay_example, Demonstrate high-precision delays);
  122. /**
  123. * @brief Example 5: High-resolution timer (one-shot)
  124. *
  125. * Demonstrates using high-resolution timer for one-shot timeout.
  126. */
  127. static void hrtimer_callback(void *parameter)
  128. {
  129. rt_kprintf("High-resolution timer fired! Parameter: %s\n",
  130. (char *)parameter);
  131. }
  132. static void clock_hrtimer_oneshot_example(void)
  133. {
  134. struct rt_clock_hrtimer timer;
  135. rt_kprintf("\n=== High-Resolution Timer (One-Shot) Example ===\n");
  136. /* Initialize one-shot timer */
  137. rt_clock_hrtimer_init(&timer, "oneshot_timer",
  138. RT_TIMER_FLAG_ONE_SHOT,
  139. hrtimer_callback,
  140. (void *)"One-shot timer");
  141. /* Start with 500ms delay */
  142. unsigned long delay_cnt = (unsigned long)rt_clock_time_ms_to_cnt(500);
  143. rt_kprintf("Starting timer for 500ms...\n");
  144. rt_err_t result = rt_clock_hrtimer_start(&timer, delay_cnt);
  145. if (result == RT_EOK)
  146. {
  147. rt_kprintf("Timer started successfully\n");
  148. }
  149. /* Let timer fire, then cleanup */
  150. rt_thread_mdelay(600);
  151. rt_clock_hrtimer_detach(&timer);
  152. rt_kprintf("Timer example complete\n");
  153. }
  154. MSH_CMD_EXPORT(clock_hrtimer_oneshot_example, Demonstrate one-shot hrtimer);
  155. /**
  156. * @brief Example 6: High-resolution timer (periodic)
  157. *
  158. * Demonstrates using high-resolution timer for periodic callbacks.
  159. */
  160. static volatile int periodic_count = 0;
  161. static void periodic_callback(void *parameter)
  162. {
  163. periodic_count++;
  164. rt_kprintf("Periodic timer tick #%d\n", periodic_count);
  165. }
  166. static void clock_hrtimer_periodic_example(void)
  167. {
  168. struct rt_clock_hrtimer timer;
  169. rt_kprintf("\n=== High-Resolution Timer (Periodic) Example ===\n");
  170. /* Initialize periodic timer */
  171. rt_clock_hrtimer_init(&timer, "periodic_timer",
  172. RT_TIMER_FLAG_PERIODIC,
  173. periodic_callback,
  174. RT_NULL);
  175. /* Start with 200ms period */
  176. unsigned long period_cnt = (unsigned long)rt_clock_time_ms_to_cnt(200);
  177. rt_kprintf("Starting periodic timer (200ms period)...\n");
  178. periodic_count = 0;
  179. rt_err_t result = rt_clock_hrtimer_start(&timer, period_cnt);
  180. if (result == RT_EOK)
  181. {
  182. rt_kprintf("Timer started successfully\n");
  183. }
  184. /* Let it tick 5 times */
  185. rt_thread_mdelay(1100);
  186. /* Stop and cleanup */
  187. rt_clock_hrtimer_stop(&timer);
  188. rt_clock_hrtimer_detach(&timer);
  189. rt_kprintf("Timer stopped. Total ticks: %d\n", periodic_count);
  190. }
  191. MSH_CMD_EXPORT(clock_hrtimer_periodic_example, Demonstrate periodic hrtimer);
  192. /**
  193. * @brief Example 7: Benchmark overhead
  194. *
  195. * Measures the overhead of various clock_time operations.
  196. */
  197. static void clock_benchmark_example(void)
  198. {
  199. const int iterations = 1000;
  200. unsigned long start, end;
  201. int i;
  202. rt_kprintf("\n=== Clock Time Benchmark ===\n");
  203. /* Benchmark get_counter() */
  204. start = (unsigned long)rt_clock_time_getcnt();
  205. for (i = 0; i < iterations; i++)
  206. {
  207. volatile unsigned long cnt = (unsigned long)rt_clock_time_getcnt();
  208. (void)cnt;
  209. }
  210. end = (unsigned long)rt_clock_time_getcnt();
  211. rt_kprintf("get_counter() x%d: %u ns per call\n",
  212. iterations,
  213. (rt_uint32_t)(rt_clock_time_cnt_to_ns(end - start) / iterations));
  214. /* Benchmark time conversion */
  215. start = (unsigned long)rt_clock_time_getcnt();
  216. for (i = 0; i < iterations; i++)
  217. {
  218. volatile rt_uint64_t us = rt_clock_time_cnt_to_us(1000);
  219. (void)us;
  220. }
  221. end = (unsigned long)rt_clock_time_getcnt();
  222. rt_kprintf("cnt_to_us() x%d: %u ns per call\n",
  223. iterations,
  224. (rt_uint32_t)(rt_clock_time_cnt_to_ns(end - start) / iterations));
  225. }
  226. MSH_CMD_EXPORT(clock_benchmark_example, Benchmark clock_time operations);
  227. /**
  228. * @brief Run all examples
  229. */
  230. static void clock_time_examples_all(void)
  231. {
  232. clock_time_info_example();
  233. rt_thread_mdelay(100);
  234. clock_boottime_example();
  235. rt_thread_mdelay(100);
  236. clock_conversion_example();
  237. rt_thread_mdelay(100);
  238. clock_delay_example();
  239. rt_thread_mdelay(100);
  240. clock_hrtimer_oneshot_example();
  241. rt_thread_mdelay(100);
  242. clock_hrtimer_periodic_example();
  243. rt_thread_mdelay(100);
  244. clock_benchmark_example();
  245. }
  246. MSH_CMD_EXPORT(clock_time_examples_all, Run all clock_time examples);
  247. #else
  248. #warning "RT_USING_CLOCK_TIME is not enabled. Examples will not be compiled."
  249. #endif /* RT_USING_CLOCK_TIME */