Pārlūkot izejas kodu

add alarm flags, alarm can repeated by hour minute and second

张世争 4 gadi atpakaļ
vecāks
revīzija
8d3f687abb

+ 6 - 1
components/drivers/include/drivers/alarm.h

@@ -6,6 +6,8 @@
  * Change Logs:
  * Change Logs:
  * Date           Author            Notes
  * Date           Author            Notes
  * 2012-10-27     heyuanjie87       first version.
  * 2012-10-27     heyuanjie87       first version.
+ * 2013-05-17     aozima            initial alarm event & mutex in system init.
+ * 2020-10-15     zhangsz           add alarm flags hour minute second.
  */
  */
 
 
 #ifndef __ALARM_H__
 #ifndef __ALARM_H__
@@ -22,6 +24,9 @@
 #define RT_ALARM_WEEKLY        0x200 /* alarm weekly at Monday or Friday etc. */
 #define RT_ALARM_WEEKLY        0x200 /* alarm weekly at Monday or Friday etc. */
 #define RT_ALARM_MONTHLY       0x400 /* alarm monthly at someday */
 #define RT_ALARM_MONTHLY       0x400 /* alarm monthly at someday */
 #define RT_ALARM_YAERLY        0x800 /* alarm yearly at a certain date */
 #define RT_ALARM_YAERLY        0x800 /* alarm yearly at a certain date */
+#define RT_ALARM_HOUR          0x1000 /* alarm each hour at a certain min:second */
+#define RT_ALARM_MINUTE        0x2000 /* alarm each minute at a certain second */
+#define RT_ALARM_SECOND        0x4000 /* alarm each second */
 
 
 /* alarm control cmd */
 /* alarm control cmd */
 #define RT_ALARM_CTRL_MODIFY       1 /* modify alarm time or alarm flag */
 #define RT_ALARM_CTRL_MODIFY       1 /* modify alarm time or alarm flag */
@@ -67,6 +72,6 @@ void rt_alarm_update(rt_device_t dev, rt_uint32_t event);
 rt_err_t rt_alarm_delete(rt_alarm_t alarm);
 rt_err_t rt_alarm_delete(rt_alarm_t alarm);
 rt_err_t rt_alarm_start(rt_alarm_t alarm);
 rt_err_t rt_alarm_start(rt_alarm_t alarm);
 rt_err_t rt_alarm_stop(rt_alarm_t alarm);
 rt_err_t rt_alarm_stop(rt_alarm_t alarm);
-void rt_alarm_system_init(void);
+int rt_alarm_system_init(void);
 
 
 #endif /* __ALARM_H__ */
 #endif /* __ALARM_H__ */

+ 141 - 9
components/drivers/rtc/alarm.c

@@ -7,6 +7,7 @@
  * Date           Author            Notes
  * Date           Author            Notes
  * 2012-10-27     heyuanjie87       first version.
  * 2012-10-27     heyuanjie87       first version.
  * 2013-05-17     aozima            initial alarm event & mutex in system init.
  * 2013-05-17     aozima            initial alarm event & mutex in system init.
+ * 2020-10-15     zhangsz           add alarm flags hour minute second.
  */
  */
 
 
 #include <rtthread.h>
 #include <rtthread.h>
@@ -97,6 +98,61 @@ static void alarm_wakeup(struct rt_alarm *alarm, struct tm *now)
             }
             }
         }
         }
         break;
         break;
