Linux RTC 驱动实验

news2024/11/16 23:41:50

RTC 也就是实时时钟,用于记录当前系统时间,对于 Linux 系统而言时间是非常重要的, 就和我们使用 Windows 电脑或手机查看时间一样,我们在使用 Linux 设备的时候也需要查看时 间。

一、Linux 内核 RTC 驱动简介

  • RTC 设备驱动是标准的字符设备驱动,应用程序通过 open、release、read、write 和 ioctl 等函数完成对 RTC 设备的操作。
  • Linux 内核将 RTC 设备抽象为 rtc_device 结构体,RTC 设备驱动申请并初始化 rtc_device,将 rtc_device 注册到内核。
  • RTC 设备的操作肯定是用一个操作集合(结构体)来表示的,rtc_device 结构体,此结构体定义在 include/linux/rtc.h 文件中。
  • drivers/rtc/rtc-dev.c 是Linux 内核提供的 RTC 通用字符设备驱动文件,结构体定义在 include/linux/rtc.h 文件中。
struct rtc_device
 {
 struct device dev; /* 设备 */
 struct module *owner;

 int id; /* ID */ 
 char name[RTC_DEVICE_NAME_SIZE]; /* 名字 */
 
 const struct rtc_class_ops *ops; /* RTC 设备底层操作函数 */
 struct mutex ops_lock;

 struct cdev char_dev; /* 字符设备 */
 unsigned long flags;

 unsigned long irq_data;
 spinlock_t irq_lock;
 wait_queue_head_t irq_queue;
 struct fasync_struct *async_queue;

 struct rtc_task *irq_task;
 spinlock_t irq_task_lock;
 int irq_freq;
 int max_user_freq;

 struct timerqueue_head timerqueue;
 struct rtc_timer aie_timer;
 struct rtc_timer uie_rtctimer;
 struct hrtimer pie_timer; /* sub second exp, so needs hrtimer */
 int pie_enabled;
 struct work_struct irqwork;
 /* Some hardware can't support UIE mode */
 int uie_unsupported;
};

 我们需要重点关注的是 ops 成员变量,这是一个 rtc_class_ops 类型的指针变量,rtc_class_ops 为 RTC 设备的最底层操作函数集合,包括从 RTC 设备中读取时间、向 RTC 设备写入新的时间 值等。因此,rtc_class_ops 是需要用户根据所使用的 RTC 设备编写的,此结构体定义在 include/linux/rtc.h 文件中,内容如下:

struct rtc_class_ops {
 int (*open)(struct device *);
 void (*release)(struct device *);
 int (*ioctl)(struct device *, unsigned int, unsigned long);
 int (*read_time)(struct device *, struct rtc_time *);
 int (*set_time)(struct device *, struct rtc_time *);
 int (*read_alarm)(struct device *, struct rtc_wkalrm *);
 int (*set_alarm)(struct device *, struct rtc_wkalrm *);
 int (*proc)(struct device *, struct seq_file *);
 int (*set_mmss64)(struct device *, time64_t secs);
 int (*set_mmss)(struct device *, unsigned long secs);
 int (*read_callback)(struct device *, int data);
 int (*alarm_irq_enable)(struct device *, unsigned int enabled);
 };

rtc_class_ops 中的这些函数只是最底层的 RTC 设备操作函数,并不是提供给应用层的 file_operations 函数操作集。RTC 是个字符设备,那么肯定有字符设备的 file_operations 函数操 作集,Linux 内核提供了一个 RTC 通用字符设备驱动文件,文件名为 drivers/rtc/rtc-dev.c,rtcdev.c 文件提供了所有 RTC 设备共用的 file_operations 函数操作集,如下所示:

static const struct file_operations rtc_dev_fops = {
 .owner = THIS_MODULE,
 .llseek = no_llseek,
 .read = rtc_dev_read,
 .poll = rtc_dev_poll,
 .unlocked_ioctl = rtc_dev_ioctl,
 .open = rtc_dev_open,
 .release = rtc_dev_release,
 .fasync = rtc_dev_fasync,
 };

当 rtc_class_ops 准备好以后需要将其注册到 Linux 内核中,这里我们可以使用 rtc_device_register函数完成注册工作。此函数会申请一个rtc_device并且初始化这个rtc_device, 最后向调用者返回这个 rtc_device,此函数原型如下:

struct rtc_device *rtc_device_register(const char *name, 
 struct device *dev,
 const struct rtc_class_ops *ops,
 struct module *owner)

/*
函数参数和返回值含义如下:
name:设备名字。
dev:设备。
ops:RTC 底层驱动函数集。
owner:驱动模块拥有者。
返回值:注册成功的话就返回 rtc_device,错误的话会返回一个负值。
*/

当卸载 RTC 驱动的时候需要调用 rtc_device_unregister 函数来注销注册的 rtc_device,函数 原型如下:

void rtc_device_unregister(struct rtc_device *rtc)
/*
函数参数和返回值含义如下:
rtc:要删除的 rtc_device。
返回值:无。
*/

还有另外一对 rtc_device 注册函数 devm_rtc_device_registerdevm_rtc_device_unregister, 分别为注册和注销 rtc_device。

二、I.MX6U 内部 RTC 驱动分析

  • RTC 底层驱动集为 snvs_rtc_ops。snvs_rtc_ops操作集包含了读取/设置RTC时间,读取/设置闹钟等函数。
  • imx6ull.dtsi,设备节点名为 snvs_rtc。compatible 的值为“fsl,sec-v4.0-mon-rtc-lp”,驱动文件为 drivers/rtc/rtc-snvs.c。
  • 设备树 ID 表,compatible 属性,值为“fsl,sec-v4.0-mon-rtc-lp”, imx6ull.dtsi 中的 snvs_rtc 设备节点会和此驱动匹配。 
  • 当设备和驱动匹配成功以后 snvs_rtc_probe 函数就会执行。
  • platform_get_resource 函数从设备树中获取到 RTC 外设寄存器基地址。
  • devm_ioremap_resource 完成内存映射,得到 RTC 外设寄存器物理基地址对应的虚拟地址。
  • devm_regmap_init_mmio 函数将 RTC 的硬件寄存器转化为 regmap 形式。
  • snvs_rtc_enable 函数使能 RTC,此函数会设置 RTC_LPCR 寄存器。
  • devm_request_irq函数请求RTC中断。
  • snvs_rtc_irq_handler为中断服务函数,用于 RTC 闹钟中断。
  • snvs_rtc_read_time 函数用于读取 RTC 时间值。
  • rtc_read_lp_counter 获取 RTC 计数值,这个时间值是秒数。
  • rtc_time_to_tm 函数将获取到的秒数转换为时间值。
  • rtc_read_lp_counter 函数,此函数用于读取 RTC 计数值。

三、RTC 时间查看与设置

1、时间 RTC 查看

  • Linux 内核在启动的时候将 snvs_rtc 设置为 rtc0。
  • Linux 内核启动的时候可以看到系统时钟设置信息:

 使用“date”命令查看时间:

 2、设置 RTC 时间

date -s "2023-05-20 9:30:00"        //设置当前系统时间
hwclock -w                            //将当前系统时间写入到 RTC 里面

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/546964.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

verdaccio + docker搭建私有npm仓库(有手就行)

一、环境准备 docker 二、步骤 运行verdaccio docker run -d --name verdaccio -p 4873:4873 --restartalways该命令执行完,一个本地的npm仓库就基本搭建好了,可以浏览器访问http://localhost:4873/ 查看,效果如下: 效果出是…

教你接入Midjourney,不用梯子也能玩

1、效果 话不多说,先上最终出图效果, 我给的关键词是一只白色的猫 2、接入流程 API文档可以来这里查(可以白嫖100次midjourney出图和10次gpt4体验),我这里精简一下接入流程,方便大家快速接入 2.1、文字生…

JDK源码怎么学?看这篇文章就够了!

最近后台收到很多粉丝私信,说的是程序员究竟要不要去读源码?当下行情,面试什么样的薪资/岗位才会被问到源码? 对此,我的回答是:一定要去读,并且要提到日程上来! 据不完全统计&…

远程访问群晖Drive并挂载为电脑磁盘同步备份文件「无需公网IP」

文章目录 前言视频教程1.群晖Synology Drive套件的安装1.1 安装Synology Drive套件1.2 设置Synology Drive套件1.3 局域网内电脑测试和使用 2.使用cpolar远程访问内网Synology Drive2.1 Cpolar云端设置2.2 Cpolar本地设置2.3 测试和使用 3. 结语 转发自CSDN远程穿透的文章&…

ARM的数据处理指令、跳转指令与储存器访问指令

最开始在此介绍一下CPSR寄存器中 N、Z、C、V 4位的作用: Bit[28](V): 当运算器中进行加法运算且产生符号位进位时该位自动置1,否则为0 当运算器中进行减法运算且产生符号位借位时该位自动置0,否则为1 …

头歌计算机组成原理实验—运算器设计(6)第6关:5位无符号阵列乘法器设计

第6关:5位无符号阵列乘法器设计 实验目的 帮助学生掌握阵列乘法器的实现原理,能够分析阵列乘法器的性能,能在 Logisim 中绘制阵列乘法器电路。 视频讲解 实验内容 在 Logisim 中打开 alu.circ 文件,在5位阵列乘法器中实现斜向…

阿里云要分拆上市,腾讯云、百度云跟不跟?

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 十年磨一剑成就的阿里云开始兵行险招,在两年多来营收增速最低的一个财季,阿里云宣布开始分拆上市。 5月18日,阿里发布财报,在财报中宣布,阿里云将从阿里巴巴集团完…

[工具分享] 如何快速的添加海外客户的whatsApp和line进入通讯录

