精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux RTC開發指南

嵌入式Linux那些事 ? 來源:嵌入式Linux那些事 ? 作者:嵌入式Linux那些事 ? 2023-03-06 10:22 ? 次閱讀

Linux RTC 開發指南

1 概述

1.1 編寫目的

介紹Linux 內核中RTC 驅動的適配和DEBUG 方法,為RTC 設備的使用者和維護者提供參考。

1.2 適用范圍

內核版本 驅動文件
LINUX-4.9 及以上 RTC-SUNXI.C

1.3 相關人員

RTC 驅動及應用層的開發/維護人員。

2 模塊介紹

Linux 內核中,RTC 驅動的結構圖如下所示, 可以分為三個層次:

image-20221216114050541

接口層,負責向用戶空間提供操作的結點以及相關接口。 ? RTC Core, 為rtc 驅動提供了一套API, 完成設備和驅動的注冊等。 ? RTC 驅動層,負責具體的RTC 驅動實現,如設置時間、鬧鐘等設置寄存器的操作。

2.2 相關術語介紹

術語 解釋說明
Sunxi 指Allwinner 的一系列SoC 硬件平臺
RTC Real Time Clock,實時時鐘

2.3 源碼結構介紹

linux-4.9

└-- drivers

└-- rtc

|-- class.c

|-- hctosys.c

|-- interface.c

|-- rtc-dev.c

|-- rtc-lib.c

|-- rtc-proc.c

|-- rtc-sysfs.c

|-- systohc.c

|-- rtc-core.h

|-- rtc-sunxi.c

└-- rtc-sunxi.h

linux-5.4

└-- drivers

└-- rtc

|-- class.c

|-- hctosys.c

|-- interface.c

|-- dev.c

|-- lib.c

|-- proc.c

|-- sysfs.c

|-- systohc.c

|-- rtc-core.h

|-- rtc-sunxi.c

└-- rtc-sunxi.h

3 模塊配置介紹

3.1 kernel menuconfig 配置

3.1.1 linux-4.9 版本下

在命令行中進入內核根目錄(kernel/linux-4.9),執行make ARCH=arm64(arm) menuconfig(32 位系統為make ARCH=arm menuconfig) 進入配置主界面(linux-5.4 內核版本在longan 目錄下執行:./build.sh menuconfig 進入配置主界面),并按以下步驟操作: 首先,選擇Device Drivers 選項進入下一級配置,如下圖所示:

image-20221216114515324

選擇Real Time Clock,進入下級配置,如下圖所示:

image-20221216114527372

選擇Allwinner sunxi RTC,如下圖所示:

image-20221216114542981

由于在關機過程中,RTC 一般都是獨立供電的,因此在RTC 電源域中的寄存器不會掉電且RTC寄存器的值也不會恢復為默認值。利用此特性,Sunxi 平臺支持reboot 命令的一些擴展功能和 假關機功能,但需要打開support ir fake poweroff 和Sunxi rtc reboot Feature 選項,RTC驅動才能支持這些擴展功能。

3.1.2 linux-5.4 版本下

在命令行中進入longan 頂層目錄,執行./build.sh config,按照提示配置平臺、板型等信息(如果之前已經配置過,可跳過此步驟)。 然后執行./build.sh menuconfig,進入內核圖形化配置界面,并按以下步驟操作: 選擇Device Driver選項進入下一級配置,如下圖所示:

image-20221216114823615

選擇Real Time Clock進入下一級配置,如下圖所示:

image-20221216114840997

選擇Allwinner sunxi RTC配置,如下圖所示。

image-20221216114857679

由于在關機過程中,RTC 一般都是獨立供電的,因此在RTC 電源域中的寄存器不會掉電且RTC寄存器的值也不會恢復為默認值。利用此特性,Sunxi 平臺支持reboot 命令的一些擴展功能,但需要打開Sunxi rtc reboot flag和Sunxi rtc general register save bootcount選項,RTC 驅動才能支持這些擴展功能。

3.2 device tree 源碼結構和路徑

SoC 級設備樹文件(sun*.dtsi)是針對該SoC 所有方案的通用配置:

