这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 行业应用 » 汽车电子 » 【S32K146】Rt-thread RTC 设备驱动使用

共1条 1/1 1 跳转至

【S32K146】Rt-thread RTC 设备驱动使用

高工
2025-06-27 15:03:33     打赏

【简介】

   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 开关

image.png

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, &currentTime );
    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, &currentTime);
    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驱动设备已经注册到系统

image.png

输入date  读取当前时间

image.png

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

image.png





共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]