瀏覽代碼

!253 更新 RTC 设备驱动框架,统一并简化 RTC 设备的注册和访问过程
Merge pull request !253 from iysheng/tmp1

bernard 4 年之前
父節點
當前提交
ddc5c793a4

+ 2 - 0
bsp/efm32/drv_rtc.c

@@ -24,6 +24,8 @@
  ******************************************************************************/
 
 /* Includes ------------------------------------------------------------------*/
+
+#include <rtdevice.h>
 #include "board.h"
 #include "hdl_interrupt.h"
 #include "drv_rtc.h"

+ 61 - 81
bsp/stm32/libraries/HAL_Drivers/drv_rtc.c

@@ -8,6 +8,7 @@
  * 2018-12-04   balanceTWK    first version
  * 2020-10-14   Dozingfiretruck Porting for stm32wbxx
  * 2021-02-05   Meco Man      fix the problem of mixing local time and UTC time
+ * 2021-07-05   iysheng       implement RTC framework V2.0
  */
 
 #include "board.h"
@@ -25,8 +26,6 @@
 
 #define BKUP_REG_DATA 0xA5A5
 
-static struct rt_device rtc;
-
 static RTC_HandleTypeDef RTC_Handler;
 
 RT_WEAK uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister)
@@ -102,34 +101,6 @@ static rt_err_t set_rtc_time_stamp(time_t time_stamp)
     return RT_EOK;
 }
 
-static void rt_rtc_init(void)
-{
-#if !defined(SOC_SERIES_STM32H7) && !defined(SOC_SERIES_STM32WL) && !defined(SOC_SERIES_STM32WB)
-    __HAL_RCC_PWR_CLK_ENABLE();
-#endif
-
-    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
-#ifdef BSP_RTC_USING_LSI
-#ifdef SOC_SERIES_STM32WB
-RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI1;
-    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
-    RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
-    RCC_OscInitStruct.LSIState = RCC_LSI_ON;
-#else
-    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
-    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
-    RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
-    RCC_OscInitStruct.LSIState = RCC_LSI_ON;
-#endif
-#else
-    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
-    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
-    RCC_OscInitStruct.LSEState = RCC_LSE_ON;
-    RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
-#endif
-    HAL_RCC_OscConfig(&RCC_OscInitStruct);
-}
-
 #ifdef SOC_SERIES_STM32F1
 /* update RTC_BKP_DRx*/
 static void rt_rtc_f1_bkp_update(void)
@@ -160,7 +131,7 @@ static void rt_rtc_f1_bkp_update(void)
 }
 #endif
 
-static rt_err_t rt_rtc_config(struct rt_device *dev)
+static rt_err_t rt_rtc_config(void)
 {
     RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 
@@ -234,81 +205,90 @@ static rt_err_t rt_rtc_config(struct rt_device *dev)
     return RT_EOK;
 }
 
-static rt_err_t rt_rtc_control(rt_device_t dev, int cmd, void *args)
+static rt_err_t stm32_rtc_init(void)
 {
-    rt_err_t result = RT_EOK;
-    RT_ASSERT(dev != RT_NULL);
-    switch (cmd)
+#if !defined(SOC_SERIES_STM32H7) && !defined(SOC_SERIES_STM32WL) && !defined(SOC_SERIES_STM32WB)
+    __HAL_RCC_PWR_CLK_ENABLE();
+#endif
+
+    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+#ifdef BSP_RTC_USING_LSI
+#ifdef SOC_SERIES_STM32WB
+RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI1;
+    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
+    RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
+    RCC_OscInitStruct.LSIState = RCC_LSI_ON;
+#else
+    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
+    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
+    RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
+    RCC_OscInitStruct.LSIState = RCC_LSI_ON;
+#endif
+#else
+    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
+    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
+    RCC_OscInitStruct.LSEState = RCC_LSE_ON;
+    RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
+#endif
+    HAL_RCC_OscConfig(&RCC_OscInitStruct);
+
+    if (rt_rtc_config() != RT_EOK)
     {
-    case RT_DEVICE_CTRL_RTC_GET_TIME:
-        *(rt_uint32_t *)args = get_rtc_timestamp();
-        LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args);
-        break;
+        LOG_E("rtc init failed.");
+        return -RT_ERROR;
+    }
 
