RTC全称Real-Time Clock,RTC模块常用于时钟日历的功能。细节化的功能可以自行搜索,这里不做扩展。
在Env环境menuconfig中 RT-Thread Components->Device Drivers 设备驱动默认为n,所以需要开启。alarm 和 software simulation rtc根据应用情况选择,本章不做介绍
先在Kconfig中添加如下语句,然后在Env环境menuconfig中 Hardware Drivers Config->On-Chip Peripheral Drivers 使能RTC
设备驱动框架:rtc.c BSP接口:drv_rtc.c fsl_snvs_hp.c
笔者查阅了文件,发现 drv_rtc.c 编译无法通过,也不用慌,反正主要工作也是修改drv_xx.c bsp驱动的,只要官方设备驱动框架没问题就行。rtc 驱动直接参考父类device标准框架搭建的,如下:
static struct rt_device device =
{
.type = RT_Device_Class_RTC,
.init = imxrt_hp_rtc_init,
.open = imxrt_hp_rtc_open,
.close = imxrt_hp_rtc_close,
.read = imxrt_hp_rtc_read,
.write = imxrt_hp_rtc_write,
.control = imxrt_hp_rtc_control,
};
int rt_hw_rtc_init(void)
{
rt_err_t ret = RT_EOK;
ret = rt_device_register(&device, "rtc", RT_DEVICE_FLAG_RDWR);
if(ret != RT_EOK)
{
LOG_E("rt device register failed %d\n", ret);
return ret;
}
rt_device_open(&device, RT_DEVICE_OFLAG_RDWR);
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_rtc_init);
内容很简单直接贴代码,基本git下来的,修改一点点rtc框架就搭建好了
static time_t imxrt_get_timestamp(void)
{
struct tm tm_new = {0};
snvs_hp_rtc_datetime_t rtcDate = {0};
SNVS_HP_RTC_GetDatetime(SNVS, &rtcDate);
tm_new.tm_sec = rtcDate.second;
tm_new.tm_min = rtcDate.minute;
tm_new.tm_hour = rtcDate.hour;
tm_new.tm_mday = rtcDate.day;
tm_new.tm_mon = rtcDate.month - 1;
tm_new.tm_year = rtcDate.year - 1900;
return timegm(&tm_new);
}
static int imxrt_set_timestamp(time_t timestamp)
{
struct tm *p_tm;
snvs_hp_rtc_datetime_t rtcDate = {0};
p_tm = gmtime(×tamp);
rtcDate.second = p_tm->tm_sec ;
rtcDate.minute = p_tm->tm_min ;
rtcDate.hour = p_tm->tm_hour;
rtcDate.day = p_tm->tm_mday;
rtcDate.month = p_tm->tm_mon + 1;
rtcDate.year = p_tm->tm_year + 1900;
if (SNVS_HP_RTC_SetDatetime(SNVS, &rtcDate) != kStatus_Success)
{
LOG_E("set rtc date time failed\n");
return -RT_ERROR;
}
return RT_EOK;
}
static rt_err_t imxrt_hp_rtc_init(rt_device_t dev)
{
snvs_hp_rtc_config_t snvsRtcConfig;
SNVS_HP_RTC_GetDefaultConfig(&snvsRtcConfig);
SNVS_HP_RTC_Init(SNVS, &snvsRtcConfig);
return RT_EOK;
}
static rt_err_t imxrt_hp_rtc_open(rt_device_t dev, rt_uint16_t oflag)
{
SNVS_HP_RTC_StartTimer(SNVS);
return RT_EOK;
}
static rt_err_t imxrt_hp_rtc_close(rt_device_t dev)
{
SNVS_HP_RTC_StopTimer(SNVS);
return RT_EOK;
}
static rt_size_t imxrt_hp_rtc_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
return RT_EOK;
}
static rt_size_t imxrt_hp_rtc_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{
return RT_EOK;
}
static rt_err_t imxrt_hp_rtc_control(rt_device_t dev, int cmd, void *args)
{
RT_ASSERT(dev != RT_NULL);
switch(cmd)
{
case RT_DEVICE_CTRL_RTC_GET_TIME:
{
*(uint32_t *)args = imxrt_get_timestamp();
}
break;
case RT_DEVICE_CTRL_RTC_SET_TIME:
{
//set_timestamp(*(time_t *)args);
imxrt_set_timestamp(*(time_t *)args);
}
break;
default:
return RT_EINVAL;
}
return RT_EOK;
}
开启定时器,查阅时间精度是否ok
/**************************************************START OF FILE*****************************************************/
/*------------------------------------------------------------------------------------------------------------------
Includes
*/
#include <rtthread.h>
#include <rtdevice.h>
/*------------------------------------------------------------------------------------------------------------------
Macros
*/
/*------------------------------------------------------------------------------------------------------------------
Variables
*/
/*------------------------------------------------------------------------------------------------------------------
Functions
*/
static int rtcsample(int argc, char *argv[])
{
rt_err_t ret = RT_EOK;
/* 设置日期 */
ret = set_date(2022, 7, 2);
if (ret != RT_EOK)
{
rt_kprintf("set RTC date failed\n");
return ret;
}
/* 设置时间 */
ret = set_time(12, 00, 00);
if (ret != RT_EOK)
{
rt_kprintf("set RTC time failed\n");
return ret;
}
rt_kprintf("RTC time start\n");
return ret;
}
static void rtcprint(void)
{
time_t now;
/* 获取时间 */
now = time(RT_NULL);
rt_kprintf("%s\n", ctime(&now));
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(rtcsample, rtc sample);
MSH_CMD_EXPORT(rtcprint, rtc print);
输入命令rtcsample运行应用,输入rtcprint打印当前rtc时钟