1. RTC概念简介
    RTC的英文全称为Real-time clock,中文名为实时时钟,是指可以像时钟一样输出实际时间的电子设备,一般会是集成电路,因此也称为时钟芯片。实时时钟芯片是日常生活中应用最为广泛的消费类电子产品之一。它为人们提供精确的实时时间,或者为电子系统提供精确的时间基准,目前实时时钟芯片大多采用精度较高的晶体振荡器作为时钟源。

2 SylixOS RTC关键结构体
2.1 RTC 设备
RTC 设备结构体LW_RTC_DEV是用来描述RTC设备的实体,是rtcOpen,rtcClose,__rtcIoctl函数的关键参数。他们包含两个成员变量,分别为设备头和操作函数集。代码描述如程序清单 2.1。
程序清单 2.1

typedef struct {
    LW_DEV_HDR           RTCDEV_devhdr;                                 /*  设备头  */
    PLW_RTC_FUNCS        RTCDEV_prtcfuncs;                             /*  操作函数*/
} LW_RTC_DEV;
typedef LW_RTC_DEV      *PLW_RTC_DEV;

2.2 RTC 函数集
RTC函数集结构体PLW_RTC_FUNCS是SylixOS 为用户抽象出来的处理硬件的接口,由用户实现。它是RTC设备创建函数API_RtcDevCreate的关键参数,包含四个函数指针,分别指向RTC初始化函数接口,设置RTC时间函数接口,获取RTC时间接口,可选的复杂RTC控制函数接口(比如设置闹铃时钟中断)。代码描述如程序清单 2.2。
程序清单 2.2

typedef struct {
    VOIDFUNCPTR     RTC_pfuncInit;                    /*  初始化 RTC               */
    FUNCPTR          RTC_pfuncSet;                     /*  设置硬件 RTC 时间        */
    FUNCPTR          RTC_pfuncGet;                     /*  读取硬件 RTC 时间        */
    FUNCPTR          RTC_pfuncIoctl;                   /*  更多复杂的 RTC 控制      */
                                                           /*  例如设置唤醒闹铃中断等等  */
} LW_RTC_FUNCS;
typedef LW_RTC_FUNCS       *PLW_RTC_FUNCS;

3 SylixOS RTC本地函数
SylixOS 为RTC实现了一套通用的操作函数,不用用户实现。他们分别为rtcOpen,rtcClose,rtcIoctl。
3.1
rtcOpen
这是文件系统打开RTC设备必须要调用的函数。该函数比较简单,只是增加文件打开的计数。函数实现如程序清单 3.1所示。
程序清单 3.1

/*********************************************************************************************************
** 函数名称: __rtcOpen
** 功能描述: 打开 RTC 设备
** 输  入  : prtcdev          rtc 设备
**           pcName           名字
**           iFlags           方式
**           iMode            方法
** 输  出  : 设备
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static LONG  __rtcOpen (PLW_RTC_DEV    prtcdev, 
                        PCHAR          pcName,   
                        INT            iFlags, 
                        INT            iMode)
{
    LW_DEV_INC_USE_COUNT(&prtcdev->RTCDEV_devhdr);

    return  ((LONG)prtcdev);
}

3.2 rtcClose
这是文件系统关闭RTC设备必须要调用的函数。它的操作和
rtcOpen相反,只是递减文件打开计数。函数实现如程序清单 3.2所示。
程序清单 3.2

/*********************************************************************************************************
** 函数名称: __rtcClose
** 功能描述: 关闭 RTC 设备
** 输  入  : prtcdev          rtc 设备
** 输  出  : 设备
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static INT  __rtcClose (PLW_RTC_DEV    prtcdev)
{
    if (prtcdev) {
        LW_DEV_DEC_USE_COUNT(&prtcdev->RTCDEV_devhdr);
        return  (ERROR_NONE);

    } else {
        return  (PX_ERROR);
    }
}

3.3 __rtcIoctl
这个函数是用来实现对RTC设备的控制,比如设置时间、获取时间和获取文件属性等。2.2节描述的用户实现的函数集将在这里被调用。函数实现如程序清单 3.3所示。
程序清单 3.3

static INT  __rtcIoctl (PLW_RTC_DEV    prtcdev, INT  iCmd, PVOID  pvArg)
{
    struct stat *pstat;

    switch (iCmd) {

    case FIOGETTIME:                                         /*  获得 rtc 时间  */
        if (prtcdev->RTCDEV_prtcfuncs->RTC_pfuncGet) {
            return  prtcdev->RTCDEV_prtcfuncs->RTC_pfuncGet(prtcdev->RTCDEV_prtcfuncs,
                                                            (time_t *)pvArg);
        }
        break;

    case FIOSETTIME:                                         /*  设置 rtc 时间  */
        if (prtcdev->RTCDEV_prtcfuncs->RTC_pfuncSet) {
            return  prtcdev->RTCDEV_prtcfuncs->RTC_pfuncSet(prtcdev->RTCDEV_prtcfuncs,
                                                            (time_t *)pvArg);
        }
        break;

    case FIOFSTATGET:                                       /*  获得文件属性    */
        pstat = (struct stat *)pvArg;
        pstat->st_dev     = (dev_t)prtcdev;
        pstat->st_ino     = (ino_t)0;                      /*  相当于唯一节点  */
        pstat->st_mode    = 0644 | S_IFCHR;               /*  默认属性        */
        pstat->st_nlink   = 1;
        pstat->st_uid     = 0;
        pstat->st_gid     = 0;
        pstat->st_rdev    = 1;
        pstat->st_size    = 0;
        pstat->st_blksize = 0;
        pstat->st_blocks  = 0;
        pstat->st_atime   = API_RootFsTime(LW_NULL);/*  默认使用 root fs 基准时间*/
        pstat->st_mtime   = API_RootFsTime(LW_NULL);
        pstat->st_ctime   = API_RootFsTime(LW_NULL);
        return  (ERROR_NONE);

    default:
        break;
    }

    if (prtcdev->RTCDEV_prtcfuncs->RTC_pfuncIoctl) {
        return  prtcdev->RTCDEV_prtcfuncs->RTC_pfuncIoctl(prtcdev->RTCDEV_prtcfuncs,
                                                          iCmd,
                                                          pvArg);
    } else {
        _ErrorHandle(ENOSYS);
        return  (PX_ERROR);
    }
}

4 SylixOS RTC全局函数

4.1 API_RtcDrvInstall
该函数是SylixOS为用户提供的RTC驱动安装函数,它将rtcOpen,rtcClose,__rtcIoctl整合进驱动程序控制块(LW_DEV_ENTRY)。在一个全局的驱动程序控制块表中查找到一个空闲的LW_DEV_ENTRY,然后初始化LW_DEV_ENTRY,并返回这个LW_DEV_ENTRY在表中的索引号。函数流程如流程图 4.1所示。
SylixOS RTC介绍_第1张图片
流程图 4.1
4.2 API_RtcDevCreate
该函数用来创建一个RTC设备。主要是申请一个LW_RTC_DEV结构体,并将初始化这个结构体,然后向系统中添加一个RTC设备,如有必要对RTC做硬件初始化。函数流程如流程图 4.2所示。
SylixOS RTC介绍_第2张图片

流程图 4.2
5 参考资料
《SylixOS_driver_usermanual》。