rtthread - V5.1.0版本 HOOK 鉤子函數總結

rtthread - V5.1.0版本 鉤子函數 相對于V4.0.3版本做了很大的修改和優化:

舊版本 V4.0.3:

   rt_thread_inited_sethook(thread_inited_hook);rt_thread_deleted_sethook(thread_deleted_hook);rt_scheduler_sethook(scheduler_hook);

新版本 V5.1.0:

    rt_thread_inited_sethook(&init_hook_node);rt_object_detach_sethook(obj_detach_hook);rt_scheduler_sethook(scheduler_hook);

初始化鉤子 和 線程刪除鉤子

在RT-Thread V5.1.0版本中,刪除線程的回調鉤子函數(hook)機制主要圍繞宏定義配置:

// overflow hook
#define RT_USING_OVERFLOW_CHECK// hook list
#define RT_USING_HOOK
#define RT_HOOK_USING_FUNC_PTR
#define RT_USING_HOOKLIST// idle thread
#define RT_USING_IDLE_HOOK
#define RT_IDLE_HOOK_LIST_SIZE 4
#define IDLE_THREAD_STACK_SIZE 2048

函數實現:相關rtthread 單元測試例程:

我自己寫的項目應用, 初始化鉤子 和 線程刪除鉤子:

extern void rt_thread_inited_sethook(rt_thread_inited_hooklistnode_t node);static void thread_inited_hook(rt_thread_t thread)
{rt_kprintf("current thread name: [%s], Object created. \n", thread->parent.name);
}RT_OBJECT_HOOKLIST_DEFINE_NODE(rt_thread_inited, init_hook_node, thread_inited_hook);static void obj_detach_hook(struct rt_object *object)
{rt_kprintf("current thread name: [%s], Object deleted. \n", object->name);
}void hook_init(void)
{rt_thread_inited_sethook(&init_hook_node);rt_object_detach_sethook(obj_detach_hook);
}

線程創建時,會自動把hook鏈表進行初始化賦值,并在運行時檢測和滿足條件時調用鉤子函數:

棧溢出鉤子

宏定義配置:

/* 棧保護方式選擇(二選一) */
#define RT_USING_OVERFLOW_CHECK      // 啟用軟件棧溢出檢查(硬件保護不足時使用)
// #define RT_USING_HW_STACK_GUARD   // 啟用硬件棧保護(推薦)/* 棧生長方向配置(根據 CPU 手冊設置) */
#define ARCH_CPU_STACK_GROWS_UPWARD     // 棧向上生長:RAM低地址增長(如 ARM Cortex-M) 
// #undef ARCH_CPU_STACK_GROWS_UPWARD   // 棧向下生長(如 x86)

若選擇軟件棧溢出檢查,確保?rt_scheduler_stack_check?函數邏輯與棧生長方向一致:

空閑線程鉤子

1.?rt_thread_idle_sethook(void (*hook)(void))

作用
  • 注冊空閑線程鉤子函數:將用戶自定義的函數(hook)注冊到系統的空閑線程(idle thread)中。當系統進入空閑狀態(即所有高優先級任務都處于阻塞狀態)時,該鉤子函數會被自動調用。
使用場景
  • 后臺低優先級任務:執行對實時性要求不高的任務,例如:
    • 內存回收(如動態內存管理中的垃圾回收)。
    • 系統狀態監控(如CPU占用率統計)。
    • 低功耗模式處理(如進入睡眠模式前的準備工作)。
  • 調試與日志:在空閑時輸出系統運行日志或調試信息。
  • 自定義清理操作:如關閉未使用的外設、重置看門狗等。
示例代碼
void my_idle_hook(void) {
rt_kprintf("System is idle, performing background tasks...\n");
// 執行內存回收或其他操作
}
int main(void) {
// 注冊空閑鉤子
rt_thread_idle_sethook(my_idle_hook);
return 0;
}

2.?rt_thread_idle_delhook(void (*hook)(void))

