- 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所示。
流程图 4.1
4.2 API_RtcDevCreate
该函数用来创建一个RTC设备。主要是申请一个LW_RTC_DEV结构体,并将初始化这个结构体,然后向系统中添加一个RTC设备,如有必要对RTC做硬件初始化。函数流程如流程图 4.2所示。
流程图 4.2
5 参考资料
《SylixOS_driver_usermanual》。