? 對于ARM64 CPU 而言,SoC 級設備樹的路徑為:arch/arm64/boot/dts/sunxi/sun*.dtsi

? 對于ARM32 CPU 而言,SoC 級設備樹的路徑為:arch/arm/boot/dts/sun*.dtsi

板級設備樹文件(board.dts)是針對該板型的專用配置:

? 板級設備樹路徑:device/config/chips/{IC}/configs/{BOARD}/board.dts

板級設備樹文件(board.dts)是針對該板型的專用配置: ? 板級設備樹路徑:device/config/chips/{IC}/configs/{BOARD}/board.dts

3.2.1 linux-4.9 版本下

device tree 的源碼結構關系如下:

board.dts

└--------sun*.dtsi

|------sun*-pinctrl.dtsi

└------sun*-clk.dtsi

3.2.2 linux-5.4 版本下

device tree 的源碼結構關系如下:

board.dts

└--------sun*.dtsi

3.3 device tree 對RTC 控制器的通用配置

3.3.1 linux-4.9 版本下

1 / {

2 rtc: rtc@07000000 {

3 compatible = "allwinner,sunxi-rtc"; //用于probe驅動

4 device_type = "rtc";

5 auto_switch; //支持RTC使用的32k時鐘源硬件自動切換

6 wakeup-source; //表示RTC是具備休眠喚醒能力的中斷喚醒源

7 reg = <0x0 0x07000000 0x0 0x200>; //RTC寄存器基地址和映射范圍

8 interrupts = ; //RTC硬件中斷號

9 gpr_offset = <0x100>; //RTC通用寄存器的偏移

10 gpr_len = <8>; //RTC通用寄存器的個數

11 gpr_cur_pos = <6>;

12 };

13 }

說明 對于linux-4.9 內核,當RTC 結點下配置auto_switch 屬性時,RTC 硬件會自動掃描檢查外部32k 晶體振蕩器的起振情 況。當外部晶體振蕩器工作異常時,RTC 硬件會自動切換到內部RC16M 時鐘分頻出來的32k 時鐘,從而保證RTC 工作正 常。當沒有配置該屬性時,驅動代碼中直接把RTC 時鐘源設置為外部32k 晶體的,當外部32K 晶體工作異常時,RTC 會工 作異常。因此建議配置上該屬性。

3.3.2 linux-5.4 版本下

1 / {

2 rtc: rtc@7000000 {

3 compatible = "allwinner,sun50iw10p1-rtc"; //用于probe驅動

4 device_type = "rtc";

5 wakeup-source; //表示RTC是具備休眠喚醒能力的中斷喚醒源

6 reg = <0x0 0x07000000 0x0 0x200>; //RTC寄存器基地址和映射范圍

7 interrupts = ; //RTC硬件中斷號

8 clocks = <&r_ccu CLK_R_AHB_BUS_RTC>, <&rtc_ccu CLK_RTC_1K>; //RTC所用到的時鐘

9 clock-names = "r-ahb-rtc", "rtc-1k"; //上述時鐘的名字

10 resets = <&r_ccu RST_R_AHB_BUS_RTC>;

11 gpr_cur_pos = <6>; //當前被用作reboot-flag的通用寄存器的序號

12 };

13 }

在Device Tree 中對每一個RTC 控制器進行配置, 一個RTC 控制器對應一個RTC 節點, 節點屬性的含義見注釋。

3.4 board.dts 板級配置

board.dts用于保存每個板級平臺的設備信息(如demo 板、demo2.0 板等等)。board.dts路徑如下:

device/config/chips/{IC}/configs/{BOARD}/boar d.dts

在board.dts中的配置信息如果在*.dtsi(如sun50iw9p1.dtsi等) 中存在,則會存在以下覆蓋規則:

在board.dts中的配置信息如果在*.dtsi(如sun50iw9p1.dtsi等) 中存在,則會存在以下覆蓋規則:

相同屬性和結點,board.dts的配置信息會覆蓋*.dtsi中的配置信息

新增加的屬性和結點,會添加到編譯生成的dtb 文件中

4 接口描述

RTC 驅動會注冊生成串口設備/dev/rtcN,應用層的使用只需遵循Linux 系統中的標準RTC 編程方法即可。