-    case RT_DEVICE_CTRL_RTC_SET_TIME:
-        if (set_rtc_time_stamp(*(rt_uint32_t *)args))
-        {
-            result = -RT_ERROR;
-        }
-        LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)args);
-        break;
+    return RT_EOK;
+}
+
+static rt_err_t stm32_rtc_get_secs(void *args)
+{
+    *(rt_uint32_t *)args = get_rtc_timestamp();
+    LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args);
+
+    return RT_EOK;
+}
+
+static rt_err_t stm32_rtc_set_secs(void *args)
+{
+    rt_err_t result = RT_EOK;
+
+    if (set_rtc_time_stamp(*(rt_uint32_t *)args))
+    {
+        result = -RT_ERROR;
     }
+    LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)args);
 
     return result;
 }
 
-#ifdef RT_USING_DEVICE_OPS
-const static struct rt_device_ops rtc_ops =
+static const struct rt_rtc_ops stm32_rtc_ops =
 {
+    stm32_rtc_init,
+    stm32_rtc_get_secs, /* get_secs */
+    stm32_rtc_set_secs, /* set secs */
     RT_NULL,
     RT_NULL,
     RT_NULL,
     RT_NULL,
-    RT_NULL,
-    rt_rtc_control
 };
-#endif
 
-static rt_err_t rt_hw_rtc_register(rt_device_t device, const char *name, rt_uint32_t flag)
-{
-    RT_ASSERT(device != RT_NULL);
+static rt_rtc_dev_t stm32_rtc_dev;
 
-    rt_rtc_init();
-    if (rt_rtc_config(device) != RT_EOK)
-    {
-        return -RT_ERROR;
-    }
-#ifdef RT_USING_DEVICE_OPS
-    device->ops         = &rtc_ops;
-#else
-    device->init        = RT_NULL;
-    device->open        = RT_NULL;
-    device->close       = RT_NULL;
-    device->read        = RT_NULL;
-    device->write       = RT_NULL;
-    device->control     = rt_rtc_control;
-#endif
-    device->type        = RT_Device_Class_RTC;
-    device->rx_indicate = RT_NULL;
-    device->tx_complete = RT_NULL;
-    device->user_data   = RT_NULL;
-
-    /* register a character device */
-    return rt_device_register(device, name, flag);
-}
-
-int rt_hw_rtc_init(void)
+static int rt_hw_rtc_init(void)
 {
     rt_err_t result;
-    result = rt_hw_rtc_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR);
+
+    stm32_rtc_dev.ops = &stm32_rtc_ops;
+    result = rt_rtc_dev_register(&stm32_rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR, RT_NULL);
     if (result != RT_EOK)
     {
         LOG_E("rtc register err code: %d", result);
         return result;
     }
     LOG_D("rtc init success");
+
     return RT_EOK;
 }
 INIT_DEVICE_EXPORT(rt_hw_rtc_init);
-
 #endif /* BSP_USING_ONCHIP_RTC */

+ 3 - 0
components/drivers/include/drivers/rtc.h

@@ -11,6 +11,9 @@
 #ifndef __RTC_H__
 #define __RTC_H__
 
+#include <rtconfig.h>
+#include <drivers/rtc_core.h>
+
 rt_err_t set_date(rt_uint32_t year, rt_uint32_t month, rt_uint32_t day);
 rt_err_t set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second);
 

+ 45 - 0
components/drivers/include/drivers/rtc_core.h

@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-06-11     iysheng      first version.
+ */
+
+#ifndef __RTC_CORE_H__
+#define __RTC_CORE_H__
+
+#include <rtthread.h>
+
+#define RT_DEVICE_CTRL_RTC_GET_TIME     0x10            /**< get second time */
+#define RT_DEVICE_CTRL_RTC_SET_TIME     0x11            /**< set second time */
+#define RT_DEVICE_CTRL_RTC_GET_TIME_US  0x12            /**< get microsecond time */
+#define RT_DEVICE_CTRL_RTC_SET_TIME_US  0x13            /**< set microsecond time */
+#define RT_DEVICE_CTRL_RTC_GET_ALARM    0x14            /**< get alarm */
+#define RT_DEVICE_CTRL_RTC_SET_ALARM    0x15            /**< set alarm */
+
+struct rt_rtc_ops
+{
+    rt_err_t (*init)(void);
+    rt_err_t (*get_secs)(void *arg);
+    rt_err_t (*set_secs)(void *arg);
+    rt_err_t (*get_alarm)(void *arg);
+    rt_err_t (*set_alarm)(void *arg);
+    rt_err_t (*get_usecs)(void *arg);
+    rt_err_t (*set_usecs)(void *arg);
+};
+
+typedef struct rt_rtc_device
+{
+    struct rt_device parent;
+    const struct rt_rtc_ops *ops;
+} rt_rtc_dev_t;
+
+rt_err_t rt_rtc_dev_register(rt_rtc_dev_t *rtc,
+                            const char    *name,
+                            rt_uint32_t    flag,
+                            void          *data);
+
+#endif /* __RTC_CORE_H__ */

