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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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;.…