OpenVela之 Arch Timer 驅動框架使用指南

一、概述

在嵌入式系統開發中,定時器是實現任務調度、精確延時等功能的核心組件。Arch Timer 作為基于 Timer Driver 實現的間隔定時器,在系統調度中扮演著重要角色。本文將全面介紹 Arch Timer 驅動框架,從基本概念到實際應用,幫助開發者快速掌握其使用與開發技巧。

二、認識 Arch Timer

1. 什么是 Arch Timer

Arch Timer 是基于 Timer Driver 實現的間隔定時器,為操作系統的 sched 模塊提供了豐富的 timer 接口。它支持兩種工作模式,以滿足不同場景的需求:

  • Tickless 模式:允許更靈活高效的系統調度,無周期性時鐘中斷,系統在無任務執行時進入空閑模式,有效降低功耗。
  • Tick 模式:提供固定時間間隔的調度機制,按照配置的固定周期運行,保證周期性任務的穩定執行。

Arch timer 在系統中的位置框架如下圖所示:
在這里插入圖片描述

2. Arch Timer 的驅動框架

Arch Timer 的驅動框架分為 upper - half 和 lower - half 兩部分:

  • upper - half 部分:由 openvela 提供,其中 up_timer_initialize 接口需由芯片廠商實現。
  • lower - half 部分:需芯片廠商進行適配,實現硬件級別的控制。

應用程序可通過標準的 POSIX API 接口或 ioctl 接口,調用這兩部分的接口來完成相應功能。
在這里插入圖片描述

三、Arch Timer 接口詳解

sched 模塊依賴于 arch 模塊提供的定時器接口,這些接口定義在 /include/nuttx/arch.h 頭文件中。在 Tickless 模式下,接口按時間單位分為基于微秒(us)和基于計時單元(tick)的兩組,開發者可通過配置選項 CONFIG_SCHED_TICKLESS_TICK_ARGUMENT 選擇啟用哪一組。默認支持 tick 接口以確保運行效率,部分主要接口如下:

Arch Timer 接口說明

接口名稱功能描述
up_timer_set_lowerhalf初始化 Arch Timer 定時器,設置一個 timer_lowerhalf_s 實例,并啟動定時器
up_timer_tick_start啟動定時器,僅在 Tickless 模式下使用,參數為超時時間(單位:tick)
up_timer_tick_cancel停止 Arch Timer 定時器,僅在 Tickless 模式中使用,返回當前剩余 tick 數
up_timer_getmask獲取定時器支持的時間掩碼(mask)的值
up_timer_gettick獲取定時器當前已經經過的 tick 數值
up_udelay實現以微秒(us)為單位的延時操作
up_mdelay實現以毫秒(ms)為單位的延時操作

四、Timer Driver 深入了解

1. 配置說明

啟用和調整 Timer Driver 功能需配置三個關鍵選項:

CONFIG_TIMER:啟用 Timer Driver 功能。
CONFIG_TIMER_ARCH:啟用 arch timer 模塊。
CONFIG_SCHED_TICKLESS:啟用 Tickless 模式。

相關配置文件路徑如下:

sched/Kconfig:包含 SCHED_TICKLESS 等相關配置。

# sched/Kconfig
config SCHED_TICKLESSdepends on ARCH_HAVE_TICKLESSconfig SCHED_TICKLESS_TICK_ARGUMENT
config SCHED_TICKLESS_LIMIT_MAX_SLEEP

drivers/timers/Kconfig:包含 TIMER 和 TIMER_ARCH 等配置。

# drivers/timers/Kconfig
config TIMER
......
if TIMER
config TIMER_ARCHselect ARCH_HAVE_TICKLESSselect ARCH_HAVE_TIMEKEEPINGselect SCHED_TICKLESS_LIMIT_MAX_SLEEP  if SCHED_TICKLESSselect SCHED_TICKLESS_TICK_ARGUMENT  if SCHED_TICKLESS
#endif

可通過以下命令檢查配置是否正確:

grep -rE "CONFIG_TIMER|CONFIG_TIMER_ARCH|CONFIG_ARCH_HAVE_TICKLESS|CONFIG_ARCH_HAVE_TIMEKEEPING|CONFIG_SCHED_TICKLESS_TICK_ARGUMENT|CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP" nuttx/.config

