|
|
@@ -0,0 +1,303 @@
|
|
|
+/*
|
|
|
+ * 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 */
|