rtc为操作系统提供时钟、日历、闹钟、周期性中断等功能,并且在断电的情况下,可以由电池供电,以很小的耗电继续运行下去,Linux内核已经支持s3c2416的rtc驱动。

1. rtc设备

rtc设备包含了名字、独有的资源等等一些驱动程序的硬件或自定义信息。通过platform_add_devices(platform_device_register)函数将定义的平台设备注册到内核中,用于匹配设备驱动。

内核在drivers\rtc\rtc-s3c.c中实现了s3c2416 rtc驱动, rtc设备平台代码如下。

  1. static struct resources3c_rtc_resource[] = {
  2. [0]= DEFINE_RES_MEM(S3C24XX_PA_RTC, SZ_256),
  3. [1]= DEFINE_RES_IRQ(IRQ_RTC),
  4. [2]= DEFINE_RES_IRQ(IRQ_TICK),
  5. };
  6. struct platform_device s3c_device_rtc ={
  7. .name = "s3c2410-rtc",
  8. .id = -1,
  9. .num_resources = ARRAY_SIZE(s3c_rtc_resource),
  10. .resource = s3c_rtc_resource,
  11. };

在static struct platform_device *home2416_devices[]板级平台设备列表中加入&3c_device_rtc,使rtc设备能够注册到内核中。

rtc-s3c.c默认只支持devices tree匹配驱动的方式,修改rtc-s3c.c使之支持平台匹配的驱动方式。

s3c_rtc_driver结构体中加入s3c_rtc_driver_id。

  1. // add
  2. static const struct platform_device_ids3c_rtc_driver_ids[] = {
  3. {
  4. .name = "s3c2410-rtc",
  5. .driver_data = (unsigned long)&s3c2410_rtc_data,
  6. },{
  7. .name = "s3c2416-rtc",
  8. .driver_data = (unsigned long)&s3c2416_rtc_data,
  9. },{
  10. .name = "s3c2443-rtc",
  11. .driver_data = (unsigned long)&s3c2443_rtc_data,
  12. },{
  13. .name = "e3c6410-rtc",
  14. .driver_data = (unsigned long)&s3c6410_rtc_data,
  15. },{
  16. .name = "exynos3250-rtc",
  17. .driver_data = (unsigned long)&s3c6410_rtc_data,
  18. },
  19. {},
  20. };
  21. MODULE_DEVICE_TABLE(platform,s3c_rtc_driver_ids);
  22. static struct platform_drivers3c_rtc_driver = {
  23. .probe = s3c_rtc_probe,
  24. .remove = s3c_rtc_remove,
  25. .id_table = s3c_rtc_driver_ids, // add
  26. .driver = {
  27. .name = "s3c-rtc",
  28. .pm = &s3c_rtc_pm_ops,
  29. .of_match_table = of_match_ptr(s3c_rtc_dt_match),
  30. },
  31. };

s3c_rtc_probe函数中更改从platform_device_id表中获取rtc的driver data。

  1. conststruct platform_device_id *platid; // add
  2. // info->data= s3c_rtc_get_data(pdev); // delete
  3. platid= platform_get_device_id(pdev); // add
  4. info->data= (struct s3c_rtc_data *)platid->driver_data; // add

2. 内核配置

Linux配置支持rtc设备驱动,选中Device Drivers-> Real Time Clock ->Samsung S3C series SoC RTC。 10_RTC驱动 - 图1

3. rtc测试

编译内核并启动。用date命令设置、显示时间。 10_RTC驱动 - 图2

4. 应用编程

cat/proc/devices可以知道rtc的主设备号为253,次设备号为0,在/dev目录中创建rtc设备文件。

  1. mknod /dev/rtc0 c 253 0

应用程序可以通过设备文件访问rtc,rtc应用测试代码rtc_test.c如下。

  1. #include "fcntl.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <linux/rtc.h>
  5. #include <sys/ioctl.h>
  6. int main(void)
  7. {
  8. intfd;
  9. intret;
  10. structrtc_time rtc_tm;
  11. fd= open("/dev/rtc0", O_RDONLY);
  12. if(fd == -1) {
  13. printf("Openrtc failed\n");
  14. exit(1);
  15. }
  16. ret= ioctl(fd, RTC_RD_TIME, &rtc_tm);
  17. if(ret == -1) {
  18. printf("Readrtc failed\n");
  19. close(fd);
  20. exit(1);
  21. }
  22. printf("Oldtime: %d-%d-%d, %02d:%02d:%02d\n",
  23. rtc_tm.tm_year + 1900,rtc_tm.tm_mon + 1,rtc_tm.tm_mday,
  24. rtc_tm.tm_hour, rtc_tm.tm_min,rtc_tm.tm_sec);
  25. rtc_tm.tm_year= 2017 - 1900;
  26. rtc_tm.tm_mon= 2 - 1;
  27. rtc_tm.tm_mday= 20;
  28. rtc_tm.tm_hour= 21;
  29. rtc_tm.tm_min= 0;
  30. rtc_tm.tm_sec= 0;
  31. ret= ioctl(fd, RTC_SET_TIME, &rtc_tm);
  32. if(ret == -1) {
  33. printf("Writertc failed\n");
  34. close(fd);
  35. exit(1);
  36. }
  37. printf("Settime: %d-%d-%d, %02d:%02d:%02d\n",
  38. rtc_tm.tm_year + 1900,rtc_tm.tm_mon + 1,rtc_tm.tm_mday,
  39. rtc_tm.tm_hour, rtc_tm.tm_min,rtc_tm.tm_sec);
  40. ret= ioctl(fd, RTC_RD_TIME, &rtc_tm);
  41. if(ret == -1) {
  42. printf("Readrtc failed\n");
  43. close(fd);
  44. exit(1);
  45. }
  46. printf("Newtime: %d-%d-%d, %02d:%02d:%02d\n",
  47. rtc_tm.tm_year + 1900,rtc_tm.tm_mon + 1,rtc_tm.tm_mday,
  48. rtc_tm.tm_hour, rtc_tm.tm_min,rtc_tm.tm_sec);
  49. close(fd);
  50. return0;
  51. }

用arm-linux-gcc静态编译,使之生成arm cpu可执行的指令,并且可脱离任何库独立运行,arm-linux-gcc -static -o rtc_test rtc_test.c,生成rtc_test可执行文件。复制可执行文件到根文件系统,目标板启动后在目录输入./rtc_test即可执行。 10_RTC驱动 - 图3

5、附录

文件 下载地址
bootloader源码以及使用说明 https://pan.baidu.com/s/1slczwhJ
Qt5.8官网源码 https://pan.baidu.com/s/1eRDJtNs
本系列例程的根文件系统 https://pan.baidu.com/s/1nuGmSqt
opev3.2.0官网源码 https://pan.baidu.com/s/1i5btLGT
yaffs官网源码 https://pan.baidu.com/s/1pLpuHw3
busybox-1.26.2官网源码 https://pan.baidu.com/s/1bpkZynt
tslib官网源码 https://pan.baidu.com/s/1i4EtjfR
mplayer-1.3.0官网源码 https://pan.baidu.com/s/1i5MGRhb
基于S3C2416修改的linux-4.10.10源码 https://pan.baidu.com/s/1sl0fXlr