作用
  • 刪除空閑線程鉤子函數:從空閑線程的鉤子函數列表中移除已注冊的hook函數。
使用場景
  • 動態管理鉤子函數:當某個后臺任務不再需要執行時(如臨時調試完成后),通過此函數移除鉤子以釋放資源。
  • 避免沖突:在系統配置變更或模塊卸載時,移除不再需要的鉤子函數。
示例代碼
// 刪除已注冊的鉤子
rt_thread_idle_delhook(my_idle_hook);

關鍵注意事項

  1. 非阻塞性:鉤子函數必須是非阻塞的,且執行時間盡可能短,否則會影響系統實時性。
  2. 多鉤子支持:RT-Thread允許注冊多個鉤子函數,按注冊順序依次執行。
  3. 線程安全:操作鉤子函數時需確保線程安全(如避免在中斷上下文中注冊/刪除鉤子)。
  4. 資源管理:若鉤子函數涉及動態內存或資源分配,需自行處理釋放邏輯。

典型應用場景

  • 內存管理:在空閑時回收動態內存碎片。
  • 低功耗優化:在空閑時關閉未使用的硬件模塊。
  • 系統監控:統計任務運行時間或檢測異常狀態。

鉤子注冊方式?-?插入代碼塊 和 函數指針

RT-Thread V5.1.0支持兩種鉤子注冊方式,編譯時插入代碼塊 優先級高于 函數指針方式

(1)接口注冊:函數指針方式(動態注冊)

  • 機制
    通過全局函數指針注冊鉤子,例如線程刪除時觸發:

// 聲明鉤子函數指針(object.c)
static void (*rt_object_detach_hook)(struct rt_object *object);// 注冊鉤子函數
void rt_object_detach_sethook(void (*hook)(struct rt_object *object)) {rt_object_detach_hook = hook;
}
  • 使用示例
    用戶需在代碼中調用rt_object_detach_sethook注冊回調:

void my_detach_hook(struct rt_object *obj) {// 自定義邏輯,如資源釋放
}// 初始化時注冊
rt_object_detach_sethook(my_detach_hook);

(2)錨點:編譯時插入代碼塊(精細控制)

  • 機制
    rtconfig.h中通過宏定義直接插入代碼到錨點位置,例如調度器鉤子:

// 定義錨點插入宏(rtconfig.h)
#define __on_rt_scheduler_hook(from, to) \my_scheduler_notifier(from, to)  // 替換為自定義函數// 需提前聲明函數原型
extern void my_scheduler_notifier(struct rt_thread *from, struct rt_thread *to);

(3)線程刪除與鉤子觸發

  • 刪除線程接口
    使用rt_thread_delete刪除線程時,系統會釋放資源并觸發相關鉤子:

    rt_err_t rt_thread_delete(rt_thread_t thread);
  • 鉤子觸發流程

    1. 線程刪除時調用rt_object_detach(內核對象分離)。
    2. 若配置了RT_USING_HOOK,觸發rt_object_detach_hook
    3. 若使用編譯時插入方式,執行用戶定義的代碼塊(如調度器切換通知)。
// rtconfig.h 中啟用鉤子并配置
#define RT_USING_HOOK
#define RT_HOOK_USING_FUNC_PTR  // 可選,啟用函數指針方式// 編譯時插入調度器鉤子(rtconfig.h)
#define __on_rt_scheduler_hook(from, to) \my_thread_delete_hook(from, to)extern void my_thread_delete_hook(struct rt_thread *from, struct rt_thread *to);

錨點位置__on_后面函數名字,是固定的和rtthread有關?還是任何名字都可以?

在 RT-Thread V5.1.0 中,錨點位置?__on_?后面的函數名字是固定的,與 RT-Thread 內核的預定義錨點名稱強相關。用戶不能隨意自定義該部分名稱,否則可能導致鉤子機制失效。