+        case RT_ALARM_SECOND:
+        {
+            alarm->wktime.tm_hour = now->tm_hour;
+            alarm->wktime.tm_min = now->tm_min;
+            alarm->wktime.tm_sec = alarm->wktime.tm_sec + 1;
+            if (alarm->wktime.tm_sec > 59)
+            {
+                alarm->wktime.tm_sec = 0;
+                alarm->wktime.tm_min = alarm->wktime.tm_min + 1;
+                if (alarm->wktime.tm_min > 59)
+                {
+                    alarm->wktime.tm_min = 0;
+                    alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
+                    if (alarm->wktime.tm_hour > 23)
+                    {
+                        alarm->wktime.tm_hour = 0;
+                    }
+                }
+            }
+            wakeup = RT_TRUE;
+        }
+        break;
+        case RT_ALARM_MINUTE:
+        {
+            alarm->wktime.tm_hour = now->tm_hour;
+            if (alarm->wktime.tm_sec == now->tm_sec)
+            {
+                alarm->wktime.tm_min = alarm->wktime.tm_min + 1;
+                if (alarm->wktime.tm_min > 59)
+                {
+                    alarm->wktime.tm_min = 0;
+                    alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
+                    if (alarm->wktime.tm_hour > 23)
+                    {
+                        alarm->wktime.tm_hour = 0;
+                    }
+                }
+                wakeup = RT_TRUE;
+            }
+        }
+        break;
+        case RT_ALARM_HOUR:
+        {
+            if ((alarm->wktime.tm_min == now->tm_min) &&
+                (alarm->wktime.tm_sec == now->tm_sec))
+            {
+                alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
+                if (alarm->wktime.tm_hour > 23)
+                {
+                    alarm->wktime.tm_hour = 0;
+                }
+                wakeup = RT_TRUE;
+            }
+        }
+        break;
         case RT_ALARM_DAILY:
         case RT_ALARM_DAILY:
         {
         {
             if (((sec_now - sec_alarm) <= RT_ALARM_DELAY) && (sec_now >= sec_alarm))
             if (((sec_now - sec_alarm) <= RT_ALARM_DELAY) && (sec_now >= sec_alarm))
@@ -177,7 +233,7 @@ static void alarm_update(rt_uint32_t event)
             /* calculate seconds from 00:00:00 */
             /* calculate seconds from 00:00:00 */
             sec_alarm = alarm_mkdaysec(&alarm->wktime);
             sec_alarm = alarm_mkdaysec(&alarm->wktime);
 
 
-            if ((alarm->flag & RT_ALARM_STATE_START) && (alarm != _container.current))
+            if (alarm->flag & RT_ALARM_STATE_START)
             {
             {
                 sec_tmp = sec_alarm - sec_now;
                 sec_tmp = sec_alarm - sec_now;
                 if (sec_tmp > 0)
                 if (sec_tmp > 0)
@@ -212,6 +268,11 @@ static void alarm_update(rt_uint32_t event)
             if (alarm_set(alm_prev) == RT_EOK)
             if (alarm_set(alm_prev) == RT_EOK)
                 _container.current = alm_prev;
                 _container.current = alm_prev;
         }
         }
+        else
+        {
+            if (_container.current != RT_NULL)
+                alarm_set(_container.current);
+        }
     }
     }
     rt_mutex_release(&_container.mutex);
     rt_mutex_release(&_container.mutex);
 }
 }