4.1 打開/關閉RTC 設備

使用標準的文件打開函數:

1 int open(const char *pathname, int flags); 2 int close(int fd);

需要引用頭文件:

1 #include 2 #include 3 #include 4 #include

4.2 設置和獲取RTC 時間

同樣使用標準的ioctl 函數:

1 int ioctl(int d, int request, ...);

需要引用頭文件:

1 #include 2 #include

5 模塊使用范例

此demo 程序是打開一個RTC 設備,然后設置和獲取RTC 時間以及設置鬧鐘功能。

1 #include /*標準輸入輸出定義*/ 2 #include /*標準函數庫定義*/ 3 #include /*Unix 標準函數定義*/ 4 #include 5 #include 6 #include /*文件控制定義*/ 7 #include /*RTC支持的CMD*/ 8 #include /*錯誤號定義*/ 9 #include 10 11 #define RTC_DEVICE_NAME "/dev/rtc0" 12 13 int set_rtc_timer(int fd) 14 { 15 struct rtc_time rtc_tm = {0}; 16 struct rtc_time rtc_tm_temp = {0}; 17 18 rtc_tm.tm_year = 2020 - 1900; /* 需要設置的年份,需要減1900 */ 19 rtc_tm.tm_mon = 11 - 1; /* 需要設置的月份,需要確保在0-11范圍*/ 20 rtc_tm.tm_mday = 21; /* 需要設置的日期*/ 21 rtc_tm.tm_hour = 10; /* 需要設置的時間*/ 22 rtc_tm.tm_min = 12; /* 需要設置的分鐘時間*/ 23 rtc_tm.tm_sec = 30; /* 需要設置的秒數*/ 24 25 /* 設置RTC時間*/ 26 if (ioctl(fd, RTC_SET_TIME, &rtc_tm) < 0) { 27 printf("RTC_SET_TIME failedn"); 28 return -1; 29 } 30 31 /* 獲取RTC時間*/ 32 if (ioctl(fd, RTC_RD_TIME, &rtc_tm_temp) < 0) { 33 printf("RTC_RD_TIME failedn"); 34 return -1; 35 } 36 printf("RTC_RD_TIME return %04d-%02d-%02d %02d:%02d:%02dn", 37 rtc_tm_temp.tm_year + 1900, rtc_tm_temp.tm_mon + 1, rtc_tm_temp.tm_mday, 38 rtc_tm_temp.tm_hour, rtc_tm_temp.tm_min, rtc_tm_temp.tm_sec); 39 return 0; 40 } 41 42 int set_rtc_alarm(int fd) 43 { 44 struct rtc_time rtc_tm = {0}; 45 struct rtc_time rtc_tm_temp = {0}; 46 47 rtc_tm.tm_year = 0; /* 鬧鐘忽略年設置*/ 48 rtc_tm.tm_mon = 0; /* 鬧鐘忽略月設置*/ 49 rtc_tm.tm_mday = 0; /* 鬧鐘忽略日期設置*/ 50 rtc_tm.tm_hour = 10; /* 需要設置的時間*/ 51 rtc_tm.tm_min = 12; /* 需要設置的分鐘時間*/ 52 rtc_tm.tm_sec = 30; /* 需要設置的秒數*/ 53 54 /* set alarm time */ 55 if (ioctl(fd, RTC_ALM_SET, &rtc_tm) < 0) { 56 printf("RTC_ALM_SET failedn"); 57 return -1; 58 } 59 60 if (ioctl(fd, RTC_AIE_ON) < 0) { 61 printf("RTC_AIE_ON failed!n"); 62 return -1; 63 } 64 65 if (ioctl(fd, RTC_ALM_READ, &rtc_tm_temp) < 0) { 66 printf("RTC_ALM_READ failedn"); 67 return -1; 68 } 69 70 printf("RTC_ALM_READ return %04d-%02d-%02d %02d:%02d:%02dn", 71 rtc_tm_temp.tm_year + 1900, rtc_tm_temp.tm_mon + 1, rtc_tm_temp.tm_mday, 72 rtc_tm_temp.tm_hour, rtc_tm_temp.tm_min, rtc_tm_temp.tm_sec); 73 return 0; 74 } 75 76 int main(int argc, char *argv[]) 77 { 78 int fd; 79 int ret; 80 81 /* open rtc device */ 82 fd = open(RTC_DEVICE_NAME, O_RDWR); 83 if (fd < 0) { 84 printf("open rtc device %s failedn", RTC_DEVICE_NAME); 85 return -ENODEV; 86 } 87 88 /* 設置RTC時間*/ 89 ret = set_rtc_timer(fd); 90 if (ret < 0) { 91 printf("set rtc timer errorn"); 92 return -EINVAL; 93 } 94 95 /* 設置鬧鐘*/ 96 ret = set_rtc_alarm(fd); 97 if (ret < 0) { 98 printf("set rtc alarm errorn"); 99 return -EINVAL; 100 } 101 102 close(fd); 103 return 0; 104 }

