3838
3939static struct rt_work rtc_sync_work ;
4040static struct rt_device soft_rtc_dev ;
41- static struct timespec init_ts = { 0 };
4241static RT_DEFINE_SPINLOCK (_spinlock );
42+ /* RTC time baseline for calculation */
43+ static struct timespec init_ts = { 0 };
4344#ifdef RT_USING_KTIME
4445static struct timespec init_ktime_ts = { 0 };
4546#else
@@ -50,11 +51,28 @@ static rt_tick_t init_tick;
5051static struct rt_rtc_wkalarm wkalarm ;
5152static struct rt_timer alarm_time ;
5253
54+ /**
55+ * @brief Alarm timeout callback function
56+ * @param param Pointer to RTC device
57+ * @return None
58+ *
59+ * This function is called when the alarm timer expires and updates
60+ * the alarm system.
61+ */
5362static void alarm_timeout (void * param )
5463{
5564 rt_alarm_update (param , 1 );
5665}
5766
67+ /**
68+ * @brief Update soft RTC alarm status
69+ * @param palarm Pointer to alarm configuration structure
70+ * @return None
71+ *
72+ * This function updates the alarm timer based on the alarm enable status.
73+ * When enabled, it starts a 1-second period timer for alarm detection.
74+ * When disabled, it stops the timer.
75+ */
5876static void soft_rtc_alarm_update (struct rt_rtc_wkalarm * palarm )
5977{
6078 rt_tick_t next_tick ;
@@ -73,6 +91,16 @@ static void soft_rtc_alarm_update(struct rt_rtc_wkalarm *palarm)
7391
7492#endif
7593
94+ /**
95+ * @brief Set RTC time baseline
96+ * @param ts Pointer to timestamp to set as baseline
97+ * @return None
98+ *
99+ * This function sets a new time baseline for the soft RTC. All subsequent
100+ * time calculations will be based on this baseline. It records both the
101+ * time value and the corresponding system tick or high-precision time.
102+ * Also updates alarm status if alarms are enabled.
103+ */
76104static void set_rtc_time (struct timespec * ts )
77105{
78106 rt_base_t level = rt_spin_lock_irqsave (& _spinlock );
@@ -89,6 +117,16 @@ static void set_rtc_time(struct timespec *ts)
89117#endif
90118}
91119
120+ /**
121+ * @brief Get current RTC time
122+ * @param ts Output parameter to store the retrieved timestamp
123+ * @return None
124+ *
125+ * This function calculates the current time based on the stored baseline
126+ * and the elapsed system tick or high-precision time. It handles both
127+ * nanosecond overflow and underflow to ensure accurate time representation.
128+ * The calculation is thread-safe using spinlock protection.
129+ */
92130static void get_rtc_time (struct timespec * ts )
93131{
94132 rt_base_t level ;
@@ -101,21 +139,19 @@ static void get_rtc_time(struct timespec *ts)
101139 struct timespec current_ts ;
102140 rt_ktime_boottime_get_ns (& current_ts );
103141
104- /* Calculate time difference */
105142 ts -> tv_sec = init_ktime_ts .tv_sec + (current_ts .tv_sec - init_ktime_ts .tv_sec );
106143 ts -> tv_nsec = init_ktime_ts .tv_nsec + (current_ts .tv_nsec - init_ktime_ts .tv_nsec );
107144#else
108145 rt_tick_t tick = rt_tick_get_delta (init_tick );
109146 ts -> tv_sec = init_ts .tv_sec + tick / RT_TICK_PER_SECOND ;
110147 ts -> tv_nsec = init_ts .tv_nsec + ((tick % RT_TICK_PER_SECOND ) * (1000000000UL / RT_TICK_PER_SECOND ));
111148#endif
112- /* Handle nanosecond overflow */
149+ /* Handle nanosecond overflow/underflow */
113150 if (ts -> tv_nsec >= 1000000000L )
114151 {
115152 ts -> tv_sec ++ ;
116153 ts -> tv_nsec -= 1000000000L ;
117154 }
118- /* Handle nanosecond underflow */
119155 if (ts -> tv_nsec < 0 )
120156 {
121157 ts -> tv_sec -- ;
@@ -124,6 +160,24 @@ static void get_rtc_time(struct timespec *ts)
124160 rt_spin_unlock_irqrestore (& _spinlock , level );
125161}
126162
163+ /**
164+ * @brief RTC device control function
165+ * @param dev Pointer to RTC device
166+ * @param cmd Control command (RT_DEVICE_CTRL_RTC_*)
167+ * @param args Command arguments (varies by command)
168+ * @return rt_err_t RT_EOK on success, -RT_EINVAL on error
169+ *
170+ * This function handles various RTC control commands including:
171+ * - RT_DEVICE_CTRL_RTC_GET_TIME: Get current time as time_t
172+ * - RT_DEVICE_CTRL_RTC_SET_TIME: Set time from time_t
173+ * - RT_DEVICE_CTRL_RTC_GET_ALARM: Get alarm configuration
174+ * - RT_DEVICE_CTRL_RTC_SET_ALARM: Set alarm configuration
175+ * - RT_DEVICE_CTRL_RTC_GET_TIMEVAL: Get time as timeval
176+ * - RT_DEVICE_CTRL_RTC_SET_TIMEVAL: Set time from timeval
177+ * - RT_DEVICE_CTRL_RTC_GET_TIMESPEC: Get time as timespec
178+ * - RT_DEVICE_CTRL_RTC_SET_TIMESPEC: Set time from timespec
179+ * - RT_DEVICE_CTRL_RTC_GET_TIMERES: Get timer resolution
180+ */
127181static rt_err_t soft_rtc_control (rt_device_t dev , int cmd , void * args )
128182{
129183 time_t * t ;
@@ -236,6 +290,15 @@ const static struct rt_device_ops soft_rtc_ops = {
236290};
237291#endif
238292
293+ /**
294+ * @brief Soft RTC device initialization
295+ * @return int 0 on success
296+ *
297+ * This function initializes the soft RTC device, registers it to the system,
298+ * and sets the default time. It ensures only one RTC device named "rtc"
299+ * exists in the system and configures the device operations.
300+ * The initialization is performed only once.
301+ */
239302static int rt_soft_rtc_init (void )
240303{
241304 static rt_bool_t init_ok = RT_FALSE ;
@@ -245,7 +308,6 @@ static int rt_soft_rtc_init(void)
245308 {
246309 return 0 ;
247310 }
248- /* Make sure only one 'rtc' device */
249311#if defined(RT_USING_SOFT_RTC ) && defined(BSP_USING_ONCHIP_RTC )
250312#warning "Please note: Currently only one RTC device is allowed in the system, and the name is "rtc"."
251313#endif
@@ -294,6 +356,13 @@ INIT_DEVICE_EXPORT(rt_soft_rtc_init);
294356
295357#ifdef RT_USING_SYSTEM_WORKQUEUE
296358
359+ /**
360+ * @brief Soft RTC time synchronization
361+ * @return rt_err_t RT_EOK on success
362+ *
363+ * This function retrieves the current RTC time and resets the time baseline.
364+ * It's used to synchronize the soft RTC time with an external time source.
365+ */
297366rt_err_t rt_soft_rtc_sync (void )
298367{
299368 time_t time = 0 ;
@@ -304,16 +373,34 @@ rt_err_t rt_soft_rtc_sync(void)
304373 return RT_EOK ;
305374}
306375
376+ /**
377+ * @brief RTC sync work function
378+ * @param work Pointer to work item
379+ * @param work_data Work data (unused)
380+ * @return None
381+ *
382+ * This function is executed periodically to maintain soft RTC time accuracy.
383+ * It performs synchronization and schedules the next sync task.
384+ */
307385static void rtc_sync_work_func (struct rt_work * work , void * work_data )
308386{
309387 rt_soft_rtc_sync ();
310388 rt_work_submit (work , rt_tick_from_millisecond (RTC_AUTO_SYNC_PERIOD * 1000 ));
311389}
312390
391+ /**
392+ * @brief Set soft RTC time source
393+ * @param name Name of the time source device
394+ * @return rt_err_t RT_EOK on success
395+ *
396+ * This function configures the soft RTC to use a specific time source
397+ * and starts the periodic synchronization mechanism. The time source
398+ * device must exist before calling this function.
399+ */
313400rt_err_t rt_soft_rtc_set_source (const char * name )
314401{
315402 RT_ASSERT (name != RT_NULL );
316- RT_ASSERT (rt_device_find (name )); /* make sure source is exist*/
403+ RT_ASSERT (rt_device_find (name ));
317404
318405 rt_work_init (& rtc_sync_work , rtc_sync_work_func , RT_NULL );
319406 rt_work_submit (& rtc_sync_work , rt_tick_from_millisecond (RTC_AUTO_SYNC_FIRST_DELAY * 1000 ));
@@ -323,6 +410,15 @@ rt_err_t rt_soft_rtc_set_source(const char *name)
323410
324411#ifdef FINSH_USING_MSH
325412#include <finsh.h>
413+ /**
414+ * @brief RTC sync command handler
415+ * @param argc Argument count
416+ * @param argv Argument array
417+ * @return None
418+ *
419+ * MSH command that manually triggers RTC time synchronization and displays
420+ * the current time information. Usage: rtc_sync
421+ */
326422static void cmd_rtc_sync (int argc , char * * argv )
327423{
328424 struct timeval tv = { 0 };
@@ -333,7 +429,6 @@ static void cmd_rtc_sync(int argc, char **argv)
333429
334430 gettimeofday (& tv , & tz );
335431 now = tv .tv_sec ;
336- /* Output current time */
337432 rt_kprintf ("local time: %.*s" , 25 , ctime (& now ));
338433 rt_kprintf ("timestamps: %ld\n" , (long )tv .tv_sec );
339434}
0 commit comments