【简介】
RTC (Real-Time Clock)实时时钟可以提供精确的实时时间,它可以用于产生年、月、日、时、分、秒等信息。在RT-thread 中将RTC 设备驱动定义了特定的驱动框架,我们只要实现底层的OPS 函数即完成了RTC 驱动的适配。对应的OPS 如下,如果不使用alarm功能我么只要实现init/get_secs/set_secs/get_timeval/set_timeval函数接口即可。
/* used for alarm function */
struct rt_rtc_wkalarm
{
rt_bool_t enable; /* 0 = alarm disabled, 1 = alarm enabled */
rt_int32_t tm_sec; /* alarm at tm_sec */
rt_int32_t tm_min; /* alarm at tm_min */
rt_int32_t tm_hour; /* alarm at tm_hour */
rt_int32_t tm_mday; /* alarm at tm_mday */
rt_int32_t tm_mon; /* alarm at tm_mon */
rt_int32_t tm_year; /* alarm at tm_year */
};
struct rt_rtc_ops
{
rt_err_t (*init)(void);
rt_err_t (*get_secs)(time_t *sec);
rt_err_t (*set_secs)(time_t *sec);
rt_err_t (*get_alarm)(struct rt_rtc_wkalarm *alarm);
rt_err_t (*set_alarm)(struct rt_rtc_wkalarm *alarm);
rt_err_t (*get_timeval)(struct timeval *tv);
rt_err_t (*set_timeval)(struct timeval *tv);
};
typedef struct rt_rtc_device
{
struct rt_device parent;
const struct rt_rtc_ops *ops;
} rt_rtc_dev_t;【驱动配置】
1.Kconfig 配置
menuconfig BSP_USING_ONCHIP_RTC bool "Enable RTC" select RT_USING_RTC select RT_USING_LIBC default n
在menuconfig 中使能刚才配置的RTC 开关

2.SConscript 配置
添加rtc 驱动适配文件
# add rtc driver
if GetDepend('BSP_USING_ONCHIP_RTC'):
src += ['drv_rtc.c']添加S32K146 SDK RTC驱动代码
# add rtc drivers config.
if GetDepend('BSP_USING_ONCHIP_RTC'):
src += ['peripherals_rtc_1.c']# add rtc drivers config.
if GetDepend('BSP_USING_ONCHIP_RTC'):
src += ['platform/drivers/src/rtc/rtc_driver.c']
src += ['platform/drivers/src/rtc/rtc_hw_access.c']
src += ['platform/drivers/src/rtc/rtc_irq.c']3.RTC 驱动OPS配置
init 函数
static rt_err_t s32k14x_rtc_init(void)
{
status_t ret;
/* Call the init function */
ret = RTC_DRV_Init(RTC_1, &rtc_1InitCfg0);
if(ret != STATUS_SUCCESS)
{
LOG_E("RTC init failed %x.",ret);
goto __exit;
}
else
{
LOG_I("RTC init OK.");
}
/* Set the time and date */
ret = RTC_DRV_SetTimeDate(RTC_1, &rtc_1InitCfg0_StartTime);
if(ret != STATUS_SUCCESS)
{
LOG_E("RTC set time failed %x.",ret);
goto __exit;
}
else
{
LOG_I("RTC set time OK.");
}
/* Start RTC counter */
ret = RTC_DRV_StartCounter(RTC_1);
if(ret != STATUS_SUCCESS)
{
LOG_E("RTC start failed %x.",ret);
goto __exit;
}
else
{
LOG_I("RTC start OK.");
}
__exit:
return ret == STATUS_SUCCESS ? RT_EOK : -RT_ERROR;
}get_timeval 函数
static rt_err_t s32k14x_rtc_get_timeval(struct timeval *tv)
{
status_t ret;
rtc_timedate_t currentTime;
struct tm tm_new = {0};
ret = RTC_DRV_GetCurrentTimeDate ( RTC_1, ¤tTime );
if(ret != STATUS_SUCCESS)
{
LOG_E("RTC read failed %x.",ret);
goto __exit;
}
tm_new.tm_sec = currentTime.seconds;
tm_new.tm_min = currentTime.minutes;
tm_new.tm_hour = currentTime.hour;
tm_new.tm_mday = currentTime.day;
tm_new.tm_mon = currentTime.month-1;
tm_new.tm_year = currentTime.year-1900;
tv->tv_sec = timegm(&tm_new);
__exit:
return ret == STATUS_SUCCESS ? RT_EOK : -RT_ERROR;
}get_secs 函数
static rt_err_t s32k14x_rtc_get_secs(time_t *sec)
{
struct timeval tv;
s32k14x_rtc_get_timeval(&tv);
*(time_t *) sec = tv.tv_sec;
LOG_D("RTC: get rtc_time %d", *sec);
return RT_EOK;
}set_secs 函数
static rt_err_t set_rtc_time_stamp(time_t time_stamp)
{
status_t ret;
rtc_timedate_t currentTime;
struct tm tm = {0};
gmtime_r(&time_stamp, &tm);
if (tm.tm_year < 100)
{
return -RT_ERROR;
}
ret = RTC_DRV_StopCounter(RTC_1);
if(ret != STATUS_SUCCESS)
{
LOG_E("RTC stop failed %x.",ret);
return -RT_ERROR;
}
currentTime.seconds = tm.tm_sec ;
currentTime.minutes = tm.tm_min ;
currentTime.hour = tm.tm_hour;
currentTime.day = tm.tm_mday;
currentTime.month = tm.tm_mon + 1 ;
currentTime.year = tm.tm_year + 1900;
ret = RTC_DRV_SetTimeDate(RTC_1, ¤tTime);
if(ret != STATUS_SUCCESS)
{
LOG_E("RTC set time failed %x.",ret);
return -RT_ERROR;
}
ret = RTC_DRV_StartCounter(RTC_1);
if(ret != STATUS_SUCCESS)
{
LOG_E("RTC start failed %x.",ret);
return -RT_ERROR;
}
return RT_EOK;
}
static rt_err_t s32k14x_rtc_set_secs(time_t *sec)
{
rt_err_t result = RT_EOK;
if (set_rtc_time_stamp(*sec))
{
result = -RT_ERROR;
}
LOG_D("RTC: set rtc_time %d", *sec);
return result;
}注册rtc_ops 至系统
/********************************************************************************************************
* Private Variable Definitions *
*******************************************************************************************************/
static const struct rt_rtc_ops s32k14x_rtc_ops =
{
.init = s32k14x_rtc_init,
.get_secs = s32k14x_rtc_get_secs,
.get_timeval = s32k14x_rtc_get_timeval,
.set_secs = s32k14x_rtc_set_secs,
.get_alarm = NULL,
.set_alarm = NULL,
.set_timeval = NULL
};
static struct rt_rtc_device rtc_device;
/********************************************************************************************************
* Global Function Declarations *
*******************************************************************************************************/
static int rt_hw_rtc_init(void)
{
rt_err_t result;
rtc_device.ops = &s32k14x_rtc_ops;
result = rt_hw_rtc_register(&rtc_device, "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);【功能验证】
list device 发现RTC驱动设备已经注册到系统

输入date 读取当前时间

date 设置时间为2025/6/27 20:35:30,设置时间后再次读取时间和设置的保持一致

我要赚赏金
