嵌入式驅動開發詳解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.pswp.cn/web/62741.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62741.shtml
英文地址,請注明出處:http://en.pswp.cn/web/62741.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

單片機:實現跑馬燈(附帶源碼)

單片機實現跑馬燈 跑馬燈&#xff08;也稱作流水燈&#xff09;是一種常見的電子效果&#xff0c;通過依次點亮和熄滅多個LED燈&#xff0c;模擬出一個燈光流動的效果。跑馬燈常見于裝飾性電子產品中&#xff0c;也是一種展示單片機控制多路輸出的基礎應用。 在本項目中&…

力扣題目 - 935. 騎士撥號器

題目 還需要你前往力扣官網查看詳細的題目要求 地址 1.象棋騎士有一個獨特的移動方式&#xff0c;它可以垂直移動兩個方格&#xff0c;水平移動一個方格&#xff0c;或者水平移動兩個方格&#xff0c;垂直移動一個方格(兩者都形成一個 L 的形狀)。2.象棋騎士可能的移動方式如下…

傳輸層7——TCP擁塞控制(重點!!!)

目錄 一、認識擁塞控制 1、什么叫做擁塞&#xff1f; 2、擁塞的特點 3、流量控制 VS 擁塞控制 二、TCP如何防止擁塞&#xff1f; 1、慢開始 2、擁塞避免 3、3重復確認 和 快重傳算法 4、快恢復算法 5、總結 三、主動隊列管理AQM 1、技術背景 2、AQM思 想和實現策略…

PostgreSQL/PostGIS中提升空間查詢(分析)性能(效率)的一些方法

目錄 1. 使用適當的索引 1.1 索引類型 1.2 分析查詢計劃 1.3 覆蓋索引 1.4 復合索引 1.5 維護索引 1.6 刪除不必要的索引 1.7 使用適當的數據類型 2. 建立分區表 2.1 分區表的基本概念 2.2 創建分區表的步驟 2.3 空間數據的分區 2.4 分區表優點 3. 簡化幾何形狀 …

輪播(css+js)

目錄 1.實現效果 2.基礎代碼演示 2.1js代碼 2.1css樣式 2.3實現效果 3.實現點擊切換 3.1給button添加點擊事件 3.2效果圖如下 3.3發現問題 3.3.1不循環 3.3.2循環 1.實現效果 2.基礎代碼演示 2.1js代碼 <div class"out-box"><div class"tes…

簡單的JavaWeb開發示例

以下是一個簡單的JavaWeb開發示例&#xff0c;包含一個使用Servlet和JSP實現的簡單網頁計數器功能&#xff0c;展示了基本的JavaWeb項目結構以及相關代碼邏輯。 1. 項目搭建與環境準備 開發工具&#xff1a;可以使用Eclipse、IntelliJ IDEA等集成開發環境&#xff0c;這里以I…

fastadmin框架同時使用 阿里云oss和阿里云點播

背景 項目的實際需求中既要用到阿里云oss產品又用到阿里云點播系統&#xff0c;實現完美的統一。設置兩個地址downUrl&#xff0c;thirdCode。分別代表阿里云oss上傳路徑和阿里云點播系統vId。 實現 默認框架你已經集成好阿里云oss集成工作&#xff0c;前端html頁面實現 <…

優秀的3d建模是數據可視化的視覺核心1

增強視覺效果&#xff1a;3D建模通過創建三維立體圖像&#xff0c;為觀眾提供了更為真實和直觀的視覺體驗。相比于傳統的二維圖表和圖形&#xff0c;3D模型能夠更準確地展示復雜數據之間的空間關系&#xff0c;使數據可視化大屏上的信息更加生動和易于理解。 提升信息傳達效率&…

flink sink kafka的事務提交現象猜想

現象 查看flink源碼時 sink kafka有事務提交機制&#xff0c;查看源碼發現是使用兩階段提交策略&#xff0c;而事務提交是checkpoint完成后才執行&#xff0c;那么如果checkpoint設置間隔時間比較長時&#xff0c;事務未提交之前&#xff0c;后端應該消費不到數據&#xff0c…

leetcode 3224. 使差值相等的最少數組改動次數

題目鏈接&#xff1a;3224. 使差值相等的最少數組改動次數 題目&#xff1a; 給你一個長度為 n 的整數數組 nums &#xff0c;n 是偶數 &#xff0c;同時給你一個整數 k 。 你可以對數組進行一些操作。每次操作中&#xff0c;你可以將數組中任一元素替換為 0 到 k 之間的任一…