(1)錨點名稱的固定性

  • 內核預定義錨點
    RT-Thread 內核在關鍵代碼位置(如線程調度、對象操作等)預定義了錨點名稱,例如:

    // 調度器切換線程的錨點
    RT_DEFINE_HOOK(rt_scheduler_hook, void(struct rt_thread *from, struct rt_thread *to));

    這里的?rt_scheduler_hook?是內核定義的錨點名稱,用戶必須嚴格遵循此名稱。

  • 用戶宏定義規則
    用戶需在?rtconfig.h?中通過?#define __on_<錨點名稱>(參數列表)?的格式重定義錨點,例如:

    #define __on_rt_scheduler_hook(from, to) my_scheduler_notifier(from, to)

    其中?rt_scheduler_hook?必須與內核預定義的錨點名稱完全一致。

RT-Thread V5.1.0 錨點鉤子函數列表

錨點名稱用途配置示例
rt_scheduler_hook線程調度器切換線程時觸發#define __on_rt_scheduler_hook(from, to) my_scheduler_notifier(from, to)
rt_object_attach_hook內核對象(如線程、信號量)添加到對象管理器時觸發#define __on_rt_object_attach_hook(obj) my_obj_attach_hook(obj)
rt_object_detach_hook內核對象從對象管理器移除時觸發#define __on_rt_object_detach_hook(obj) my_obj_detach_hook(obj)
rt_object_trytake_hook線程嘗試獲取內核對象(如信號量)時觸發#define __on_rt_object_trytake_hook(obj) my_trytake_hook(obj)
rt_object_take_hook線程成功獲取內核對象后觸發#define __on_rt_object_take_hook(obj) my_take_hook(obj)
rt_object_put_hook線程釋放內核對象時觸發#define __on_rt_object_put_hook(obj) my_put_hook(obj)
rt_malloc_hook從堆內存分配內存塊時觸發#define __on_rt_malloc_hook(ptr, size) my_malloc_hook(ptr, size)
rt_free_hook釋放堆內存塊時觸發#define __on_rt_free_hook(ptr) my_free_hook(ptr)
rt_mp_alloc_hook從內存池分配內存塊時觸發#define __on_rt_mp_alloc_hook(mp, block) my_mp_alloc_hook(mp, block)
rt_mp_free_hook釋放內存池內存塊時觸發#define __on_rt_mp_free_hook(mp, block) my_mp_free_hook(mp, block)
rt_interrupt_enter_hook進入中斷時觸發#define __on_rt_interrupt_enter_hook() my_irq_enter_hook()
rt_interrupt_leave_hook退出中斷時觸發#define __on_rt_interrupt_leave_hook() my_irq_leave_hook()
rt_timer_timeout_hook定時器超時時觸發#define __on_rt_timer_timeout_hook(timer) my_timer_hook(timer)
rt_thread_inited_hook線程初始化完成后觸發#define __on_rt_thread_inited_hook(thread) my_thread_init_hook(thread)
rt_thread_suspend_hook線程掛起時觸發#define __on_rt_thread_suspend_hook(thread) my_suspend_hook(thread)
rt_thread_resume_hook線程恢復時觸發#define __on_rt_thread_resume_hook(thread) my_resume_hook(thread)

注意事項

  • 錨點名稱必須與內核定義一致,否則鉤子無法生效。
  • 插入宏優先級高于函數指針,同時使用時插入宏會覆蓋函數指針。
  • 避免在鉤子函數中執行阻塞操作(如?rt_thread_delay),否則可能導致系統異常。
  • 頭文件管理:建議在?rtconfig.h?中包含用戶鉤子頭文件,或通過編譯選項(如?-include user_hook.h)引入。

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

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

相關文章

Python特性:裝飾器解決數據庫長時間斷連問題

前言 在基于 Python 的 Web 應用開發里&#xff0c;數據庫連接是極為關鍵的一環。不過&#xff0c;像網絡波動、數據庫服務器維護這類因素&#xff0c;都可能造成數據庫長時間斷連&#xff0c;進而影響應用的正常運作。本文將詳細介紹怎樣運用 retry_on_failure 裝飾器來解決數…