6 FAQ

6.1 RTC 時間不準

按照下圖RTC 時鐘源的路徑,確認一下RTC 所使用的時鐘源

image-20221216124213488

如果確認使用的時鐘源為RC16M,則確認一下有沒有啟用校準功能,因為RC16M 有正負50% 的偏差。

如果使用外部晶體,則確認一下外部晶體的震蕩頻率是否正確。

6.2 RTC 時間不走

請查看RTC 時鐘源圖,確認一下使用的時鐘源。

當RTC 時鐘源為外部32K 時,請確認一下外部32k 晶體的起振情況。

說明:當使用示波器測量外部32k 晶體起振情況時,有可能會導致32k 晶體起振。

當排查完時鐘源,確認時鐘源沒有問題后,通過以下命令dump rtc 相關寄存器,查看偏移0x0 寄存器的狀態位bit7 和bit8 是否異常置1 了,如下所示:

/ # echo 0x07000000,0x07000200 > /sys/class/sunxi_dump/dump; cat /sys/class/sunxi_dump/dump 0x0000000007000000: 0x00004010 0x00000004 0x0000000f 0x7a000000 0x0000000007000010: 0x00000001 0x00000023 0x00000000 0x00000000 0x0000000007000020: 0x00000000 0x00000000 0x00000000 0x00000000 0x0000000007000030: 0x00000000 0x00000000 0x00000000 0x00000000 0x0000000007000040: 0x00000000 0x00000000 0x00000000 0x00000000 0x0000000007000050: 0x00000001 0x00000000 0x00000000 0x00000000 0x0000000007000060: 0x00000004 0x00000000 0x00000000 0x00000000 0x0000000007000070: 0x00010003 0x00000000 0x00000000 0x00000000 0x0000000007000080: 0x00000000 0x00000000 0x00000000 0x00000000 0x0000000007000090: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000070000a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000070000b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000070000c0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000070000d0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000070000e0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000070000f0: 0x00000000 0x00000000 0x00000000 0x00000000 0x0000000007000100: 0x00000000 0x00000000 0x00000000 0x00000000 0x0000000007000110: 0x00000000 0x00000000 0x00000000 0x00000000 0x0000000007000120: 0x00000000 0x00000000 0x00000000 0x00000000 0x0000000007000130: 0x00000000 0x000030ea 0x04001000 0x00006061 0x0000000007000140: 0x00000000 0x00000000 0x00000000 0x00000000 0x0000000007000150: 0x00000000 0x00000000 0x00000000 0x00000000 0x0000000007000160: 0x083f10f7 0x00000043 0x00000000 0x00000000 0x0000000007000170: 0x00000000 0x00000000 0x00000000 0x00000000 0x0000000007000180: 0x00000000 0x00000000 0x00010001 0x00000000 0x0000000007000190: 0x00000004 0x00000000 0x00000000 0x00000000 0x00000000070001a0: 0x000090ff 0x00000000 0x00000000 0x00000000 0x00000000070001b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000070001c0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000070001d0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000070001e0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000070001f0: 0x00000000 0x00000001 0x00000000 0x00000000 0x0000000007000200: 0x10000000

說明:

每款SoC 的模塊首地址是不一樣的,具體根據spec 或data sheet 確認模塊首地址。