Y3編輯器文檔4:觸發器1(對話、裝備、特效、行為樹、排行榜、不同步問題)

文章目錄 一、觸發器簡介1.1 觸發器界面1.2 ECA語句編輯及快捷鍵1.3 參數設置1.4 變量設置1.5 實體觸發器1.6 函數庫與觸發器復用 二、觸發器的多層結構2.1 子觸發器&#xff08;在游戲內對新的事件進行注冊&#xff09;2.2 觸發器變量作用域2.3 復合條件2.4 循環2.5 計時器2.6…

前端WebSocket應用——聊天實時通信的基本配置

使用 WebSocket 實現實時通信的 Vue 應用 前言1. WebSocketService 類 1.1 類屬性1.2 構造函數和連接初始化1.3 WebSocket 連接1.4 事件處理方法1.5 發送和關閉 WebSocket 消息1.6 狀態查詢與回調注冊1.7 完整代碼 2. 在 Vue 組件中使用 WebSocketService 2.1 定義 WebSocket …

【開源】A065—基于SpringBoot的庫存管理系統的設計與實現

&#x1f64a;作者簡介&#xff1a;在校研究生&#xff0c;擁有計算機專業的研究生開發團隊&#xff0c;分享技術代碼幫助學生學習&#xff0c;獨立完成自己的網站項目。 代碼可以查看項目鏈接獲取??&#xff0c;記得注明來意哦~&#x1f339; 贈送計算機畢業設計600個選題ex…

基于python實現自動化的驗證碼識別:探索與實踐

基于python實現自動化的驗證碼識別&#xff1a;探索與實踐 一、驗證碼的類型及特點&#xff08;一&#xff09;圖像驗證碼&#xff08;二&#xff09;短信驗證碼&#xff08;三&#xff09;語音驗證碼 二、驗證碼識別的方法*&#xff08;一&#xff09;傳統圖像處理方法&#x…

Vue vs. React:兩大前端框架的深度對比與分析(一)

前言 在當今快速發展的前端領域中&#xff0c;Vue和React作為兩個備受矚目的前端框架&#xff0c;已經成為許多開發者的首選。這兩個框架憑借其出色的設計和強大的功能&#xff0c;在構建現代化、高效性能的Web應用方面扮演著重要角色。 Vue和React都以其獨特的特點吸引了眾多開…

windows安裝使用conda

在Windows系統上安裝和使用Conda的詳細步驟如下&#xff1a; 一、下載Conda安裝包 訪問Conda的官方網站Anaconda | The Operating System for AI&#xff0c;點擊“Downloads”按鈕。在下載頁面&#xff0c;選擇適合您系統的安裝包。通常&#xff0c;對于Windows系統&#xf…

websocket 服務 pinia 全局配置

websocket 方法類 // stores/webSocketStore.ts import { defineStore } from "pinia";interface WebSocketStoreState {ws: WebSocket | null; // WebSocket 實例callbacks: ((message: string) > void)[]; // 消息回調函數列表connected: boolean; // 連接狀態…

Ariba Procurement: Administration_Cloud Basics

# SAP Ariba Procurement: Administration_Cloud Basics 認識Ariba Cloud SAP Ariba Procurement 是一個云計算平臺… The Ariba Cloud 平臺需要簡單理解的概念: Datacenter數據中心:SAP Ariba在世界各地有許多數據中心。這些數據中心構成了Ariba云的基本物理基礎設施。 …

vulnhub靶場【shenron】--1

前言 靶機&#xff1a;shenron-1 攻擊&#xff1a;kali 都采用虛擬機&#xff0c;網卡為橋接模式 主機發現 使用arp-scan -l或netdiscover -r 192.168.1.1/24掃描 信息收集 使用nmap掃描端口 網站信息探測 查看頁面&#xff0c;發現是apache2的默認界面&#xff0c;查看…

等保2.0數據庫測評之SQL server數據庫測評

一、SQL server數據庫介紹 SQL server美國Microsoft公司推出的一種關系型數據庫系統。SQL Server是一個可擴展的、高性能的、為分布式客戶機/服務器計算所設計的數據庫管理系統。 本次安裝環境為Windows10專業版操作系統&#xff0c;數據庫版本為Microsoft SQL Server 2019 (…