2. 初始化

在 board 初始化過程中,需調用具體廠商實現的 ***_timer_initialize 函數,完成分配并初始化 struct timer_lowerhalf_s 結構實例、注冊 Timer 驅動等操作,注冊后會生成 /dev/timer 設備節點,并綁定相關結構實例。

/***************************************************************************** Name: timer_register** Description:*   This function binds an instance of a "lower half" timer driver with the*   "upper half" timer device and registers that device so that can be used*   by application code.**   When this function is called, the "lower half" driver should be in the*   disabled state (as if the stop() method had already been called).**   NOTE:  Normally, this function would not be called by application code.*   Rather it is called indirectly through the architecture-specific*   initialization.** Input Parameters:*   dev path - The full path to the driver to be registered in the NuttX*     pseudo-filesystem.  The recommended convention is to name all timer*     drivers as "/dev/timer0", "/dev/timer1", etc.  where the driver*     path differs only in the "minor" number at the end of the device name.*   lower - A pointer to an instance of lower half timer driver.  This*     instance is bound to the timer driver and must persists as long as*     the driver persists.** Returned Value:*   On success, a non-NULL handle is returned to the caller.  In the event*   of any failure, a NULL value is returned.*****************************************************************************/FAR void *timer_register(FAR const char *path,FAR struct timer_lowerhalf_s *lower);

3. 上下層接口

  • upper - half 接口:主要供 sched 調用,根據配置可選擇以 struct timespec 或 tick 為單位的接口,減少時間轉換工作。

  • lower - half 接口:通過 struct timer_ops_s 提供標準化接口,供 upper - half、ioctl 系統調用等使用,按時間單位分為兩組,開發者可根據需求選擇實現,未實現的接口有默認實現。

struct timer_ops_s
{/* Required methods *******************************************************/CODE int (*start)(FAR struct timer_lowerhalf_s *lower);CODE int (*stop)(FAR struct timer_lowerhalf_s *lower);CODE int (*getstatus)(FAR struct timer_lowerhalf_s *lower,FAR struct timer_status_s *status);CODE int (*settimeout)(FAR struct timer_lowerhalf_s *lower,uint32_t timeout);CODE void (*setcallback)(FAR struct timer_lowerhalf_s *lower,CODE tccb_t callback, FAR void *arg);CODE int (*maxtimeout)(FAR struct timer_lowerhalf_s *lower,FAR uint32_t *maxtimeout);CODE int (*ioctl)(FAR struct timer_lowerhalf_s *lower, int cmd,unsigned long arg);CODE int (*tick_getstatus)(FAR struct timer_lowerhalf_s *lower,FAR struct timer_status_s *status);CODE int (*tick_setttimeout)(FAR struct timer_lowerhalf_s *lower,uint32_t timeout);CODE int (*tick_maxtimeout)(FAR struct timer_lowerhalf_s *lower,FAR uint32_t *maxtimeout);
};

五、調用流程解析

  1. Tickless 模式
  • 模式概述:sched 動態管理軟件定時器,選擇最短時長的定時器作為下一次超時時間,動態調用啟動或停止函數。
  • 調用流程:初始化定時器后,sched 計算超時時間,配置并啟動定時器,超時后觸發回調函數通知 sched,隨后重新分配時長并啟動下一個定時器或任務。

以下為 Tickless 模式下的調用流程圖

在這里插入圖片描述

  1. Tick 模式
  • 模式概述:sched 啟用固定時間間隔的周期性定時器,間隔由 CONFIG_USEC_PER_TICK 配置,系統初始化時啟動,無需頻繁調用啟動和停止接口。
  • 流程描述:初始化時啟動周期性定時器,按固定周期觸發事件,觸發調度器調度,保證周期性任務執行。

六、驅動適配實例

以 nrf52(基于 ARMv7 - M 架構)為例,驅動適配主要包括兩部分:

1. 實現 up_timer_initialize 接口

在平臺特定代碼中實現該接口,調用 timer_register 函數注冊定時器驅動,生成設備節點。初始化調用流程如下:

nx_start
-> clock_initialize-> up_timer_initialize      #開發者實現-> systick_initialize    #開發者實現-> timer_register-> up_timer_set_lowerhalf

以下為 systick_initialize 的實現參考:

struct timer_lowerhalf_s *systick_initialize(bool coreclk,unsigned int freq, int minor)
{struct systick_lowerhalf_s *lower =(struct systick_lowerhalf_s *)&g_systick_lower;.../* Register the timer driver if need */if (minor >= 0){char devname[32];sprintf(devname, "/dev/timer%d", minor);timer_register(devname, (struct timer_lowerhalf_s *)lower);}return (struct timer_lowerhalf_s *)lower;
}

2. 實現 lower - half 接口

通過定義 struct timer_ops_s 結構的實例,實現其中的方法,如 startstop 等,以控制硬件運行。

在 ARMv7-M 的 Arch Timer 適配中,lower-half 方法的出現形式如下:

文件路徑: arch/arm/src/armv7-m/arm_systick.c

/* "Lower half" driver methods */
static const struct timer_ops_s g_systick_ops =
{.start       = systick_start,.stop        = systick_stop,.getstatus   = systick_getstatus,.settimeout  = systick_settimeout,.setcallback = systick_setcallback,.maxtimeout  = systick_maxtimeout,
};

七、POSIX API 與測試實例

1. POSIX API

包括 timer_createtimer_deletetimer_settime 等接口,用于創建、刪除、配置定時器等操作。

  1. timer_create
/*
* 函數:timer_create
* 參數:clockid,定時類型;evp,sigevent結構體,用來指定定時器到期時如何相應
*       timerid,返回一個timerid
* 返回:0 success | -1 error
* 說明:創建一個定時器
*/
int timer_create(clockid_t clockid, FAR struct sigevent *evp,FAR timer_t *timerid);
  1. timer_delete
/*
* 函數:timer_delete
* 參數:timerid,執行timer_create返回的timerid
* 返回:0 success | -1 error
* 說明:刪除一個定時器
*/
int timer_delete(timer_t timerid);
  1. timer_settime
/* 設置定時器
* 函數:timer_settime
* 參數:timerid:id
*      flags:相對時間/絕對時間
*      value:定時時間和間隔
*      ovalue:若不為NULL,則返回上次定時的剩余到期時間 
* 返回:0 success | -1 error
* 說明:設置定時
*/
int timer_settime(timer_t timerid, int flags,FAR const struct itimerspec *value,FAR struct itimerspec *ovalue);

2. IOCTL 接口

應用級別的程序可以通過 ioctl 函數直接操作定時器(前提是在 bringup 過程中已注冊 /dev/timer 設備節點)。

支持的 IOCTL 命令

IOCTL 命令功能描述參數類型參數說明
TCIOC_START啟動定時器
TCIOC_STOP停止定時器
TCIOC_GETSTATUS獲取當前定時器的狀態struct timer_status_s*用于存儲定時器狀態信息的結構體指針
TCIOC_SETTIMEOUT設置定時器間隔時間(單位:微秒)32位無符號整數定時器的間隔時間值
TCIOC_NOTIFICATION設置定時器超時消息struct timer_notify_s*包含超時通知配置的結構體指針
TCIOC_MAXTIMEOUT獲取定時器支持的最大時延(單位:微秒)uint32_t*用于存儲最大時延值的指針

3. 測試實例

  1. TIMER API 測試:通過 cmocka 測試框架驗證 POSIX API 的工作,包括創建、配置、以及刪除定時器的全過程。

此部分介紹如何測試定時器相關功能,通過 cmocka 測試框架(可參考文檔:OpenVela之開發自測試框架cmocka進行cmocka相關配置)驗證 POSIX API 的工作,包括創建、配置、以及刪除定時器的全過程。

  • 代碼位置:apps/testing/drivertest/drivertest_posix_timer.c
  • 測試框架:cmocka
  • 依賴配置:
    • TESTING_CMOCKA
    • TESTING_DRIVER_TEST
    • CONFIG_SIG_EVTHREAD

在這里插入圖片描述