+ 2 - 2
components/drivers/rtc/SConscript

@@ -13,7 +13,7 @@ CPPPATH = [cwd + '/../include']
 group = []
 
 if GetDepend(['RT_USING_RTC']):
-    src = src + rtc
+    src = src + ['rtc.c', 'rtc_core.c']
     if GetDepend(['RT_USING_ALARM']): 
         src = src + rtc_alarm
     if GetDepend(['RT_USING_SOFT_RTC']): 
@@ -21,4 +21,4 @@ if GetDepend(['RT_USING_RTC']):
 
 group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_RTC'], CPPPATH = CPPPATH)
 
-Return('group')
+Return('group')

+ 1 - 0
components/drivers/rtc/rtc.c

@@ -14,6 +14,7 @@
 #include <sys/time.h>
 #include <string.h>
 #include <rtthread.h>
+#include <drivers/rtc.h>
 
 #ifdef RT_USING_RTC
 

+ 123 - 0
components/drivers/rtc/rtc_core.c

@@ -0,0 +1,123 @@
+/*
+ * COPYRIGHT (C) 2011-2021, Real-Thread Information Technology Ltd
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-06-11     iysheng      first version.
+ */
+
+#include <drivers/rtc_core.h>
+
+#define TRY_DO_RTC_FUNC(rt_rtc_dev, func_name, args) \
+    rt_rtc_dev->ops->func_name ?  rt_rtc_dev->ops->func_name(args) : -RT_EINVAL;
+
+/*
+ * This function initializes rtc_core
+ */
+static rt_err_t rt_rtc_core_init(struct rt_device *dev)
+{
+    rt_rtc_dev_t *rtc_core;
+
+    RT_ASSERT(dev != RT_NULL);
+    rtc_core = (rt_rtc_dev_t *)dev;
+    if (rtc_core->ops->init)
+    {
+        return (rtc_core->ops->init());
+    }
+
+    return (-RT_ENOSYS);
+}
+
+static rt_err_t rt_rtc_core_open(struct rt_device *dev, rt_uint16_t oflag)
+{
+    return (RT_EOK);
+}
+
+static rt_err_t rt_rtc_core_close(struct rt_device *dev)
+{
+    /* Add close member function in rt_rtc_ops when need,
+     * then call that function here.
+     * */
+    return (RT_EOK);
+}
+
+static rt_err_t rt_rtc_core_control(struct rt_device *dev,
+                                    int              cmd,
+                                    void             *args)
+{
+    rt_rtc_dev_t *rtc_core;
+    rt_err_t ret = -RT_EINVAL;
+
+    RT_ASSERT(dev != RT_NULL);
+    rtc_core = (rt_rtc_dev_t *)dev;
+
+    switch (cmd)
+    {
+        case RT_DEVICE_CTRL_RTC_GET_TIME:
+            ret = TRY_DO_RTC_FUNC(rtc_core, get_secs, args);
+            break;
+        case RT_DEVICE_CTRL_RTC_SET_TIME:
+            ret = TRY_DO_RTC_FUNC(rtc_core, set_secs, args);
+            break;
+        case RT_DEVICE_CTRL_RTC_GET_TIME_US:
+            ret = TRY_DO_RTC_FUNC(rtc_core, get_usecs, args);
+            break;
+        case RT_DEVICE_CTRL_RTC_SET_TIME_US:
+            ret = TRY_DO_RTC_FUNC(rtc_core, set_usecs, args);
+            break;
+        case RT_DEVICE_CTRL_RTC_GET_ALARM:
+            ret = TRY_DO_RTC_FUNC(rtc_core, get_alarm, args);
+            break;
+        case RT_DEVICE_CTRL_RTC_SET_ALARM:
+            ret = TRY_DO_RTC_FUNC(rtc_core, set_alarm, args);
+            break;
+        default:
+            break;
+    }
+
+    return ret;
+}
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops rtc_core_ops =
+{
+    rt_rtc_core_init,
+    rt_rtc_core_open,
+    rt_rtc_core_close,
+    RT_NULL,
+    RT_NULL,
+    rt_rtc_core_control,
+};
+#endif
+
+rt_err_t rt_rtc_dev_register(rt_rtc_dev_t *rtc,
+                            const char    *name,
+                            rt_uint32_t    flag,
+                            void          *data)
+{
+    struct rt_device *device;
+    RT_ASSERT(rtc != RT_NULL);
+
+    device = &(rtc->parent);
+
+    device->type        = RT_Device_Class_RTC;
+    device->rx_indicate = RT_NULL;
+    device->tx_complete = RT_NULL;
+
+#ifdef RT_USING_DEVICE_OPS
+    device->ops         = &rtc_core_ops;
+#else
+    device->init        = rt_rtc_core_init;
+    device->open        = rt_rtc_core_open;
+    device->close       = rt_rtc_core_close;
+    device->read        = RT_NULL;
+    device->write       = RT_NULL;
+    device->control     = rt_rtc_core_control;
+#endif
+    device->user_data   = data;
+
+    /* register a character device */
+    return rt_device_register(device, name, flag);
+}
+