@@ -279,6 +340,51 @@ static rt_err_t alarm_setup(rt_alarm_t alarm, struct tm *wktime)
 
 
     switch (alarm->flag & 0xFF00)
     switch (alarm->flag & 0xFF00)
     {
     {
+    case RT_ALARM_SECOND:
+    {
+        alarm->wktime.tm_hour = now.tm_hour;
+        alarm->wktime.tm_min = now.tm_min;
+        alarm->wktime.tm_sec = now.tm_sec + 1;
+        if (alarm->wktime.tm_sec > 59)
+        {
+            alarm->wktime.tm_sec = 0;
+            alarm->wktime.tm_min = alarm->wktime.tm_min + 1;
+            if (alarm->wktime.tm_min > 59)
+            {
+                alarm->wktime.tm_min = 0;
+                alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
+                if (alarm->wktime.tm_hour > 23)
+                {
+                    alarm->wktime.tm_hour = 0;
+                }
+            }
+        }
+    }
+    break;
+    case RT_ALARM_MINUTE:
+    {
+        alarm->wktime.tm_hour = now.tm_hour;
+        alarm->wktime.tm_min = now.tm_min + 1;
+        if (alarm->wktime.tm_min > 59)
+        {
+            alarm->wktime.tm_min = 0;
+            alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
+            if (alarm->wktime.tm_hour > 23)
+            {
+                alarm->wktime.tm_hour = 0;
+            }
+        }
+    }
+    break;
+    case RT_ALARM_HOUR:
+    {
+        alarm->wktime.tm_hour = now.tm_hour + 1;
+        if (alarm->wktime.tm_hour > 23)
+        {
+            alarm->wktime.tm_hour = 0;
+        }
+    }
+    break;
     case RT_ALARM_DAILY:
     case RT_ALARM_DAILY:
     {
     {
         /* do nothing but needed */
         /* do nothing but needed */
@@ -426,17 +532,17 @@ rt_err_t rt_alarm_start(rt_alarm_t alarm)
     if (alarm == RT_NULL)
     if (alarm == RT_NULL)
         return (ret);
         return (ret);
     rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER);
     rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER);
-    if (!(alarm->flag & RT_ALARM_STATE_INITED))
+
+    if (!(alarm->flag & RT_ALARM_STATE_START))
     {
     {
         if (alarm_setup(alarm, &alarm->wktime) != RT_EOK)
         if (alarm_setup(alarm, &alarm->wktime) != RT_EOK)
             goto _exit;
             goto _exit;
-    }
-    if ((alarm->flag & 0x01) == RT_ALARM_STATE_STOP)
-    {
+
         timestamp = time(RT_NULL);
         timestamp = time(RT_NULL);
         localtime_r(&timestamp, &now);
         localtime_r(&timestamp, &now);
 
 
         alarm->flag |= RT_ALARM_STATE_START;
         alarm->flag |= RT_ALARM_STATE_START;
+
         /* set alarm */
         /* set alarm */
         if (_container.current == RT_NULL)
         if (_container.current == RT_NULL)
         {
         {
@@ -518,10 +624,10 @@ _exit:
  */
  */
 rt_err_t rt_alarm_delete(rt_alarm_t alarm)
 rt_err_t rt_alarm_delete(rt_alarm_t alarm)
 {
 {
-    rt_err_t ret = RT_ERROR;
+    rt_err_t ret = RT_EOK;
 
 
     if (alarm == RT_NULL)
     if (alarm == RT_NULL)
-        return (ret);
+        return RT_ERROR;
     rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER);
     rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER);
     /* stop the alarm */
     /* stop the alarm */
     alarm->flag &= ~RT_ALARM_STATE_START;
     alarm->flag &= ~RT_ALARM_STATE_START;
@@ -551,9 +657,11 @@ rt_alarm_t rt_alarm_create(rt_alarm_callback_t callback, struct rt_alarm_setup *
 
 
     if (setup == RT_NULL)
     if (setup == RT_NULL)
         return (RT_NULL);
         return (RT_NULL);
+
     alarm = rt_malloc(sizeof(struct rt_alarm));
     alarm = rt_malloc(sizeof(struct rt_alarm));
     if (alarm == RT_NULL)
     if (alarm == RT_NULL)
         return (RT_NULL);
         return (RT_NULL);
+
     rt_list_init(&alarm->list);
     rt_list_init(&alarm->list);
 
 
     alarm->wktime = setup->wktime;
     alarm->wktime = setup->wktime;
@@ -586,13 +694,33 @@ static void rt_alarmsvc_thread_init(void *param)
     }
     }
 }
 }
 
 
+void rt_alarm_dump(void)
+{
+    rt_list_t *next;
+    rt_alarm_t alarm;
+    rt_uint8_t index = 0;
+
+    rt_kprintf("| alarm_id | YYYY-MM-DD hh:mm:ss | weekday |  flags  |\n");
+    rt_kprintf("+----------+---------------------+---------+---------+\n");
+    for (next = _container.head.next; next != &_container.head; next = next->next)
+    {
+        alarm = rt_list_entry(next, struct rt_alarm, list);
+        rt_kprintf("| No %5d | %04d-%02d-%02d %02d:%02d:%02d | %7d |  0x%04x |\n",
+            index++, alarm->wktime.tm_year + 1900, alarm->wktime.tm_mon + 1, alarm->wktime.tm_mday,
+            alarm->wktime.tm_hour, alarm->wktime.tm_min, alarm->wktime.tm_sec,
+            alarm->wktime.tm_wday, alarm->flag);
+    }
+    rt_kprintf("+----------+---------------------+---------+---------+\n");
+}
+
+FINSH_FUNCTION_EXPORT_ALIAS(rt_alarm_dump, __cmd_alarm_dump, dump alarm info);
 
 
 /** \brief initialize alarm service system
 /** \brief initialize alarm service system
  *
  *
  * \param none
  * \param none
  * \return none
  * \return none
  */
  */
-void rt_alarm_system_init(void)
+int rt_alarm_system_init(void)
 {
 {
     rt_thread_t tid;
     rt_thread_t tid;
 
 
@@ -602,8 +730,12 @@ void rt_alarm_system_init(void)
 
 
     tid = rt_thread_create("alarmsvc",
     tid = rt_thread_create("alarmsvc",
                            rt_alarmsvc_thread_init, RT_NULL,
                            rt_alarmsvc_thread_init, RT_NULL,
-                           512, 8, 1);
+                           2048, 10, 5);
     if (tid != RT_NULL)
     if (tid != RT_NULL)
         rt_thread_startup(tid);
         rt_thread_startup(tid);
+
+    return 0;
 }
 }
+
+INIT_PREV_EXPORT(rt_alarm_system_init);
 #endif
 #endif