療愈之手的智慧覺醒:Deepoc具身智能如何重塑按摩機器人的觸覺神經

療愈之手的智慧覺醒&#xff1a;Deepoc具身智能如何重塑按摩機器人的觸覺神經康復中心的理療室內&#xff0c;一位運動員正俯臥在治療床上。機械臂的硅膠觸頭沿腰背肌群緩緩移動&#xff0c;當傳感器捕捉到豎脊肌的異常僵直時&#xff0c;觸頭自動切換高頻震顫模式&#xff1b;…

webpack將組件vue進行編譯混淆,并能正常使用編譯之后的文件

介紹: 我們在開發的過程中有很多組件都需要復用,特別是我們耗費了好幾天時間寫出來的組件,比如自己寫的表格組件,流程圖組件等。總之都是自己不斷測試,不斷編寫耗費了大把的精力寫的。直接用到自己的項目中倒是無所謂,如果是把自己寫的組件給別人,這里就涉及到自己的勞動…

onenote千年老bug,字體bug (calibri微軟雅黑) 的解決

一、如何改這個bug&#xff08;bug是什么在后文&#xff09;一、注意1、有些onenote可能是版本問題&#xff0c;即使提供了設置默認字體的選項&#xff0c;但按教程設置后還是不work&#xff0c;建議升級版本2、親身測過這個方法是可行的&#xff0c;如果不行&#xff0c;考慮下…

麒麟信安參編的三項軟件供應鏈安全團體標準發布

日前&#xff0c;由中國電子商會正式發布了T/CECC 39—2025《信息安全技術 軟件供應鏈管理規范》、T/CECC 40—2025《信息安全技術 軟件供應鏈開源組件檢測要求》以及 T/CECC 41—2025《信息安全技術 軟件供應鏈軟件產品檢測要素和方法》三項重要團體標準。麒麟信安結合自身在軟…

Django ORM系統

1. ORM基礎概念1.1 什么是ORM&#xff1f;ORM&#xff08;Object Relational Mapping&#xff0c;對象關系映射&#xff09;是一種編程技術&#xff0c;用于在面向對象編程語言中實現不同類型系統的數據轉換。在Django中&#xff0c;ORM充當業務邏輯層和數據庫層之間的橋梁。核…

Tailwind CSS中設定寬度和高度的方法

在 Tailwind CSS 中&#xff0c;設定元素的寬度&#xff08;width&#xff09;和高度&#xff08;height&#xff09;有多種方式&#xff0c;涵蓋固定值、相對值、響應式調整等。以下是完整的方法分類及示例&#xff1a;一、固定寬度 / 高度類以 4px (0.25rem) 為單位遞增&…

Java行為型模式---備忘錄模式

備忘錄模式基礎概念備忘錄模式&#xff08;Memento Pattern&#xff09;是一種行為型設計模式&#xff0c;其核心思想是在不破壞封裝性的前提下&#xff0c;捕獲一個對象的內部狀態&#xff0c;并在該對象之外保存這個狀態&#xff0c;以便后續可以將該對象恢復到先前保存的狀態…

后端參數校驗

前端給后端傳輸數據&#xff0c;有時候參數需要校驗&#xff0c;我們自己寫代碼會比較麻煩&#xff0c;我們可以使用springboot為我們提供的注解&#xff0c;降低這些沒有必要的代碼開發。1.引入依賴<dependency><groupId>org.springframework.boot</groupId>…

C++ - 仿 RabbitMQ 實現消息隊列--服務端核心模塊實現(一)

目錄 日志打印工具 實用 Helper 工具 sqlite 基礎操作類 字符串操作類 UUID 生成器類 文件基礎操作 文件是否存在判斷 文件大小獲取 讀文件 寫文件 文件重命名 文件創建/刪除 父級目錄的獲取 目錄創建/刪除 附錄&#xff08;完整代碼&#xff09; 日志打印工具 為了便…

C語言:第07天筆記