在這里插入圖片描述

  • 運行步驟:
  1. 啟用上述配置,并構建固件。
  2. 在 NuttShell(NSH)中運行以下命令:
nsh> cmocka_posix_timer

在這里插入圖片描述

  1. IOCTL 測試:通過 IOCTL 命令控制定時器設備,測試啟動、停止、設置間隔等功能。
  • 代碼路徑:apps/testing/drivertest/drivertest_timer.c
  • 測試框架:cmocka
  • 依賴配置:
    • TESTING_CMOCKA
    • TESTING_DRIVER_TEST

在這里插入圖片描述

在這里插入圖片描述

  • 測試步驟:
  1. 啟用依賴配置,并構建功能完整的固件。
  2. 在 NuttShell(NSH)中運行以下命令:
nsh> cmocka_driver_timer

在這里插入圖片描述

總結

Arch Timer 驅動框架為嵌入式系統提供了靈活高效的定時器解決方案,支持兩種工作模式,滿足不同調度需求。通過本文的介紹,相信開發者對其原理、接口、配置和應用有了全面的了解,能夠根據實際需求進行開發和適配,充分發揮其在系統調度中的作用。

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

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

相關文章

AAC編解碼

AAC(Advanced Audio Coding,高級音頻編碼)是一種基于心理聲學原理的有損音頻編解碼技術,廣泛應用于流媒體、數字廣播、移動音頻等場景。其編解碼流程圍繞 “保留人耳可感知信息、去除冗余” 設計,分為編碼(…

STM32 | HC-SR04 超聲波傳感器測距

模塊:HC-SR04感應角度:不大于15度 探測距離:2cm-450cm 高精度:可達0.3cmTrig:觸發信號,接收MCU發送的控制脈沖,MCU對應GPIO 設置為輸出Echo:反饋信號,向MCU發送數據…

【RTSP從零實踐】12、TCP傳輸H264格式RTP包(RTP_over_TCP)的RTSP服務器(附帶源碼)

😁博客主頁😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客內容🤑:🍭嵌入式開發、Linux、C語言、C、數據結構、音視頻🍭 🤣本文內容🤣&a…

【unitrix】 6.1 類型化整數特征(t_int.rs)

一、源碼 這段代碼定義了一個 Rust 特征(trait)TInt 和一些實現,用于表示類型化的整數。 use crate::number::{Null, B, Bit, TNumber};/// 類型化整數標記特征 /// /// 要求: /// - 實現 TNumber /// - 可復制 (Copy) /// - 默認…

速通LVS

一、LVS的使用lvs部署命令介紹lvs軟件相關信息:程序包:ipvsadm Unit File: ipvsadm.service 主程序:/usr/sbin/ipvsadm 規則保存工具:/usr/sbin/ipvsadm-save 規則重載工具:/usr/sbin/ipvsadm-restore 配置文件&#x…

Nginx,MD5和Knife4j

一、 Nginx: 項目網關與流量調度核心原理反向代理 (Reverse Proxy):在Web架構中,Nginx作為系統的統一入口(API網關),接收所有外部客戶端請求。它通過解析請求的URL路徑(location指令),判斷請求的…

多態,內部類(匿名內部類),常用API(1)

多態 什么是多態? 同一個對象在不同時刻表現出來的不同形態(多種形態) 例:Cat extends Animal 第一種形態:Cat c1 new Cat(); //c1是只貓 第二種形態:Animal c2 new Cat(); //c2是個動物 &#xff08…

Qt小組件 - 7 SQL Thread Qt訪問數據庫ORM

簡介網上關于Qt訪問數據庫的資料大多使用QSqlDatabase模塊。雖然這在C中尚可接受,但在Python中使用就顯得過于繁瑣了——不僅要手動編寫SQL語句,還與Python追求簡潔的理念背道而馳。在這里寫一個基于sqlalchemy的示例,也可以使用其他的ORM庫 …

使用Gin框架構建高并發教練預約微服務:架構設計與實戰解析

項目概述 技術棧 Web框架:Gin(高性能HTTP框架)數據存儲:Redis(內存數據庫,用于高并發讀寫) 項目結構 coach-booking-service ├── main.go # 程序入口,路由初始化&am…

深入拆解Spring第二大核心思想:AOP

什么是AOP Aspect Oriented Programming(面向切面編程) 什么是面向切面編程呢? 切?就是指某?類特定問題, 所以AOP也可以理解為面向特定方法編程. 什么是面向特定方法編程呢? 比如對于"登錄校驗", 就是?類特定問題. 登錄校驗攔截器, 就是…

linux服務器stress-ng的使用

安裝方法 ? Ubuntu/Debian:sudo apt update && sudo apt install stress-ng -y? CentOS/RHEL(需EPEL源):sudo yum install epel-release -ysudo yum install stress-ng -y? 源碼編譯(適合定制化需求&#x…

探索阿里云DMS:解鎖高效數據管理新姿勢

一、阿里云 DMS 是什么 阿里云 DMS,全稱為 Data Management Service,即數據管理服務 ,是一種集數據管理、結構管理、安全管理于一體的全面數據庫服務平臺。它能夠有效地支持各類數據庫產品,包括但不限于 MySQL、SQL Server、Post…

python爬取新浪財經網站上行業板塊股票信息的代碼

在這個多行業持續高速發展的時代,科技正在改變著我們的生活。 在世界科技領域中,中國正占據越來越重要的位置。當下,每個行業都提到了區塊鏈、人工智能、大數據、5G等科技力量,強調了科技在行業咨詢與數據分析領域的重要意義。 隨…

【JAVA】監聽windows中鼠標側面鍵的按鈕按下事件

監聽windows中鼠標側面鍵的按鈕按下事件用到的包核心類使用這個類用到的包 jna-5.11.0.jar jna-platform-5.11.0.jar核心類 package sample.tt.mouse;import com.sun.jna.Pointer; import com.sun.jna.platform.win32.*; import com.sun.jna.platform.win32.WinDef.HMODULE; …

Redis突發寫入阻斷?解析“MISCONF Redis is configured to save RDB…“故障處理

當你的Redis服務器突然拒絕寫入并拋出 MISCONF Redis is configured to save RDB snapshots... 錯誤時,別慌!這是Redis的數據安全保護機制在發揮作用。本文帶你深度解析故障根因,并提供完整的解決方案。🔥 故障現象還原 客戶端&am…

產品更新丨谷云科技 iPaaS 集成平臺 V7.6 版本發布

六月,谷云科技iPaaS集成平臺更新了V7.6版本。這次更新中我們著重對API網關、API編排、組織管理權限、API監控等功能進行了增強以及優化,一起來看看有什么新變化吧! 網關、監控、編排、組織權限全方位升級 1.API網關 錯誤碼預警,可…

圖像處理中的模板匹配:原理與實現

目錄 一、什么是模板匹配? 二、模板匹配的匹配方法 1. 平方差匹配(cv2.TM_SQDIFF) 2. 歸一化平方差匹配(cv2.TM_SQDIFF_NORMED) 3. 相關匹配(cv2.TM_CCORR) 4. 歸一化相關匹配&#xff08…

高性能架構模式——高性能NoSQL

目錄 一、關系數據庫的缺點二、常見的 NoSQL 方案分 類2.1、K-V 存儲2.2、文檔數據庫2.3、列式數據庫2.4、全文搜索引擎三、高性能 NoSQL 方案的典型特征和應用場景3.1、K-V 存儲典型特征和應用場景3.2、文檔數據庫典型特征和應用場景3.1.1、文檔數據庫的 no-schema 特性的優勢…

正確選擇光伏方案設計軟件:人力成本優化的關鍵一步

在競爭激烈的市場環境中,企業無不追求效率提升與成本控制。設計環節作為產品開發的核心流程,其效率高低直接影響整體項目進度與資源消耗。錯誤的設計軟件選擇如同在信息高速公路上設置路障——它不會阻止前行,卻會讓每一次溝通、每一次修改都…

Git問題排查與故障解決詳解

前言 在使用Git進行版本控制的過程中,開發者常常會遇到各種各樣的問題和錯誤。本文將詳細介紹常見的Git問題及其解決方法,幫助開發者快速定位和解決問題,避免在開發過程中浪費時間。 1. 基礎錯誤與解決 1.1 身份配置問題 問題&#xff1a…