嵌入式驱动开发详解6(RTC)

文章目录

  • 前言
  • RTC简介
  • RTC驱动分析
    • RTC驱动框架
    • RTC驱动实现
  • RTC应用
  • 后续

前言

实时时钟是很常用的一个外设,通过实时时钟我们就可以知道年、月、日和时间等信息。 因此在需要记录时间的场合就需要实时时钟,可以使用专用的实时时钟芯片来完成此功能,但 是现在大多数的 MCU 或者 MPU 内部就已经自带了实时时钟外设模块。

RTC简介

STM32 内部有一个 RTC 外设模块,这个模块需要一个 32.768KHz 的晶振,对这个 RTC 模块进行初始化就可以得到一个实时时钟。I.MX6U 内部也有 个 RTC 模块,但是不叫作“RTC”,而是叫做“SNVS”,这一点要注意
SNVS 直译过来就是安全的非易性存储,SNVS 里面主要是一些低功耗的外设,包括一个 安全的实时计数器(RTC)、一个单调计数器(monotonic counter)和一些通用的寄存器。SNVS 里面的外设在芯片掉电以后由电池供电继续运行,这个纽扣电池就是在主电源关闭以后为 SNVS 供电的。

SNVS 分为两个子模块:SNVS_HP 和 SNVS_LP,也就是高功耗域(SNVS_HP)和低功耗域 (SNVS_LP),系统主电源断电以后SNVS_HP也会断电,但是在后备电源支持下,SNVS_LP 是不会断电的,而且SNVS_LP是和芯片复位隔离开的,因此SNVS_LP相关的寄存器的值会一直保存着。
在这里插入图片描述
①、VDD_HIGH_IN 是系统(芯片)主电源,这个电源会同时供给给 SNVS_HP 和 SNVS_LP。
②、VDD_SNVS_IN 是纽扣电池供电的电源,这个电源只会供给给 SNVS_LP,保证在系 统主电源 VDD_HIGH_IN 掉电以后 SNVS_LP 会继续运行。
③、SNVS_HP 部分。
④、SNVS_LP 部分,此部分有个 SRTC,这个就是我们本章要使用的 RTC。

其实不管是 SNVS_HP 还是 SNVS_LP,其内部都有一个 SRTC,但是因为 SNVS_HP 在系 统电源掉电以后就会关闭,所以我们使用的是 SNVS_LP内部的SRTC,不管是 SNVS_HP 里面的SRTC,还是 SNVS_LP 里面的 SRTC,其本质就是一个定时 器,SRTC需要外界提供一个32.768KHz 的时钟,寄存器 SNVS_LPSRTCMR 和 SNVS_LPSRTCLR 保存着秒数,直接读取这两个寄存 器的值就知道过了多长时间了。一般以 1970 年 1 月 1 日为起点,加上经过的秒数即可得到现在 的时间和日期,原理还是很简单的。SRTC 也是带有闹钟功能的,可以在寄存器 SNVS_LPAR 中 写入闹钟时间值,当时钟值和闹钟值匹配的时候就会产生闹钟中断,要使用时钟功能的话还需要进行一些设置。

RTC驱动分析

RTC驱动框架

Linux内核中的RTC设备不仅用于获取当前时间,还可以用于设置系统时间。内核提供了一套API,允许用户空间程序与RTC设备进行交互,实现时间的读取和设置。
RTC 设备驱动是一个标准的字符设备驱动,应用程序通过 open、release、read、write 和 ioctl 等函数完成对 RTC 设备的操作,如下图所示:
在这里插入图片描述
内核将 RTC 设备抽象为 rtc_device 结构体,定义在include/linux/rtc.h:

struct rtc_device
{struct device dev;struct module *owner;int id;char name[RTC_DEVICE_NAME_SIZE];const struct rtc_class_ops *ops;struct mutex ops_lock;struct cdev char_dev;unsigned long flags;…………
};

我们需要重点关注的是 ops 成员变量,这是一个 rtc_class_ops 类型的指针变量,定义在include/linux/rtc.h,rtc_class_ops 为 RTC 设备的最底层操作函数集合,包括从 RTC 设备中读取时间、向 RTC 设备写入新的时间值等。

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 函数操作集。之所以称之为通用,是因为二次开发的驱动是建立在这个通用字符设备驱动文件和linux内核的基础上开发的

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,
};

