【RT-Thread】nxp rt10xx 设备驱动框架之--rtc搭建和使用

RTC全称Real-Time Clock,RTC模块常用于时钟日历的功能。细节化的功能可以自行搜索,这里不做扩展。

开发前准备

  • 硬件平台:nxp rt10xx单片机
  • IDE: Keil

1.Kconfig 修改和menuconfig配置

Env环境menuconfigRT-Thread Components->Device Drivers 设备驱动默认为n,所以需要开启。alarm 和 software simulation rtc根据应用情况选择,本章不做介绍

请添加图片描述

先在Kconfig中添加如下语句,然后在Env环境menuconfigHardware Drivers Config->On-Chip Peripheral Drivers 使能RTC

请添加图片描述

2.工程添加RTC驱动框架和BSP驱动接口

设备驱动框架:rtc.c BSP接口:drv_rtc.c fsl_snvs_hp.c

请添加图片描述

3.添加或修改drv_rtc.c

笔者查阅了文件,发现 drv_rtc.c 编译无法通过,也不用慌,反正主要工作也是修改drv_xx.c bsp驱动的,只要官方设备驱动框架没问题就行。rtc 驱动直接参考父类device标准框架搭建的,如下:

  • 定义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);
  • rtc device 相关函数

内容很简单直接贴代码,基本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(&timestamp);

    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;
}

4.搭建应用层demo

开启定时器,查阅时间精度是否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时钟

请添加图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值