+ 9 - 0
components/libc/compilers/common/time.c

@@ -473,12 +473,17 @@ static int clock_time_system_init()
     rt_device_t device;
 
     time = 0;
+
+#ifdef RT_USING_RTC
     device = rt_device_find("rtc");
     if (device != RT_NULL)
     {
         /* get realtime seconds */
         rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time);
     }
+#else
+    LOG_W("Cannot find a RTC device to provide time!");
+#endif
 
     /* get tick */
     tick = rt_tick_get();
@@ -591,6 +596,7 @@ int clock_settime(clockid_t clockid, const struct timespec *tp)
     _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
     _timevalue.tv_sec = second - tick/RT_TICK_PER_SECOND - 1;
 
+#ifdef RT_USING_RTC
     /* update for RTC device */
     device = rt_device_find("rtc");
     if (device != RT_NULL)
@@ -599,6 +605,9 @@ int clock_settime(clockid_t clockid, const struct timespec *tp)
         rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second);
     }
     else
+#else
+    LOG_W("Cannot find a RTC device to save time!");
+#endif
         return -1;
 
     return 0;

+ 0 - 6
include/rtdef.h

@@ -962,12 +962,6 @@ enum rt_device_class_type
 #define RT_DEVICE_CTRL_BLK_AUTOREFRESH  0x13            /**< block device : enter/exit auto refresh mode */
 #define RT_DEVICE_CTRL_NETIF_GETMAC     0x10            /**< get mac address */
 #define RT_DEVICE_CTRL_MTD_FORMAT       0x10            /**< format a MTD device */
-#define RT_DEVICE_CTRL_RTC_GET_TIME     0x10            /**< get second time */
-#define RT_DEVICE_CTRL_RTC_SET_TIME     0x11            /**< set second time */
-#define RT_DEVICE_CTRL_RTC_GET_TIME_US  0x12            /**< get microsecond time */
-#define RT_DEVICE_CTRL_RTC_SET_TIME_US  0x13            /**< set microsecond time */
-#define RT_DEVICE_CTRL_RTC_GET_ALARM    0x14            /**< get alarm */
-#define RT_DEVICE_CTRL_RTC_SET_ALARM    0x15            /**< set alarm */
 
 typedef struct rt_device *rt_device_t;
 

+ 3 - 1
libcpu/arm/s3c24x0/rtc.c

@@ -12,11 +12,12 @@
  */
 
 #include <rtthread.h>
+#include <rtdevice.h>
 #include <sys/time.h>
 #include <s3c24x0.h>
 
 // #define RTC_DEBUG
-
+#ifdef RT_USING_RTC
 #define RTC_ENABLE      RTCCON |=  0x01;    /*RTC read and write enable */
 #define RTC_DISABLE     RTCCON &= ~0x01;    /* RTC read and write disable */
 #define BCD2BIN(n)      (((((n) >> 4) & 0x0F) * 10) + ((n) & 0x0F))
@@ -183,3 +184,4 @@ void list_date()
 }
 FINSH_FUNCTION_EXPORT(list_date, list date);
 #endif
+#endif