開發一個RISC-V上的操作系統(七)—— 硬件定時器(Hardware Timer)

目錄

往期文章傳送門

一、硬件定時器

硬件實現

軟件實現

二、上板測試


往期文章傳送門

開發一個RISC-V上的操作系統(一)—— 環境搭建_riscv開發環境_Patarw_Li的博客-CSDN博客

開發一個RISC-V上的操作系統(二)—— 系統引導程序(Bootloader)_Patarw_Li的博客-CSDN博客

開發一個RISC-V上的操作系統(三)—— 串口驅動程序(UART)_Patarw_Li的博客-CSDN博客

開發一個RISC-V上的操作系統(四)—— 內存管理_Patarw_Li的博客-CSDN博客

開發一個RISC-V上的操作系統(五)—— 協作式多任務_Patarw_Li的博客-CSDN博客

開發一個RISC-V上的操作系統(六)—— 中斷(interrupt)和異常(exception)_Patarw_Li的博客-CSDN博客

本節的代碼在倉庫的?05_HW_TIMER?目錄下,倉庫鏈接:riscv_os: 一個RISC-V上的簡易操作系統

本文代碼的運行調試會在前面開發的RISC-V處理器上進行,倉庫鏈接:cpu_prj: 一個基于RISC-V指令集的CPU實現

一、硬件定時器

生活離不開對時間的管理,操作系統也是一樣。

時鐘節拍(Tick)

  • 操作系統中最小的時間單位。
  • Tick的單位(周期)由硬件定時器的周期決定(通常為1~100ms)。
  • Tick周期越小,系統精度越高,但開銷越大。

系統時鐘?

  • 操作系統維護一個整形計數值,記錄著系統啟動直到當前發生的Tick總數。

硬件實現

在本項目中,timer作為一個外設掛載在總線rib上,rtl文件為 cpu_prj\FPGA\rtl\perips\timer.v :?

五個讀寫信號用于讀寫timer模塊中的寄存器,信號?timer_int_flag_o 用于給 clint 中斷模塊發出中斷信號,verilog 代碼如下:

// 32bit 定時器
module timer(input   wire                        clk                 ,input   wire                        rst_n               ,// 讀寫信號    input   wire                        wr_en_i             , // write enableinput   wire[`INST_ADDR_BUS]        wr_addr_i           , // write addressinput   wire[`INST_REG_DATA]        wr_data_i           , // write datainput   wire[`INST_ADDR_BUS]        rd_addr_i           , // read addressoutput  reg [`INST_REG_DATA]        rd_data_o           , // read data// 中斷信號output  wire                        timer_int_flag_o    );localparam TIMER_CTRL = 4'h0;localparam TIMER_COUNT = 4'h4;localparam TIMER_EVALUE = 4'h8;// [0]: timer enable// [1]: timer int enable// [2]: timer int pending, software write 0 to clear it// addr offset: 0x00reg[31:0] timer_ctrl;// timer current count, read only// addr offset: 0x04reg[31:0] timer_count;// timer expired value// addr offset: 0x08reg[31:0] timer_evalue;assign timer_int_flag_o = ((timer_ctrl[2] == 1'b1) && (timer_ctrl[1] == 1'b1))? 1'b1 : 1'b0;// 讀寫寄存器,write before readalways @ (posedge clk or negedge rst_n) beginif (!rst_n) begintimer_ctrl <= `ZERO_WORD;timer_evalue <= `ZERO_WORD;endelse beginif (wr_en_i == 1'b1) begincase (wr_addr_i[3:0])TIMER_CTRL: begin// 這里代表軟件只能把 timer_ctrl[2]置0,無法將其置1timer_ctrl = {wr_data_i[31:3], (timer_ctrl[2] & wr_data_i[2]), wr_data_i[1:0]};endTIMER_EVALUE: begintimer_evalue = wr_data_i;endendcaseendif(timer_ctrl[0] == 1'b1 && timer_count >= timer_evalue) begintimer_ctrl[0] = 1'b0;timer_ctrl[2] = 1'b1;endcase (rd_addr_i[3:0])TIMER_CTRL: beginrd_data_o = timer_ctrl;endTIMER_COUNT: beginrd_data_o = timer_count;endTIMER_EVALUE: beginrd_data_o = timer_evalue;enddefault: beginrd_data_o = `ZERO_WORD;endendcaseendend// 計數器 timer_countalways @ (posedge clk or negedge rst_n) beginif (!rst_n) begintimer_count <= `ZERO_WORD;endelse beginif (timer_ctrl[0] != 1'b1 || timer_count >= timer_evalue) begintimer_count <= `ZERO_WORD;endelse begintimer_count <= timer_count + 1'b1;endendendendmodule

其中:

timer_ctrl?為控制寄存器,低三位有效,分別是第0位?timer enable ,置1則 timer_count 開始計時;第1位 timer int enable,置1則允許發出中斷信號,反之則不允許;第2位 timer int pending,當 timer_count >= timer_evalue 時,就把該位置1,表示有中斷信號要發出,需要軟件置0。

timer_count 為計數寄存器(只讀)。

timer_evalue 存放過期值,用來與?timer_count 寄存器比較,當 timer_count >= timer_evalue 時則發出中斷信號。

軟件實現

代碼實現為 riscv_os/05_HW_TIMER/timer.c :

// 1s
#define TIMER_INTERVAL 50000000/** The TIMER control registers are memory-mapped at address TIMER (defined in inc/platform.h). * This macro returns the address of one of the registers.*/
#define TIMER_REG_ADDRESS(reg) ((volatile uint32_t *) (TIMER + reg))/** TIMER registers map* timer_count is a read-only reg*/
#define TIMER_CTRL      0
#define TIMER_COUNT     4
#define TIMER_EVALUE    8#define timer_read_reg(reg) (*(TIMER_REG_ADDRESS(reg)))
#define timer_write_reg(reg, data) (*(TIMER_REG_ADDRESS(reg)) = (data))#define TIMER_EN          1 << 0
#define TIMER_INT_EN      1 << 1
#define TIMER_INT_PENDING 1 << 2static uint32_t _tick = 0;void timer_load(uint32_t interval)
{timer_write_reg(TIMER_EVALUE, interval);timer_write_reg(TIMER_CTRL, (timer_read_reg(TIMER_CTRL) | (TIMER_EN)));
}/** enable timer interrupt*/
void timer_init()
{timer_write_reg(TIMER_CTRL, (timer_read_reg(TIMER_CTRL) | (TIMER_INT_EN)));timer_load(TIMER_INTERVAL);
}void timer_handler()
{timer_write_reg(TIMER_CTRL, (timer_read_reg(TIMER_CTRL) & ~(TIMER_INT_PENDING)));_tick++;printf("tick: %d\n", _tick);timer_load(TIMER_INTERVAL);
}

其中:

_tick?為該模塊維護的全局時間節拍。

timer_load(uint32_t interval) 函數用于給定時器模塊寄存器賦值,interval 個硬件時鐘周期后發出定時器中斷(如果 interval = 板子系統時鐘頻率,相當于1s)。

timer_init() 函數用于給定時器模塊寄存器初始化。

timer_handler() 函數用于執行定時器中斷處理,當定時器中斷發生的時候,執行這個函數的內容。該函數會將 _tick 值加一后,執行 timer_load(uint32_t interval) 函數,從而達到持續計數的功能。

二、上板測試

燒錄到板子上后,打開串口調試程序,可以看到tick值一直在計數,從而實現系統時鐘的功能:

遇到問題歡迎加群 892873718 交流~?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/35573.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/35573.shtml
英文地址,請注明出處:http://en.pswp.cn/news/35573.shtml

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

相關文章

AD域機器KMS自動激活

1、打開AD域控&#xff0c;點擊DNS管理 2、創建其它記錄 3、選擇服務位置 SRV 4、輸入相關信息 服務&#xff1a;_VLMCS協議&#xff1a;_TCP權重&#xff1a;100端口號&#xff1a;1688KMS服務器地址&#xff1a;10.3.0.211 5、成功&#xff0c;這時域內主機重啟后&#xff0…

騰訊云CVM服務器2核2g1m帶寬支持多少人訪問?

騰訊云2核2g1m的服務器支持多少人同時訪問&#xff1f;2核2g1m云服務器短板是在1M公網帶寬上&#xff0c;騰訊云服務器網以網站應用為例&#xff0c;當大規模用戶同時訪問網站時&#xff0c;很大概率會卡在公網帶寬上&#xff0c;所以壓根就談不上2核2G的CPU內存計算性能是否夠…

sql 執行的順序

在執行 SQL 查詢時&#xff0c;通常會按照以下順序進行處理&#xff1a; FROM 子句&#xff1a;指定要查詢的表或視圖。WHERE 子句&#xff1a;篩選滿足特定條件的行。GROUP BY 子句&#xff1a;將結果按照指定的列進行分組。HAVING 子句&#xff1a;篩選滿足特定條件的分組。…

燒寫PYNQ鏡像到SD卡

一&#xff0c;安裝 Win32diskimager 首先將Micro SD卡插入讀卡器的卡槽中&#xff0c;然后再將讀卡器插入計算機USB接口&#xff0c;此時計算機將會識別到插入的可移動磁盤。雙擊打開Win32DiskImager-1.0.0.zip 壓縮文件&#xff0c;里面win32diskimager-1.0.0-install.exe文…

Postman

Postman 簡介下載安裝 簡介 Postman 是一款用于測試和開發 API&#xff08;應用程序編程接口&#xff09;的工具&#xff0c;它提供了用戶友好的界面和豐富的功能&#xff0c;幫助開發者輕松地創建、測試、調試和文檔化各種類型的 API。無論是在構建 Web 應用、移動應用還是其…

“深入解析Maven:安裝、創建項目和依賴管理的完全指南“

目錄 引言Maven的安裝創建Maven項目之前的裝備工作Eclipse創建新的Maven項目項目依賴管理 總結 引言 Maven是一個流行的項目管理工具&#xff0c;被廣泛用于Java項目的構建、依賴管理和部署。它提供了一種簡單而強大的方式來管理項目的各個方面&#xff0c;使開發人員能夠更專…

LeetCode 1631. Path With Minimum Effort【最小瓶頸路;二分+BFS或DFS;計數排序+并查集;最小生成樹】1947

本文屬于「征服LeetCode」系列文章之一&#xff0c;這一系列正式開始于2021/08/12。由于LeetCode上部分題目有鎖&#xff0c;本系列將至少持續到刷完所有無鎖題之日為止&#xff1b;由于LeetCode還在不斷地創建新題&#xff0c;本系列的終止日期可能是永遠。在這一系列刷題文章…

阿里云PolarDB數據庫倚天ARM架構詳細介紹

阿里云云原生數據庫PolarDB MySQL版推出倚天ARM架構&#xff0c;倚天ARM架構規格相比X86架構規格最高降價45%&#xff0c;PolarDB針對自研倚天芯片&#xff0c;從芯片到數據庫內核全鏈路優化&#xff0c;助力企業降本增效。基于阿里云自研的倚天服務器&#xff0c;同時在數據庫…

誰能講清楚Spark之Spark系統架構

### 整體架構概述 Spark與Hadoop MapReduce的結構類似,Spark也采用Master-Worker結構。如果一個Spark集群由4個節點組成,即1個Master節點和3個Worker節點,那么在部署Standalone版本后,Spark部署的系統架構圖如圖2.1所示。簡單來說,Master節點負責管理應用和任務,…

【0day】復現廣聯達-Linkworks 協同辦公管理平臺GetUserByUserCode接口存在SQL注入漏洞

目錄 一、漏洞描述 二、影響版本 三、資產測繪 四、漏洞復現 一、漏洞描述 廣聯達科技股份有限公司成立于1998年,以建設工程領域專業應用為核心基礎支撐,以產業大數據、產業新金融等為增值服務的數字建筑平臺服務商。廣聯達-Linkworks 協同辦公管理平臺GetUserByUserC…

pytest fixture 用于teardown工作

fixture通過scope參數控制setup級別&#xff0c;setup作為用例之前前的操作&#xff0c;用例執行完之后那肯定也有teardown操作。這里用到fixture的teardown操作并不是獨立的函數&#xff0c;用yield關鍵字呼喚teardown操作。 舉個例子&#xff1a; 輸出&#xff1a; 說明&…

掌握Python的X篇_37_類的實例化、類方法

上篇我們已經學習了python中的類&#xff0c;并且學習到可以通過class關鍵字定義類&#xff0c;而類的最基本特性就是它是一個名稱空間&#xff0c;本篇將會學習類的實例化。 文章目錄 1. 類的實例化1.1__init__函數1.2 實例化流程 2. 類方法與成員 1. 類的實例化 上篇中新定義…

二十二、策略模式

目錄 1、項目需求2、傳統方案解決鴨子問題的分析和代碼實現3、傳統方式實現存在的問題分析和解決方案4、策略模式基本介紹5、使用策略模式解決鴨子問題6、策略模式的注意事項和細節7、策略模式的使用場景 以具體項目來演示為什么需要策略模式&#xff0c;策略模式的優點&#x…

貝銳蒲公英:快速搭建連鎖門店監控體系,賦能企業高效管理

隨著國民生活水平的提高和零售場景的變革&#xff0c;消費者對于餐飲類目的消費支出不斷增加&#xff0c;線下社區生鮮商超作為下沉市場最主要的消費場景之一&#xff0c;蘊藏著巨大價值機會。 對于線下連鎖生鮮超市而言&#xff0c;連鎖門店多、員工多&#xff0c;門店管理時會…

ubuntu磁盤管理

show partition information 掛載設備在這 顯示文件系統信息 build file system mkfs -t ext4 /dev/nvme0n1p4命令作用&#xff1a;將/dev/nvme0n1p4 格式化為 ext4 建立交換分區 mkswap -c -v1 /dev/nvme0n1p4 102400-c&#xff1a;check -v1&#xff1a;新版交換分區 -v0&…

安裝PaddleDetection-2.6.0版本-筆記

安裝PaddleDetection-2.6.0版本-筆記 一、第一步先激活環境 conda activate base conda activate base安裝完paddleDetection后要關閉conda激活環境 conda deactivate conda deactivate二、安裝PaddleDetection2.6.0版本 #pip install PaddleDet2.6.0 #切換版本可安裝pip i…

gitblit windows部署

1.官網下載 往死慢&#xff0c;我是從百度找的1.9.1&#xff0c;幾乎就是最新版 http://www.gitblit.com/ 2.解壓 下載下來是一個zip壓縮包&#xff0c;直接解壓即可 3.配置 3.1.配置資源庫路徑 找到data文件下的gitblit.properties文件&#xff0c;用Notepad打開 **注意路…

詳解編譯過程(編譯+鏈接)

翻譯環境&#xff1a; 編譯&#xff08;編譯器&#xff09;&#xff1a; 1.預編譯&#xff08;預處理&#xff09;&#xff1a; 最終生成test.i文件 【命令】&#xff1a;gcc test.c -E -O test.i 【包含過程】&#xff1a; 1.頭文件的包含 2.注釋的刪除 3.#define定義…

小程序具體開發

window 導航欄 屬性名類型默認值作用navigationBarTitleText string字字符串導航欄標題內容navigationBarBackgroundColorHexcolor#000000設置導航欄背景顏色&#xff08;比如熒黃色 #ffa&#xff09;navigationBarTextStylestringwhite設置導航欄標題的顏色&#xff08;僅含有…

通過將信號頻譜與噪聲頻譜進行比較,自動檢測適當的帶通濾波器轉折頻率研究(Matlab代碼實現)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;歡迎來到本博客????&#x1f4a5;&#x1f4a5; &#x1f3c6;博主優勢&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客內容盡量做到思維縝密&#xff0c;邏輯清晰&#xff0c;為了方便讀者。 ??座右銘&a…