審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 模塊
    +關注

    關注

    7

    文章

    2671

    瀏覽量

    47340
  • 內核
    +關注

    關注

    3

    文章

    1363

    瀏覽量

    40228
  • Linux
    +關注

    關注

    87

    文章

    11229

    瀏覽量

    208927
  • 時鐘
    +關注

    關注

    10

    文章

    1720

    瀏覽量

    131364
  • RTC
    RTC
    +關注

    關注

    2

    文章

    528

    瀏覽量

    66310
收藏 人收藏

    評論

    相關推薦

    EAC0945 linux開發指南

    EAC0945 linux開發指南
    發表于 09-28 12:40

    EAC0945 linux開發指南

    `EAC0945 linux開發指南`
    發表于 10-31 12:18

    Rockchip Linux SDK uboot logo開發指南

    arm嵌入式vs-rk3399 板卡uboot logo 開發指南概述:本文檔主要介紹 rockchip linux sdk uboot logo 顯示的相關功能、配置以及開發過程中的注意事項。適用于 rockhip
    發表于 10-09 08:12

    CPLD FPGA高級應用開發指南

    CPLD FPGA高級應用開發指南
    發表于 04-15 10:56 ?58次下載
    CPLD FPGA高級應用<b class='flag-5'>開發指南</b>

    Tiny6410 Linux開發指南詳解

    Tiny6410 Linux 開發指南
    發表于 07-08 17:12 ?210次下載
    Tiny6410 <b class='flag-5'>Linux</b><b class='flag-5'>開發指南</b>詳解

    A64開發板LCD開發指南

    A64開發板LCD開發指南,驅動開發指南
    發表于 06-21 17:02 ?0次下載

    彩光燈開發指南

    彩光燈開發指南
    發表于 12-29 20:15 ?0次下載

    Linux的平臺下Mini210S裸機程序開發指南

    Linux的平臺下Mini210S裸機程序開發指南
    發表于 10-29 10:52 ?59次下載
    <b class='flag-5'>Linux</b>的平臺下Mini210S裸機程序<b class='flag-5'>開發指南</b>

    Rockchip Linux SDK的開發指南的詳細資料說明

    本文檔的主要內容詳細介紹的是Rockchip Linux SDK的開發指南的詳細資料說明。
    發表于 01-10 17:17 ?74次下載
    Rockchip <b class='flag-5'>Linux</b> SDK的<b class='flag-5'>開發指南</b>的詳細資料說明

    迅為RK3399開發板嵌入式linux開發指南

    迅為RK3399開發板嵌入式linux開發指南迅為RK3399開發板發布《北京迅為嵌入式linux開發指
    發表于 11-01 16:58 ?76次下載
    迅為RK3399<b class='flag-5'>開發</b>板嵌入式<b class='flag-5'>linux</b><b class='flag-5'>開發指南</b>

    nRF52832開發指南-下冊

    nRF52832開發指南-下冊
    發表于 06-16 14:14 ?44次下載

    Tina_Linux_系統軟件開發指南

    Tina_Linux_系統軟件開發指南
    的頭像 發表于 03-02 15:25 ?1775次閱讀
    Tina_<b class='flag-5'>Linux</b>_系統軟件<b class='flag-5'>開發指南</b>

    Tina Linux配置開發指南

    Tina Linux配置開發指南
    的頭像 發表于 03-02 15:28 ?1.6w次閱讀
    Tina <b class='flag-5'>Linux</b>配置<b class='flag-5'>開發指南</b>

    Linux NOR開發指南

    Linux NOR開發指南
    的頭像 發表于 03-06 09:55 ?924次閱讀
    <b class='flag-5'>Linux</b> NOR<b class='flag-5'>開發指南</b>

    【北京迅為】itop-龍芯2k1000開發指南Linux基礎入門vim 編輯器

    【北京迅為】itop-龍芯2k1000開發指南Linux基礎入門vim 編輯器
    的頭像 發表于 10-25 14:56 ?253次閱讀
    【北京迅為】itop-龍芯2k1000<b class='flag-5'>開發指南</b><b class='flag-5'>Linux</b>基礎入門vim 編輯器