- 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》。