你的位置:首页 > 软件开发 > 操作系统 > 30.Linux

30.Linux

发布时间:2017-11-15 17:00:18
linux中的rtc驱动位于drivers/rtc下,里面包含了许多开发平台的RTC驱动,我们这里是以S3C24xx为主,所以它的RTC驱动为rtc-s3c.c 1.进入./drivers/rtc/rtc-s3c.c还是首先进入入口函数,如下图所示: 这里注册了一个&am ...

30.Linux

 linux中的rtc驱动位于drivers/rtc下,里面包含了许多开发平台的RTC驱动,我们这里是以S3C24xx为主,所以它的RTC驱动为rtc-s3c.c


 

1.进入./drivers/rtc/rtc-s3c.c

还是首先进入入口函数,如下图所示:

 30.Linux

这里注册了一个“s3c2410-rtc”名称的平台设备驱动

而“s3c2410-rtc”的平台设备,在./arch/arm/plat-s3c24xx/dev.c里定义了,只不过这里没有注册,如下图所示:

 30.Linux

当内核匹配到有与它名称同名的平台设备,就会调用.probe函数,接下来我们便进入s3c2410_rtcdrv->probe函数中看看,做了什么:

static int s3c_rtc_probe(struct platform_device *pdev){struct rtc_device *rtc;   //rtc设备结构体struct resource *res;int ret;s3c_rtc_tickno = platform_get_irq(pdev, 1);       //获取IRQ_TICK节拍中断资源s3c_rtc_alarmno = platform_get_irq(pdev, 0);       //获取IRQ_RTC闹钟中断资源res = platform_get_resource(pdev, IORESOURCE_MEM, 0); //获取内存资源s3c_rtc_mem = request_mem_region(res->start,res->end-res->start+1,pdev->name);//申请内存资源s3c_rtc_base = ioremap(res->start, res->end - res->start + 1);  //对内存进行重映射s3c_rtc_enable(pdev, 1);       //设置硬件相关设置,使能RTC寄存器s3c_rtc_setfreq(s3c_rtc_freq);  //设置TICONT寄存器,使能节拍中断,设置节拍计数值/*1.注册RTC设备*/rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops,THIS_MODULE); retry_get_time:  /*获取年,月,日,时,分,秒寄存器*/  rtc_tm->tm_min = readb(base + S3C2410_RTCMIN);   rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR);  rtc_tm->tm_mday = readb(base + S3C2410_RTCDATE);  rtc_tm->tm_mon = readb(base + S3C2410_RTCMON);  rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR);  rtc_tm->tm_sec = readb(base + S3C2410_RTCSEC);    /* 判断秒寄存器中是0,则表示过去了一分钟,那么小时,天,月,等寄存器中的值都可能已经变化,需要重新读取这些寄存器的值*/if (rtc_tm->tm_sec == 0 && !have_retried) {    have_retried = 1;    goto retry_get_time;  }  /*将获取的寄存器值,转换为真正的时间数据*/  BCD_TO_BIN(rtc_tm->tm_sec);  BCD_TO_BIN(rtc_tm->tm_min);  BCD_TO_BIN(rtc_tm->tm_hour);  BCD_TO_BIN(rtc_tm->tm_mday);  BCD_TO_BIN(rtc_tm->tm_mon);  BCD_TO_BIN(rtc_tm->tm_year); rtc_tm->tm_year += 100; //存储器中存放的是从1900年开始的时间,所以加上100  rtc_tm->tm_mon -= 1; return 0;}

同样, 在s3c_rtcops-> set_time()函数里,也是向相关寄存器写入RTC时间

所以,总结如下所示:

  • rtc_device->char_dev:   字符设备,与应用层、以及更底层的函数打交道
  • rtc_device->ops:    更底层的操作函数,直接操作硬件相关的寄存器,被rtc_device->char_dev调用

 

4.修改内核

我们单板上使用ls /dev/rtc*,找不到该字符设备, 因为内核里只定义了s3c_device_rtc这个RTC平台设备,没有注册,所以平台驱动没有被匹配上,接下来我们来修改内核里的注册数组

4.1进入arch/arm/plat-s3c24xx/Common-smdk.c

如下图所示,在smdk_devs[]里,添加RTC的平台设备即可,当内核启动时,就会调用该数组,将里面的platform_device统统注册一遍

 30.Linux

然后将Common-smdk.c代替虚拟机的内核目录下的Common-smdk.c,重新make uImage编译内核即可

5.测试运行

启动后,如下图所示, 使用ls /dev/rtc*,就找到了rtc0这个字符设备

 30.Linux

 

5.1接下来,便开始设置RTC时间

在linux里有两个时钟:

硬件时钟(2440里寄存器的时钟)、系统时钟(内核中的时钟)

所以有两个不同的命令: date命令、hwclock命令

5.2 date命令使用:

输入date查看系统时钟:

 30.Linux

如果觉得不方便也可以指定格式显示日期,需要在字符串前面加”+”

如下图所示,输入了  date  "+ %Y/%m/%d %H:%M:%S"

 30.Linux

  • %M:表示秒
  • %m:表示月
  • %Y:表示年,当只需要最后两位数字,输入%y即可

 

date命令设置时间格式如下:

date  月日时分年.秒

如下图所示,输入date 111515292017.20,即可设置好系统时钟

 30.Linux

 

5.3 hwclock命令使用:

常用参数如下所示

  -r, --show          读取并打印硬件时钟(read hardware clock and print result )
  -s, --hctosys      将硬件时钟同步到系统时钟(set the system time from the hardware clock )
  -w, --systohc     将系统时钟同步到硬件时钟(set the hardware clock to the current system time )

如下图所示,使用hwclock -w,即可同步硬件时钟

 30.Linux

 

 

然后重启后,使用date命令,看到时间正常

 

 

海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com

原标题:30.Linux

关键词:linux

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录