C語言&#xff1a;第07天筆記 內容提要 循環結構 break與continue 綜合案例《猜拳游戲》數組 數組的概念一維數組流程控制 break與continue break 功能&#xff1a; ① 用在switch中&#xff0c;用來跳出switch中的case語句&#xff1b;如果case沒有break&#xff0c;可能會產生…

qt 中英文翻譯 如何配置和使用

qt 中英文翻譯 如何配置和使用 1. 在.pro文件中添加TRANSLATIONS 在你的 .pro 文件&#xff08;比如 HYAC_AAF_HOST.pro&#xff09;中添加&#xff1a; TRANSLATIONS \ zh\_CN.ts en\_US.ts這會告訴Qt項目你要支持中文和英文。 2. 提取可翻譯文本&#xff08;生成ts文件&#…

Leetcode 710. 黑名單中的隨機數

1.題目基本信息 1.1.題目描述 給定一個整數 n 和一個 無重復 黑名單整數數組 blacklist 。設計一種算法&#xff0c;從 [0, n - 1] 范圍內的任意整數中選取一個 未加入 黑名單 blacklist 的整數。任何在上述范圍內且不在黑名單 blacklist 中的整數都應該有 同等的可能性 被返…

RxJava 全解析:從原理到 Android 實戰

在 Android 開發中&#xff0c;異步任務處理是繞不開的核心場景 —— 網絡請求、數據庫操作、文件讀寫等都需要在后臺執行&#xff0c;而結果需回調到主線程更新 UI。傳統的 “HandlerThread” 或 AsyncTask 不僅代碼冗余&#xff0c;還容易陷入 “回調地獄”&#xff08;嵌套回…

OpenCV 官翻7 - 對象檢測

文章目錄ArUco 標記檢測標記與字典標記物創建標記檢測姿態估計選擇字典預定義字典自動生成字典手動定義字典檢測器參數閾值處理adaptiveThreshConstant輪廓過濾minMarkerPerimeterRate 與 maxMarkerPerimeterRatepolygonalApproxAccuracyRateminCornerDistanceRateminMarkerDis…

【Oracle】ORACLE OMF說明

ORACLE OMF (Oracle Managed Files) 是 Oracle 數據庫提供的一項自動化文件管理功能。它的核心目的是簡化數據庫管理員&#xff08;DBA&#xff09;對數據庫底層操作系統文件的管理工作。 以下是 OMF 的關鍵要點&#xff1a; 核心功能&#xff1a;自動命名和定位文件 在創建數據…

408考研逐題詳解:2010年第35題——RIP協議

2010年第35題 某自治系統內采用 RIP 協議&#xff0c;若該自治系統內的路由器 R1 收到其鄰居路由器 R2 的距離矢量&#xff0c;距離矢量中包含信息 <net1, 16>&#xff0c;則能得出的結論是&#xff08; &#xff09; A. R2 可以經過 R1 到達 net1&#xff0c;跳數為17 …

http與https的主要區別是什么?

什么是HTTP&#xff1f; HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本傳輸協議&#xff09;是互聯網上應用最為廣泛的一種網絡協議。它構成了Web數據通信的基礎&#xff0c;并定義了客戶端和服務器之間如何請求和傳遞網頁信息。當您在瀏覽器中輸入一個網址時…

STC89C52系列單片機簡介

STC89C52系列單片機是由中國宏晶科技&#xff08;STC&#xff09;推出的一款新一代增強型8051內核單片機。它不僅繼承了傳統8051指令系統的兼容性&#xff0c;還在性能、功耗、抗干擾能力以及性價比方面進行了全面提升&#xff0c;廣泛應用于各類嵌入式控制場景&#xff0c;如工…

基于 Docker 環境的 JupyterHub 詳細部署手冊

本文詳細介紹基于Docker Compose的單機版JupyterHub部署方案&#xff0c;通過容器化技術實現多用戶Notebook環境的快速搭建。方案采用官方JupyterHub鏡像&#xff0c;配置11個端口映射&#xff08;18000-18010&#xff09;支持用戶并發&#xff0c;通過數據卷掛載&#xff08;.…