应用程序可以通过 ioctl 函 数来设置/读取时间、设置/读取闹钟的操作,那么对应的 rtc_dev_ioctl 函数就会执行, rtc_dev_ioctl 最终会通过操作 rtc_class_ops 中的 read_time、set_time 等函数来对具体 RTC 设备 的读写操作。具体的源码详细分析就不展示了,需要时可以自行查看。
字符设备的file_operations结构体设置好以后需要调用rtc_class_ops里的指针函数,但是rtc_class_ops的函数仅仅只是设置好了形式没有注册,因此需要将其注册到 Linux 内核中,这里我们可以使用 rtc_device_register 函数完成注册工作,rtc_device_unregister 函数来注销注册的 rtc_device。

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

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

RTC驱动实现

一般情况下,内部 RTC 驱动都不需要我们去编写,半导体厂商会编写好,这里就只学习原厂已经写好的驱动是怎么写的,以NXP的imx6ull为例,分析驱动,先从设备树入手,打开 imx6ull.dtsi,在里面找到如下 snvs_rtc 设备节点,节点 内容如下所示:

/{soc{aips1: aips-bus@2000000{snvs: snvs@020cc000 {compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";reg = <0x020cc000 0x4000>;snvs_rtc: snvs-rtc-lp {compatible = "fsl,sec-v4.0-mon-rtc-lp";regmap = <&snvs>;offset = <0x34>;interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 20 		IRQ_TYPE_LEVEL_HIGH>;};};}};
};

通过兼容属性 compatible 的值“fsl,sec-v4.0-mon-rtc-lp”可以在Linux内核源码中搜索到对应的驱动文件,此文件为 drivers/rtc/rtc-snvs.c,如下所示,可以看出该驱动对应的也是platform架构:

static const struct of_device_id snvs_dt_ids[] = {{ .compatible = "fsl,sec-v4.0-mon-rtc-lp", },{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, snvs_dt_ids);static struct platform_driver snvs_rtc_driver = {.driver = {.name	= "snvs_rtc",.pm	= SNVS_RTC_PM_OPS,.of_match_table = snvs_dt_ids,},.probe		= snvs_rtc_probe,
};

在.snvs_rtc_probe函数中,主要做了以下几个事件,代码就不在展示了:

  • platform_get_resource 函数从设备树中获取到 RTC 外设寄存器基地址
  • devm_ioremap_resource 完成内存映射,得到 RTC 外设寄存器物理基 地址对应的虚拟地址
  • devm_regmap_init_mmio 函数将 RTC 的硬件寄存器转化为 regmap 形式,这样 regmap 机制的 regmap_write、regmap_read 等 API 函数才能操作寄存器。==具体有关regmap机制的说明后面会出相关笔记
  • 从设备树中获取 RTC 的中断号
  • 设置对应的寄存器
  • 用 snvs_rtc_enable 函数使能 RTC
  • devm_request_irq 函数请求 RTC 中断
  • devm_rtc_device_register 函数向系统注册 rtc_devcie,此函数会设置snvs_rtc_ops操作集
    最后需要原厂驱动开发人员把snvs_rtc_ops对应的函数完成:
static const struct rtc_class_ops snvs_rtc_ops = {.read_time = snvs_rtc_read_time,.set_time = snvs_rtc_set_time,.read_alarm = snvs_rtc_read_alarm,.set_alarm = snvs_rtc_set_alarm,.alarm_irq_enable = snvs_rtc_alarm_irq_enable,
};

RTC应用

  • 如果要查看时间的话输入“date”命令即可
date
  • RTC 时间设置也是使用的date命令,输入“date --help”命令即可查看 date 命令如何设置系统 时间,设置当前时间为 2019 年 8 月 31 日 18:13:00,因此输入如下命令:
date -s "2019-08-31 18:13:00"
  • “date -s”命令仅仅是将当前系统时间设置了,此时间还没有写入到 I.MX6U 内部 RTC 里面或其他的 RTC 芯片里面,因此系统重启以后时间又会丢失。我们需要将 当前的时间写入到 RTC 里面,这里要用到 hwclock 命令,输入如下命令将系统时间写入到 RTC 里面:
hwclock -w //将当前系统时间写入到 RTC 里面

后续

到这里对RTC的笔记记录大致结束了,后面有新的相关的重要的内容会继续进行更新。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是MAC地址?什么是IP地址?IP地址与MAC地址是什么关系?

MAC地址是指Media Access Control Address&#xff0c;媒体访问控制地址。MAC地址被烧录在网络设备的ROM之内&#xff0c; IP地址类似于门牌号码&#xff0c;有了门牌号码&#xff0c;邮差才知道把邮件投送到哪里。 有人新建房屋了&#xff0c;就会分配新的门牌号码&#xff08…

go语言的成神之路-标准库篇-os标准库

一、权限 在操作系统&#xff08;OS&#xff09;中&#xff0c;标准库的权限管理是非常重要的&#xff0c;它确保了不同用户和进程能够安全地访问系统资源。以下是一些常见的权限概念和说明&#xff1a; 1.用户权限 用户ID&#xff08;UID&#xff09;&#xff1a;每个用户在…

ASP.NET|日常开发中连接Sqlite数据库详解

ASP.NET&#xff5c;日常开发中连接Sqlite数据库详解 前言一、安装和引用相关库1.1 安装 SQLite 驱动1.2 引用命名空间 二、配置连接字符串2.1 连接字符串的基本格式 三、建立数据库连接3.1 创建连接对象并打开连接 四、执行数据库操作4.1 创建表&#xff08;以简单的用户表为例…

机器学习:监督学习、无监督学习

1. 引言 机器学习是一种人工智能领域的技术&#xff0c;它旨在让计算机通过学习数据和模式&#xff0c;而不是明确地进行编程来完成任务。 机器学习分为监督学习、无监督学习、半监督学习、强化学习 四种。 ​ 2. 监督学习 2.1 什么是监督学习 定义&#xff1a;根据已有的数…

IEEE T-RO 软体机器人手指状态估计实现两栖触觉传感

摘要&#xff1a;南方科技大学戴建生院士、林间院士、万芳老师、宋超阳老师团队近期在IEEE T-RO上发表了关于软体机器人手指在两栖环境中本体感知方法的论文。 近日&#xff0c;南方科技大学戴建生院士、林间院士、万芳老师、宋超阳老师团队在机器人顶刊IEEE T-RO上以《Propri…

MySQL-DML之数据表操作

文章目录 一. 插入表记录1. 向表中插入部分字段2. 向表中插入所有字段,字段的顺序为创建表时的顺序3. 一次添加多条数据信息 二. 更新表记录1. 更新所有记录的指定字段2. 更新符号条件记录的指定字段 三. 删除表记录1. 按条件删除记录2. 清空记录 四. SQL约束1. 主键约束① 添加…

Exp 智能协同管理系统前端首页框架开发

一、 需求分析 本案例的主要目标是开发一个智能学习辅助系统的前端界面&#xff0c;涵盖以下功能模块&#xff1a; 首页&#xff1a;显示系统的总体概览和关键功能介绍。 班级学员管理&#xff1a;实现班级管理和学员管理。 系统信息管理&#xff1a;管理部门和员工信息。 …

5G中的ATG Band

Air to Ground Networks for NR是R18 NR引入的。ATG很多部分和NTN类似中的内容类似。比较明显不同的是&#xff0c;NTN的RF内容有TS 38.101-5单独去讲&#xff0c;而ATG则会和地面网络共用某些band&#xff0c;这部分在38.101-1中有描述。 所以会存在ATG与地面网络之间的相邻信…

MongoDB与阿里云庆祝合作五周年,展望AI赋能新未来

12月3日&#xff0c;在印尼举行的阿里云合作伙伴大会2024上&#xff0c;MongoDB荣膺阿里云“2024技术创新成就奖”&#xff0c;该奖项旨在表彰与阿里云保持长期稳定合作&#xff0c;通过深度技术融合&#xff0c;在产品技术创新、行业区域深耕等领域取得卓越成就的伙伴。自2019…

未来已来:人工智能如何重塑我们的生活与工作

引言 未来的生活和工作场景正从想象走向现实。想象一下&#xff0c;一个清晨&#xff0c;语音助手已经为你安排好一天的任务&#xff0c;自动驾驶汽车准时送你上班&#xff0c;智能冰箱提醒你需要补充的食材。曾经只存在于科幻小说中的场景&#xff0c;如今正在我们的身边实现。…

苹果全家桶接入ChatGPT,近屿智能邀您共绘AI蓝图

北京时间12月12日凌晨&#xff0c;OpenAI开启了备受瞩目的第五天技术直播。宣布了一个令人振奋的消息&#xff1a;苹果的iPhone、iPad、Mac以及智能助手Siri可以原生使用ChatGPT。 这一合作无疑为生成式AI赛道注入了新的活力&#xff0c;作为全球科技行业的巨头&#xff0c;苹果…

企业级日志分析系统ELK之ELK概述

ELK 概述 ELK 介绍 什么是 ELK 早期IT架构中的系统和应用的日志分散在不同的主机和文件&#xff0c;如果应用出现问题&#xff0c;开发和运维人员想排 查原因&#xff0c;就要先找到相应的主机上的日志文件再进行查找和分析&#xff0c;所以非常不方便&#xff0c;而且还涉及…

安全攻击平台介绍

目录 XSS攻击平台 Attack API BeEF XSS-Proxy 漏洞平台 cnvd 阿里云漏洞库 攻防演练平台 XCTF 攻防平台 零日靶场&#xff08;0ops&#xff09; 安恒靶场&#xff08;赛宁安全&#xff09; XSS攻击平台 XSS Payload如此强大&#xff0c;为了使用方便&#xff0c;有安…

计算机毕业设计Python+Vue.js游戏推荐系统 Steam游戏推荐系统 Django Flask 游 戏可视化 游戏数据分析 游戏大数据 爬虫 机

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

【电机控制器】FM33LF015芯片——FLASH模拟EEPROM

【电机控制器】FM33LF015芯片——FLASH模拟EEPROM 文章目录 [TOC](文章目录) 前言一、概述二、代码三、实验四、参考资料总结 前言 使用工具&#xff1a; 1.ARM仿真器/J-OBV2仿真器 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、概述 二、代码 …

算法日记48 day 图论(拓扑排序,dijkstra)

今天继续图论章节&#xff0c;主要是拓扑排序和dijkstra算法。 还是举例说明。 题目&#xff1a;软件构建 117. 软件构建 (kamacoder.com) 题目描述 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件…

物联网安全-ARMv8-M Trustzone 实操

前言 本文针对ARMv8m架构M23/M33 MCU安全特性使用进行介绍,以nxp LPC55xx系列和STM32L5xx系列为例,为大家阐述如何使用Trustzone技术提高物联网设备安全性,适合有一定平台安全基础的物联网设备开发人员、安全方案开发人员。 背景 为了提升平台安全性,ARM推出了ARMv8m架构…

若依集成Uflo2工作流引擎

文章目录 1. 创建子模块并添加依赖1.1 新建子模块 ruoyi-uflo1.2 引入 Uflo2 相关依赖 2. 配置相关 config2.1 配置 ServletConfig2.2 配置 UfloConfig2.3 配置 TestEnvironmentProvider 3. 引入Uflo配置文件4. 启动并访问 Uflo2 是由 BSTEK 自主研发的一款基于 Java 的轻量级工…

linux启动流程

linux 启动详细流程 启动流程主要分为四个阶段&#xff1a;BIOS与UEFI->bootloader->kernel->busybox()init,下面从这四个方面展开 BIOS与UEFI 由于计算机启动是一个很矛盾的过程&#xff0c;即必须先运行程序&#xff0c;然后计算机才能启动&#xff0c;但是计算机不…

基于Qwen2-VL模型针对LaTeX OCR任务进行微调训练 - 多图推理

基于Qwen2-VL模型针对LaTeX OCR任务进行微调训练 - 多图推理 flyfish 基于Qwen2-VL模型针对LaTeX_OCR任务进行微调训练_-_LoRA配置如何写 基于Qwen2-VL模型针对LaTeX_OCR任务进行微调训练_-_单图推理 基于Qwen2-VL模型针对LaTeX_OCR任务进行微调训练_-_原模型_单图推理 基于Q…