RTC(OS)

本文详细介绍了如何在Linux系统中,使用平台设备驱动机制,通过修改或读取相应寄存器来设置和获取开发板的时间。实验通过编写驱动程序实现了时间的设置与实时显示,验证了在掉电状态下的时间保持功能。

一、实验平台:开发板fs2410,采用三星s3c2410的CPU,linux操作系统。

二、实现功能:设置开发板的时间,并能实时显示出时间。

三、实验原理:

       采用平台设备驱动机制来编写驱动程序,通过修改或读取相应寄存器的值来修改或获取开发板的时间。

四、实验现象:

       应用程序执行时,若输入./RTC_test set,则为设置当前时间,这时提示输入时间,格式为年月 日 时 分 秒(如2011 11 28 20 45 0)。若输入./RTC_test get则实时地显示当前的时间,可以看到每隔一秒钟,秒的时间+1。关掉开发板电源,等待一段时间后,再读取时间,可以看到时间是在改变的,即在掉电的状态下,时钟没有停下来,因为它有板子上的纽扣电池来供电。


五、实验总结:

       实验原理很简单,主要是体会一下采用平台设备驱动机制来写驱动代码时的步骤和思路,以及与之前没使用平台设备驱动机制时的不同。

六、示例代码:

驱动部分:

/*RTC_dev.c*/
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/init.h>
#include<linux/device.h>
#include <asm/mach/map.h>
#include<linux/platform_device.h>

static struct resource rtc_resource[] = {
	[0] = {
		.start = S3C24XX_PA_RTC,
		.end   = S3C24XX_PA_RTC + 0xff,
		.flags = IORESOURCE_MEM,
	}
};

void rtc_release(struct device * dev)
{
	
}

struct platform_device rtc_device = {
	.name 	= "myrtc",
	.id		= -1,
	.num_resources	  = ARRAY_SIZE(rtc_resource),
	.resource	  = rtc_resource,
	.dev 		= {
		.release 	 = rtc_release,
	},
};

int __init rtc_dev_init(void)
{
	platform_device_register(&rtc_device);
	
	return 0;
}

void __exit rtc_dev_exit(void)
{
	platform_device_unregister(&rtc_device);
}

module_init(rtc_dev_init);
module_exit(rtc_dev_exit);

MODULE_LICENSE("GPL");
/*RTC_drv.c*/
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/init.h>
#include<linux/device.h>
#include<linux/platform_device.h>
#include <linux/rtc.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/arch/regs-rtc.h>
#include <linux/bcd.h>

#define TIME_SET 	0
#define TIME_GET	1

static void __iomem *rtc_base;
static unsigned int rtc_major = 0;
static struct class *rtc_class = NULL;
static struct rtc_time rtc_time;

void set_time(struct rtc_time *rtc_time)
{
	int val;
	int year,mon,date,hour,min,sec;

	val = readb(rtc_base +S3C2410_RTCCON);
	val |=(0x1<<0);
	writeb(val, rtc_base +S3C2410_RTCCON);
	
	year = rtc_time->tm_year;
	mon = rtc_time->tm_mon;
	date = rtc_time->tm_mday;
	hour = rtc_time->tm_hour;
	min = rtc_time->tm_min;
	sec = rtc_time->tm_sec;
	
	year -= 1900;

	BIN_TO_BCD(year);
	BIN_TO_BCD(mon);
	BIN_TO_BCD(date);
	BIN_TO_BCD(hour);
	BIN_TO_BCD(min );
	BIN_TO_BCD(sec);
	
	writeb(year, rtc_base+S3C2410_RTCYEAR);
	writeb(mon, rtc_base+S3C2410_RTCMON);
	writeb(date, rtc_base+S3C2410_RTCDATE);
	writeb(hour, rtc_base+S3C2410_RTCHOUR);
	writeb(min, rtc_base+S3C2410_RTCMIN);
	writeb(sec,rtc_base+S3C2410_RTCSEC);

	val = readb(rtc_base +S3C2410_RTCCON);
	val &=~(0x1<<0);
	writeb(val, rtc_base +S3C2410_RTCCON);	
}

void get_time(struct rtc_time *rtc_time)
{
	int year,mon,date,hour,min,sec;
	
	year = readb(rtc_base+S3C2410_RTCYEAR);
	mon = readb(rtc_base+S3C2410_RTCMON);
	date = readb(rtc_base+S3C2410_RTCDATE);
	hour = readb(rtc_base+S3C2410_RTCHOUR);
	min = readb(rtc_base+S3C2410_RTCMIN);
	sec = readb(rtc_base+S3C2410_RTCSEC);
	
	BCD_TO_BIN(year);
	BCD_TO_BIN(mon);
	BCD_TO_BIN(date);
	BCD_TO_BIN(hour);
	BCD_TO_BIN(min);
	BCD_TO_BIN(sec);	
	
	year += 1900;

	rtc_time->tm_year = year;
	rtc_time->tm_mon = mon;
	rtc_time->tm_mday = date;
	rtc_time->tm_hour = hour;
	rtc_time->tm_min = min;
	rtc_time->tm_sec = sec;
}

static int rtc_open(struct inode *inode, struct file *file)
{
	return 0;
}

