//刚启动的uClinux系统时间用date命令查看是1970年,心里很不爽,看了今天那篇关于时间的文章,想搞一下。可惜能力有限,改不了内部的date指令,只能自己写个showtime的小命令,调用S3C44B0X板子上面的RTC了,功能嘛仅仅是读出时间,需要时再扩充修改时间的功能。
============================驱动文件myrtc.c=======================================
/********************Copyright (c)**********************
** FREE
**--------------File Info---------------------------
** File Name: rtc.c
** Last modified Date: 2008-6-11
** Last Version: 1.0
** Descriptions: kernel char rtc driver
**--------------------------------------------------
** Created By: kyon
** Created date: 2008-6-11
** Version: 1.0
** Descriptions: First version
**--------------------------------------------------
** Modified by:
** Modified date:2008-6-9
** Version:1.0
** Descriptions:
*****************************************************/
//包含必要的头文件
#include <linux/config.h>
#include <linux/module.h> //模块必须包含的头文件
#include <linux/kernel.h> /* printk()函数,用于向内核输出信息 */
#include <linux/fs.h> /* 很重要 其中包含了如file_opration等结构 此结构用于文件层接口 */
#include <linux/errno.h> /* 错误代码*/
#include <asm/uaccess.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <asm/arch/s3c44b0x.h>
/********************************/
/* 应用程序配置 */
/********************************/
//以下根据需要改动
//定义主设备号 设备名称
#define RTC_MAJOR_NR 232 //231-255
#define DEVICE_NAME "rtc" //name for messaging
//my RTC define
#define RTC_YEAR0 (0x03) //年
#define RTC_MONTH0 (0x02) //月
#define RTC_DAY0 (0x0e) //日
#define RTC_DATE0 (0x06) //星期SUN:1 MON:2 TUE:3 WED:4 THU:5 FRI:6 SAT:7
#define RTC_HOUR0 (0x08) //小时
#define RTC_MIN0 (0x08) //分
#define RTC_SEC0 (0x08) //秒
#define RTC_YEAR1 (0x03) //年
#define RTC_MONTH1 (0x03) //月
#define RTC_DAY1 (0x0e) //日
#define RTC_DATE1 (0x06) //星期-SUN:1 MON:2 TUE:3 WED:4 THU:5 FRI:6 SAT:7
#define RTC_HOUR1 (0x08) //小时
#define RTC_MIN1 (0x08) //分
#define RTC_SEC1 (0x08) //秒
#define RTC_RW_EN() S3C44B0X_RTCCON = 1 //|= 1
#define RTC_RW_DS() S3C44B0X_RTCCON &= 0xfe
/************************************************************
function announce
************************************************************/
//以下是关键函数的声明
static int rtc_open(struct inode *inode, struct file *filp);
//打开设备时用的 linux把设备当作文件管理 设备最好在用的时候再打开 尽量不要提前
static int rtc_release(struct inode *inode, struct file *filp);
//static int rtc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
// unsigned long param);
//控制函数,rtc程序中没有使用
int rtc_init(void);//注册时用的 注意 模块注册的越早越好
void rtc_cleanup(void);//卸载时用的
/****************************************************************
** "全局和静态变量在这里定义"
** global variables and static variables define here
****************************************************************/
static struct file_operations RTC_fops = /* 前面基础部分提到的重要结构体了*/
{
owner: THIS_MODULE,
#if 0/*注意:#if 0-#endif里的代码是不编译的,但这里为了驱动模板讲解上的完整性仍然加上了*/
llseek: gpio_llseek,
read: gpio_read,
write: gpio_write,
ioctl: rtc_ioctl,//控制函数
#endif
open: rtc_open, //打开函数,打开文件时做初始化的
release: rtc_release,//释放函数,关闭时调用
};
typedef struct tagTIME{
unsigned short wYear;
unsigned char byMonth;
unsigned char byDay;
unsigned char byWeekday;
unsigned char byHour;
unsigned char byMin;
unsigned char bySec;
}TIME, *PTIME;
/**************************************************************
** Function name: rtcGetTime
** Descriptions:
** Input:inode:
** filp:
** Output 0:
** other:
** Created by: kyon
** Created Date: 2008-6-11
**------------------------------------------------------------
**************************************************************/
void rtcGetTime (PTIME pTime)
{
unsigned char byVal;
(*(volatile unsigned *)S3C44B0X_RTCCON) = 1; //RTC读写使能
pTime->wYear = 2000 + (*(volatile unsigned *)S3C44B0X_BCDYEAR);
pTime->byWeekday = (*(volatile unsigned *)S3C44B0X_BCDDATE);
byVal = (*(volatile unsigned *)S3C44B0X_BCDMON);
pTime->byMonth = (byVal>>4)*10 + (byVal&0xf); //BCD码转十进制
byVal = (*(volatile unsigned *)S3C44B0X_BCDDAY);
pTime->byDay = (byVal>>4)*10 + (byVal&0xf);
byVal = (*(volatile unsigned *)S3C44B0X_BCDHOUR);
pTime->byHour = (byVal>>4)*10 + (byVal&0xf);
byVal = (*(volatile unsigned *)S3C44B0X_BCDMIN);
pTime->byMin = (byVal>>4)*10 + (byVal&0xf);
byVal = (*(volatile unsigned *)S3C44B0X_BCDSEC);
pTime->bySec = (byVal>>4)*10 + (byVal&0xf);
(*(volatile unsigned *)S3C44B0X_RTCCON) &= 0xfe; //RTC读写禁止(降低功率消耗),选择BCD时钟、计数器,无复位,1/32768
}
/**************************************************************
** Function name: rtc_open
** Descriptions: open device
** Input:inode: information of device
** filp: pointer of file
** Output 0: OK
** other: not OK
** Created by: kyon
** Created Date: 2008-6-11
**------------------------------------------------------------
**************************************************************/
static int rtc_open(struct inode *inode, struct file *filp)
{
TIME time;
rtcGetTime (&time);
printk ("The current time is :\t%04d-%02d-%02d, %02d:%02d:%02d.\n",
time.wYear, time.byMonth, time.byDay, time.byHour, time.byMin, time.bySec);
MOD_INC_USE_COUNT;
return 0;
}
/*********************************************************
** Function name: rtc_release
** Descriptions: release device
** Input:inode: information of device
** filp: pointer of file
** Output 0: OK
** other: not OK
** Created by: kyon
** Created Date: 2008-6-11
**-----------------------------------------------------
** Modified by:
** Modified Date:
**-----------------------------------------------------
*********************************************************/
static int rtc_release(struct inode *inode, struct file *filp)
{
MOD_DEC_USE_COUNT;
return(0);
}
/**************************************************
** Function name: rtc_init
** Descriptions: init driver
** Input:none
** Output 0: OK
** other: not OK
** Created by: kyon
** Created Date: 2008-6-9
**------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------
***************************************************/
int rtc_init(void)
{
int result;
result = register_chrdev(232,"rtc", &RTC_fops);
/*关键语句 用于注册
** 注意!这是传统的注册方法 在2.4以上的linux版本中 加入了devfs设备文件系统 使注册更容易 但为了与大部分资料相**同 大家看的方便 这里仍然使用老方法*/
if (result < 0) //用于异常检测
{
printk(KERN_ERR DEVICE_NAME ": Unable to get major %d\n", RTC_MAJOR_NR ); //printk用于向内核输出信息
return(result);
}
printk(KERN_INFO DEVICE_NAME ": init OK\n");
return(0);
}
/*************************************************************
** Function name: rtc_cleanup
** Descriptions: exit driver
** Input:none
** Output none
** Created by:
** Created Date: 2008-6-11
**--------------------------------------------------------
** Modified by:
** Modified Date:
**--------------------------------------------------------
**************************************************************/
void rtc_cleanup(void)
{
unregister_chrdev(232, "rtc"); //与register_chrdev配对使用 用于清除驱动
}
/***********************************************************
** End Of File **
***********************************************************/
=============================用户程序showtime.c==========================
/*********************Copyright (c)**************************
** FREE
**--------------File Info----------------------------
** File Name: showtime.c
** Last modified Date: 2008-6-11
** Last Version: 1.0
** Descriptions: User rtc test file
**-------------------------------------------------------
** Created By: kyon
** Created date: 2008-6-11
** Version: 1.0
** Descriptions: First version
**--------------------------------------------------------
** Modified by:
** Modified date:
** Version:1.0
** Descriptions:
********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
void delay(int delay)//延时用函数
{
int i;
for(;delay>0;delay--)
{
for(i=0 ; i < 5000 ; i ++);
}
}
int main()
{
int fd3;
int j;
fd3= open("/dev/rtc" , O_RDWR);/*打开设备,就象打开文件一样简单*/
if(fd3 == -1)/*异常处理*/
{
printf ( "file can not be open" );
return -1;
}
delay(10000);
close (fd3);/*关闭设备(文件)*/
return 0;
}
(aokikyon) |