| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- /*
- * Copyright (c) 2006-2024, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2024-12-04 RT-Thread clock_time usage examples
- */
- /**
- * @file clock_time_example.c
- * @brief Examples demonstrating the unified clock_time subsystem
- *
- * This file contains various examples showing how to use the clock_time
- * subsystem for different time-related tasks.
- */
- #include <rtthread.h>
- #include <rtdevice.h>
- #ifdef RT_USING_CLOCK_TIME
- /**
- * @brief Example 1: Basic time information
- *
- * Demonstrates how to get clock frequency, resolution, and current counter.
- */
- static void clock_time_info_example(void)
- {
- rt_kprintf("\n=== Clock Time Info Example ===\n");
-
- /* Get clock frequency */
- rt_uint64_t freq = rt_clock_time_getfreq();
- rt_kprintf("Clock frequency: %u Hz\n", (rt_uint32_t)freq);
-
- /* Get clock resolution (in nanoseconds * RT_CLOCK_TIME_RESMUL) */
- rt_uint64_t res = rt_clock_time_getres();
- rt_kprintf("Clock resolution: %u ns (scaled)\n",
- (rt_uint32_t)(res / RT_CLOCK_TIME_RESMUL));
-
- /* Get current counter value */
- rt_uint64_t cnt = rt_clock_time_getcnt();
- rt_kprintf("Current counter: %u\n", (rt_uint32_t)cnt);
-
- /* Get device info */
- struct rt_clock_time_device *dev = rt_clock_time_get_default();
- if (dev)
- {
- rt_kprintf("Device name: %s\n", dev->parent.parent.name);
- rt_kprintf("Capabilities: ");
- if (dev->caps & RT_CLOCK_TIME_CAP_CLOCKSOURCE)
- rt_kprintf("CLOCKSOURCE ");
- if (dev->caps & RT_CLOCK_TIME_CAP_CLOCKEVENT)
- rt_kprintf("CLOCKEVENT ");
- rt_kprintf("\n");
- }
- }
- MSH_CMD_EXPORT(clock_time_info_example, Show clock time information);
- /**
- * @brief Example 2: Boottime tracking
- *
- * Demonstrates how to get system uptime in different formats.
- */
- static void clock_boottime_example(void)
- {
- struct timespec ts;
- struct timeval tv;
- time_t t;
-
- rt_kprintf("\n=== Boottime Example ===\n");
-
- /* Get boottime in nanoseconds */
- rt_clock_time_boottime_ns(&ts);
- rt_kprintf("Boottime (ns): %d.%09d seconds\n",
- (rt_uint32_t)ts.tv_sec, (rt_uint32_t)ts.tv_nsec);
-
- /* Get boottime in microseconds */
- rt_clock_time_boottime_us(&tv);
- rt_kprintf("Boottime (us): %d.%06d seconds\n",
- (rt_uint32_t)tv.tv_sec, (rt_uint32_t)tv.tv_usec);
-
- /* Get boottime in seconds */
- rt_clock_time_boottime_s(&t);
- rt_kprintf("Boottime (s): %d seconds\n", (rt_uint32_t)t);
- }
- MSH_CMD_EXPORT(clock_boottime_example, Show system boottime);
- /**
- * @brief Example 3: Time conversion
- *
- * Demonstrates conversion between counter ticks and time units.
- */
- static void clock_conversion_example(void)
- {
- rt_kprintf("\n=== Time Conversion Example ===\n");
-
- /* Convert 1 second to counter ticks */
- unsigned long cnt_1s = (unsigned long)rt_clock_time_ms_to_cnt(1000);
- rt_kprintf("1 second = %u counter ticks\n", cnt_1s);
-
- /* Convert back to time units */
- rt_uint64_t ms = rt_clock_time_cnt_to_ms(cnt_1s);
- rt_uint64_t us = rt_clock_time_cnt_to_us(cnt_1s);
- rt_uint64_t ns = rt_clock_time_cnt_to_ns(cnt_1s);
-
- rt_kprintf(" = %u ms\n", (rt_uint32_t)ms);
- rt_kprintf(" = %u us\n", (rt_uint32_t)us);
- rt_kprintf(" = %u ns\n", (rt_uint32_t)ns);
- }
- MSH_CMD_EXPORT(clock_conversion_example, Show time conversion);
- /**
- * @brief Example 4: High-precision delay
- *
- * Demonstrates using high-precision delay functions.
- */
- static void clock_delay_example(void)
- {
- rt_kprintf("\n=== High-Precision Delay Example ===\n");
-
- /* Measure delay accuracy */
- unsigned long start_cnt = (unsigned long)rt_clock_time_getcnt();
-
- rt_kprintf("Delaying 100 microseconds...\n");
- rt_clock_udelay(100);
-
- unsigned long end_cnt = (unsigned long)rt_clock_time_getcnt();
- unsigned long delta_cnt = end_cnt - start_cnt;
-
- rt_uint64_t actual_us = rt_clock_time_cnt_to_us(delta_cnt);
- rt_kprintf("Actual delay: %u us (target: 100 us)\n", (rt_uint32_t)actual_us);
-
- /* Millisecond delay */
- start_cnt = (unsigned long)rt_clock_time_getcnt();
- rt_kprintf("Delaying 10 milliseconds...\n");
- rt_clock_mdelay(10);
- end_cnt = (unsigned long)rt_clock_time_getcnt();
- delta_cnt = end_cnt - start_cnt;
-
- rt_uint64_t actual_ms = rt_clock_time_cnt_to_ms(delta_cnt);
- rt_kprintf("Actual delay: %u ms (target: 10 ms)\n", (rt_uint32_t)actual_ms);
- }
- MSH_CMD_EXPORT(clock_delay_example, Demonstrate high-precision delays);
- /**
- * @brief Example 5: High-resolution timer (one-shot)
- *
- * Demonstrates using high-resolution timer for one-shot timeout.
- */
- static void hrtimer_callback(void *parameter)
- {
- rt_kprintf("High-resolution timer fired! Parameter: %s\n",
- (char *)parameter);
- }
- static void clock_hrtimer_oneshot_example(void)
- {
- struct rt_clock_hrtimer timer;
-
- rt_kprintf("\n=== High-Resolution Timer (One-Shot) Example ===\n");
-
- /* Initialize one-shot timer */
- rt_clock_hrtimer_init(&timer, "oneshot_timer",
- RT_TIMER_FLAG_ONE_SHOT,
- hrtimer_callback,
- (void *)"One-shot timer");
-
- /* Start with 500ms delay */
- unsigned long delay_cnt = (unsigned long)rt_clock_time_ms_to_cnt(500);
- rt_kprintf("Starting timer for 500ms...\n");
-
- rt_err_t result = rt_clock_hrtimer_start(&timer, delay_cnt);
- if (result == RT_EOK)
- {
- rt_kprintf("Timer started successfully\n");
- }
-
- /* Let timer fire, then cleanup */
- rt_thread_mdelay(600);
- rt_clock_hrtimer_detach(&timer);
-
- rt_kprintf("Timer example complete\n");
- }
- MSH_CMD_EXPORT(clock_hrtimer_oneshot_example, Demonstrate one-shot hrtimer);
- /**
- * @brief Example 6: High-resolution timer (periodic)
- *
- * Demonstrates using high-resolution timer for periodic callbacks.
- */
- static volatile int periodic_count = 0;
- static void periodic_callback(void *parameter)
- {
- periodic_count++;
- rt_kprintf("Periodic timer tick #%d\n", periodic_count);
- }
- static void clock_hrtimer_periodic_example(void)
- {
- struct rt_clock_hrtimer timer;
-
- rt_kprintf("\n=== High-Resolution Timer (Periodic) Example ===\n");
-
- /* Initialize periodic timer */
- rt_clock_hrtimer_init(&timer, "periodic_timer",
- RT_TIMER_FLAG_PERIODIC,
- periodic_callback,
- RT_NULL);
-
- /* Start with 200ms period */
- unsigned long period_cnt = (unsigned long)rt_clock_time_ms_to_cnt(200);
- rt_kprintf("Starting periodic timer (200ms period)...\n");
-
- periodic_count = 0;
- rt_err_t result = rt_clock_hrtimer_start(&timer, period_cnt);
- if (result == RT_EOK)
- {
- rt_kprintf("Timer started successfully\n");
- }
-
- /* Let it tick 5 times */
- rt_thread_mdelay(1100);
-
- /* Stop and cleanup */
- rt_clock_hrtimer_stop(&timer);
- rt_clock_hrtimer_detach(&timer);
-
- rt_kprintf("Timer stopped. Total ticks: %d\n", periodic_count);
- }
- MSH_CMD_EXPORT(clock_hrtimer_periodic_example, Demonstrate periodic hrtimer);
- /**
- * @brief Example 7: Benchmark overhead
- *
- * Measures the overhead of various clock_time operations.
- */
- static void clock_benchmark_example(void)
- {
- const int iterations = 1000;
- unsigned long start, end;
- int i;
-
- rt_kprintf("\n=== Clock Time Benchmark ===\n");
-
- /* Benchmark get_counter() */
- start = (unsigned long)rt_clock_time_getcnt();
- for (i = 0; i < iterations; i++)
- {
- volatile unsigned long cnt = (unsigned long)rt_clock_time_getcnt();
- (void)cnt;
- }
- end = (unsigned long)rt_clock_time_getcnt();
- rt_kprintf("get_counter() x%d: %u ns per call\n",
- iterations,
- (rt_uint32_t)(rt_clock_time_cnt_to_ns(end - start) / iterations));
-
- /* Benchmark time conversion */
- start = (unsigned long)rt_clock_time_getcnt();
- for (i = 0; i < iterations; i++)
- {
- volatile rt_uint64_t us = rt_clock_time_cnt_to_us(1000);
- (void)us;
- }
- end = (unsigned long)rt_clock_time_getcnt();
- rt_kprintf("cnt_to_us() x%d: %u ns per call\n",
- iterations,
- (rt_uint32_t)(rt_clock_time_cnt_to_ns(end - start) / iterations));
- }
- MSH_CMD_EXPORT(clock_benchmark_example, Benchmark clock_time operations);
- /**
- * @brief Run all examples
- */
- static void clock_time_examples_all(void)
- {
- clock_time_info_example();
- rt_thread_mdelay(100);
-
- clock_boottime_example();
- rt_thread_mdelay(100);
-
- clock_conversion_example();
- rt_thread_mdelay(100);
-
- clock_delay_example();
- rt_thread_mdelay(100);
-
- clock_hrtimer_oneshot_example();
- rt_thread_mdelay(100);
-
- clock_hrtimer_periodic_example();
- rt_thread_mdelay(100);
-
- clock_benchmark_example();
- }
- MSH_CMD_EXPORT(clock_time_examples_all, Run all clock_time examples);
- #else
- #warning "RT_USING_CLOCK_TIME is not enabled. Examples will not be compiled."
- #endif /* RT_USING_CLOCK_TIME */
|