static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	int ret;
	
	switch(cmd){
		case TIME_SET:
			ret = copy_from_user(&rtc_time, (struct rtc_time *)arg, sizeof(rtc_time));
			set_time(&rtc_time);
			break;
		case TIME_GET:
			get_time(&rtc_time);
			ret = copy_to_user((struct rtc_time *)arg, &rtc_time, sizeof(rtc_time));
			break;
	}

	return 0;
}

struct file_operations rtc_fops = {
	.owner 	= THIS_MODULE,
	.open 	= rtc_open,
	.ioctl 	= rtc_ioctl,
};

static int __devinit rtc_probe(struct platform_device *pdev)
{
	struct resource *res;
	/*获得资源*/
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	/*映射*/
	rtc_base = ioremap(res->start, res->end-res->start+1);

	/*注册*/
	rtc_major = register_chrdev(0, "rtc", &rtc_fops);
	rtc_class = class_create(THIS_MODULE, "rtc_class");
	class_device_create(rtc_class, NULL, MKDEV(rtc_major, 0), NULL, "rtc");
	
	return 0;
}

static int __devexit rtc_remove(struct platform_device *dev)
{
	iounmap(rtc_base);
	unregister_chrdev(rtc_major, "rtc");
	class_destroy(rtc_class);
	class_device_destroy(rtc_class, MKDEV(rtc_major, 0));

	return 0;
}

struct platform_driver rtc_driver = {
	.probe 	= rtc_probe,
	.remove 	= rtc_remove,
	.driver ={
		.owner 	= THIS_MODULE,
		.name 	= "myrtc",
	},
};

int __init rtc_drv_init(void)
{
	platform_driver_register(&rtc_driver);

	return 0;
}

void __exit rtc_drv_exit(void)
{
	platform_driver_unregister(&rtc_driver);
}

module_init(rtc_drv_init);
module_exit(rtc_drv_exit);

MODULE_LICENSE("GPL");
/*测试代码RTC_test.c*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>

#define TIME_SET 0
#define TIME_GET 1

struct rtc_time{
	int tm_sec;
	int tm_min;
	int tm_hour;
	int tm_mday;
	int tm_mon;
	int tm_year;
	int tm_wday;
	int tm_yday;
	int tm_isdst;
};

int main(int argc,char **argv)
{
	int fd,cmd;
	struct rtc_time set_time,get_time;

	if(argc != 2){
		printf("Usage:./RTC_test set/get\n");
		exit(-1);
	}	

	if((fd = open("/dev/rtc",O_RDWR)) == -1){
		perror("/dev/rtc open failed");
		exit(-1);
	}

	if(strcmp(argv[1],"set") == 0){
		printf("设置时间(如2011 11 28 19 30 0):\n");
		scanf("%d%d%d%d%d%d",&set_time.tm_year,&set_time.tm_mon,&set_time.tm_mday
				,&set_time.tm_hour,&set_time.tm_min,&set_time.tm_sec);
		cmd = TIME_SET;
		ioctl(fd,cmd,&set_time);
	}
	else if(strcmp(argv[1],"get") == 0){
		cmd = TIME_GET;
		while(1){
			ioctl(fd,cmd,&get_time);
			printf("北京时间:%4d-%02d-%02d,%02d:%02d:%02d",get_time.tm_year,get_time.tm_mon,get_time.tm_mday
					,get_time.tm_hour,get_time.tm_min,get_time.tm_sec);
			fflush(stdout);
			usleep(500000);
			printf("\r");
		}
	}

	return 0;
}


源码来自:https://pan.quark.cn/s/41b9d28f0d6d 在信息技术领域中,jQuery作为一个广受欢迎的JavaScript框架,显著简化了诸多操作,包括对HTML文档的遍历、事件的管理、动画的设计以及Ajax通信等。 本篇文档将深入阐释如何运用jQuery达成一个图片自动播放的功能,这种效果常用于网站的轮播展示或幻灯片演示,有助于优化用户与页面的互动,使网页呈现更加动态的视觉体验。 为了有效实施这一功能,首先需掌握jQuery的核心操作。 通过$符号作为接口,jQuery能够迅速选取DOM组件,例如$("#id")用于选取具有特定ID的元素,而$(".class")则能选取所有应用了某类class的元素。 在选定元素之后,可以执行多种行为,诸如事件监听、样式的变更、内容的更新以及动画的制作等。 关于“一个基于jQuery的图片自动播放功能”,首要任务是准备一组图片素材,这些素材将被整合至一个容器元素之中。 例如,可以构建一个div元素,将其宽度设定为单张图片的尺寸,再借助CSS实现溢出内容的隐藏,从而构建出水平滚动的初始框架。 ```html<div id="slider"> <img src="image1.jpg" alt="Image 1"> <img src="image2.jpg" alt="Image 2"> <!-- 更多图片内容... --></div>```接着,需要编写jQuery脚本以实现图片的自动切换。 这通常涉及到定时器的运用,以设定周期性间隔自动更换当前显示的图片。 通过使用`.fadeOut()`和`.fadeIn()`方法,能够实现图片间的平滑过渡,增强视觉效果。 ```javascript$(document).re...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值