很多做外贸的朋友经常需要和海外的朋友联系,我们经常有时候需要添加海外客户的whatsApp和line等海外社交软件更好的与客户沟通,其他的App呢也是类似的,一下分享的方法 第一步、首先下载软件: 腾讯网盘:https://share.weiyun.com…

【已解决】grub引导项修复:Minimal BASH-like line editing is supported.

目录 1 问题背景2 问题探索3 问题解决4 告别Bug 1 问题背景 环境: Win10Ubuntu20.04 现象:双系统电脑向移动硬盘安装Ubuntu系统后,重启黑屏并显示Minimal BASH-like line editing is supported. For the first word, TAB lists possible comm…

入驻QQ一天就爆满,Midjourney中文版来了

目录 官方中文版上线,名额有限官方教程,详细可查社区内的优秀作品花式鼓励优秀创作者为你的创作保驾护航国内模式:当然少不了付费国内用户实现快速访问快去体验吧,「折腾没有消失,只是转移到了你的身上…」 国内用户终…

Windows环境下pcl点云库 安装配置全流程(精简、有效)

本文为Windows配置点云库pcl步骤,具体win10、visual studio 2019、pcl1.11.1。 目录 【1】下载安装包 【2】安装 2.1 先执行win64.exe 2.2 解压win64.zip 2.3 OpenNI2安装 【3】设置环境变量 【4】visual studio 项目实战 4.1 新建C空项目 4.2 包含目录 4…

c++STL—容器map/multimap

目录 1、map基本概念 1.1、简介 1.2、本质 1.3、优点 1.4、map和multimap区别 2、map构造和赋值 2.1、功能描述 2.2、函数原型 2.3、示例 3、map的大小和交换 3.1、功能描述 3.2、函数原型 3.3、示例 4、map插入和删除 4.1、功能描述 4.2、函数原型 4.3、示例…

【利用AI让知识体系化】解锁异步编程的新世界!

文章目录 I. 前言简介异步在计算机编程中的应用 II. 同步与异步定义与区别同步编程的缺点 III. 异步编程定义应用场景回调函数Promise对象async/await关键字事件循环 IV. 异步编程实例Node.js中使用异步编程异步HTTP请求实现异步文件操作 V. 异步编程的优势VI. 异步编程的挑战与…

Docker 运行 jenkins

概述 虚拟机启动Docker,运行Jenkins,进行代码拉取测试 实现功能: 1. 可链接外网 2. 可拉取仓库代码 3. 基本配置 部署 拉取镜像 docker search jenkins docker pull jenkins/jenkins 创建工作目录 # 创建目录 给工作挂载目录赋予权限 mk…

KingbaseES V8R6 数据库运维案例之 -- root用户securecmd连接'Permission denied'错误

案例分析: 在KingbaseES V8R6数据库在不支持ssh连接的系统环境,可以通过securecmdd服务建立主机之间的通讯,默认securecmdd服务建立用户之间的互信,通过publickey认证建立访问连接。在配置securecmdd服务后,默认kingba…

JavaScript实现计算1-100之间不能被7整除的数的和的代码

以下为实现计算1-100之间不能被7整除的数的和的程序代码和运行截图 目录 前言 一、实现计算1-100之间不能被7整除的数的和 1.1 运行流程及思想 1.2 代码段 1.3 JavaScript语句代码 1.4 运行截图 前言 1.若有选择,您可以在目录里进行快速查找; 2.…

【JavaWeb】--06.Filter、Listener、Ajax、Vue

文章目录 Filter1.概述2.快速入门2.1 开发步骤2.2 代码演示 3.Filter执行流程4. Filter拦截路径配置5.过滤器链5.1 概述5.2 代码演示5.3 问题 Listener1.概述2. 分类3.代码演示 Ajax1.概述1.1作用1.2 同步和异步 2.快速入门2.1 服务端实现2.2 客户端实现2.3 测试 3.axios3.1 基…

MVC 三层架构案例详细讲解

MVC 三层架构案例详细讲解 文章目录 MVC 三层架构案例详细讲解每博一文案1. MVC 概述2. MVC设计思想3. 三层架构4. MVC 与 三层架构的关系:5. 案例举例:用户账户转账5.1 M(Model :数据/业务处理层)5.2 C (Controller :…

软件测试实验:Web应用测试

目录 前言Web应用的特点实验目的实验内容实验要求实验过程系统测试用例系统测试执行记录系统测试缺陷报告 总结 前言 软件质量保证与测试技术实验是一门旨在培养学生掌握软件测试的基本理论和方法的课程。本实验主要涉及Web应用测试,包括以下几个方面:一…

Scala初学者指南

本文已收录至Github,推荐阅读 👉 Java随想录 文章目录 Scala跟Java的区别和联系Scala安装Scala中的数据类型Scala语法val和var泛型包导入包对象特质运算符传名参数implicitObject和Class样例类_(下划线)println集合ListMapRange 迭代器Tuple提取器对象流…