0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

聊聊新版RT-Thread内核中的钩子

RTThread物联网操作系统 来源:RTThread物联网操作系统 作者:RTThread物联网操作 2022-10-25 09:32 次阅读

GitHub:https://github.com/RT-Thread/rt-thread

Gitee:https://gitee.com/rtthread/rt-thread?_from=gitee_search

欢迎star!

1、综述

从4.1.0版本开始,RT-Thread在保证向前兼容的基础上对原有的HOOK方式进行了改进,实现了如下的效果:

与原有使用函数指针进行“运行时刻”HOOK的方式兼容,依赖原有方式进行代码插入或HOOK的模块无需修改;

使用RT_USING_HOOK作为总开关

当未定义该宏时,将关闭所有HOOK功能,也不再生成任何相关代码

当定义该宏时,在未开启传统“函数指针HOOK”时,默认情况下也不再生成额外代码

允许用户通过“插入宏的方式”在编译时刻精细控制具体HOOK哪个位置

可以插入任意代码块——其中就包括函数指针、对普通函数的调用等等

2、使用方法

2.1 总开关

在rtconfig.h定义宏开关RT_USING_HOOK将开启HOOK功能。默认情况下,在该宏未定义时,所有HOOK功能都将被强制关闭,不会生成任何代码。

2.2 向前兼容

在4.1.0之前,RT-Thread提供了一套基于函数指针运行时注册的HOOK机制。新版本中,在开启HOOK功能的前提下,定义宏开关RT_HOOK_USING_FUNC_PTR将开启与过去相同的基于函数指针运行时注册的HOOK机制,实现向前兼容。

需要特别说明的是:

该机制的优点:在运行时刻允许用户动态修改HOOK函数;

其缺点是:即便用户并未使用对应的HOOK,该机制也将生成对应的代码,并在运行时刻略微占用一些几乎可以忽略不计的CPU周期数。

2.3 使用插入宏实现定点精细HOOK

无论用户是否定义了宏RT_HOOK_USING_FUNC_PTR,新的HOOK机制都允许用户“定点”、“精细”的对RT-Thread的任意锚点进行HOOK。具体方法为:在rtconfig.h(或其直接、间接包含的头文件)中按照如下的格式定义插入宏:

#define __on_<锚点名称>(<形参列表>)   
    do {                           
        /* 你要插入的任意代码 */      
    } while(0)

以内核的调度锚点rt_scheduler_hook为例,它的"等效"函数原型如下:

void __on_rt_scheduler_hook(struct rt_thread *from, struct rt_thread *to);

因此,我们只需要在rtconfig.h(或其直接、间接包含的头文件)中定义如下的宏:

#define __on_rt_scheduler_hook(__from, __to)   
    do {                                       
        /* 你要插入的任意代码 */                  
    } while(0)

就可以将任意代码插入到锚点rt_scheduler_hook在scheduler.c中的对应位置上。实际上,所有锚点的名称都与过去函数指针的名称相同。

除了插入代码块以外,一般插入宏会被用来将目标锚点直接替换为“对用户指定函数的调用”,比如,在上述例子中,假设用户想在调度器切换线程时调用一个指定的函数my_scheduler_notifier(),则可以修改插入宏为:

#define __on_rt_scheduler_hook(__from, __to)   
    my_scheduler_notifier((__from), (__to))

这里存在一个明显的问题,即,一般来说锚点所在的c源文件并不知道用户目标函数的原型(function prototype),因此编译器会报告"implicit function declaration" 一类的警告,甚至会将其视作编译错误。为了避免这类情况的发生,我们可以在定义插入宏时顺便引入对应的函数原型:

extern void my_scheduler_notifier(struct rt_thread *from, struct rt_thread *to);

#define __on_rt_scheduler_hook(__from, __to)   
    my_scheduler_notifier((__from), (__to))

2.4 注意事项

插入宏的方式优先级高于函数指针方式,即:当你同时使用两种方法对同一个锚点进行HOOK时,插入宏的方式将覆盖(Override)掉对应的函数指针HOOK。

RT-Thread一般不推荐用户直接修改rtconfig.h也不推荐在其中添加额外的代码:比如用户函数的原型等等。为了解决这一问题,通常有两个方案:

在rtconfig.h中包含一个专门存放用户HOOK的头文件,比如:

//! rtconfg.h
...
#include “user_hook.h”

在编译选项中以全局头文件包含的形式将专门存放用户HOOK的头文件引用进来,比如:

在gcc、clang和arm compiler 6中使用-include "<头文件>"的方式:

-include "user_hook.h"

在arm compiler 5中使用--preinclude=头文件的方式:

--preinclude="user_hook.h"

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内核
    +关注

    关注

    3

    文章

    1309

    浏览量

    39846
  • RT-Thread
    +关注

    关注

    31

    文章

    1148

    浏览量

    38867
  • 函数指针
    +关注

    关注

    2

    文章

    53

    浏览量

    3737

原文标题:聊聊新版RT-Thread内核中的钩子

文章出处:【微信号:RTThread,微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    如何对RT-Thread内核有基本的了解?

    RT-Thread 的时钟管理以时钟节拍为基础,时钟节拍是 RT-Thread 操作系统中最小的时钟单位。
    的头像 发表于 07-19 10:12 6790次阅读
     如何对<b class='flag-5'>RT-Thread</b><b class='flag-5'>内核</b>有基本的了解?

    RT-Thread记录(二、RT-Thread内核启动流程)

    在前面我们RT-Thread Studio工程基础之上讲一讲RT-Thread内核启动流程.
    的头像 发表于 06-20 00:30 4412次阅读
    <b class='flag-5'>RT-Thread</b>记录(二、<b class='flag-5'>RT-Thread</b><b class='flag-5'>内核</b>启动流程)

    RT-Thread记录(五、RT-Thread 临界区保护)

    本文聊聊临界区,以及RT-Thread对临界区的处理
    的头像 发表于 06-20 16:06 4286次阅读
    <b class='flag-5'>RT-Thread</b>记录(五、<b class='flag-5'>RT-Thread</b> 临界区保护)

    RT-Thread内核简介

    RT-Thread 内核简介前言1、RT-Thread 的架构2、RT-Thread内核3、RT-T
    发表于 08-06 07:44

    钩子函数是什么?RT-Thread系统引入钩子函数有何用处

    系统钩子函数为了在运行时跟踪和记录RT-Thread的活动,引入了一种钩子机制。钩子函数是在一些特殊检查点调用的一类函数。 钩子函数包括:对
    发表于 08-29 15:30

    RT-Thread内核对象管理器设计思路

    [导读] 前面写了些文章分享C语言面向对象设计的一些个人体会,个人认为RT-Thread内核对于面向对象实现思想是一个非常好的设计。向这些在基础软件上深耕的国人大牛们致敬。本文基于学习
    的头像 发表于 11-04 18:09 1497次阅读
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>内核</b>对象管理器设计思路

    RT-Thread 内核学习笔记 - 理解defunct僵尸线程

    RT-Thread 内核学习笔记 - 内核对象rt_objectRT-Thread 内核学习笔记 -
    发表于 01-25 18:19 8次下载
    <b class='flag-5'>RT-Thread</b> <b class='flag-5'>内核</b>学习笔记 - 理解defunct僵尸线程

    RT-Thread 内核学习笔记 - 设备模型rt_device的理解

    RT-Thread 内核学习笔记 - 内核对象rt_objectRT-Thread 内核学习笔记 -
    发表于 01-25 18:19 8次下载
    <b class='flag-5'>RT-Thread</b> <b class='flag-5'>内核</b>学习笔记 - 设备模型<b class='flag-5'>rt</b>_device的理解

    RT-Thread 内核学习笔记 - 内核对象链表结构深入理解

    RT-Thread 内核学习笔记 - 内核对象rt_objectRT-Thread 内核学习笔记 -
    发表于 01-25 18:23 6次下载
    <b class='flag-5'>RT-Thread</b> <b class='flag-5'>内核</b>学习笔记 - <b class='flag-5'>内核</b>对象链表结构深入理解

    RT-Thread 内核学习笔记 - 内核对象初始化链表组织方式

    RT-Thread 内核学习笔记 - 内核对象rt_objectRT-Thread 内核学习笔记 -
    发表于 01-25 18:24 3次下载
    <b class='flag-5'>RT-Thread</b> <b class='flag-5'>内核</b>学习笔记 - <b class='flag-5'>内核</b>对象初始化链表组织方式

    RT-Thread 内核学习笔记 - 内核对象操作API

    RT-Thread 内核学习笔记 - 内核对象rt_objectRT-Thread 内核学习笔记 -
    发表于 01-25 18:26 7次下载
    <b class='flag-5'>RT-Thread</b> <b class='flag-5'>内核</b>学习笔记 - <b class='flag-5'>内核</b>对象操作API

    RT-Thread文档_RT-Thread 简介

    RT-Thread文档_RT-Thread 简介
    发表于 02-22 18:22 5次下载
    <b class='flag-5'>RT-Thread</b>文档_<b class='flag-5'>RT-Thread</b> 简介

    RT-Thread文档_内核基础

    RT-Thread文档_内核基础
    发表于 02-22 18:28 0次下载
    <b class='flag-5'>RT-Thread</b>文档_<b class='flag-5'>内核</b>基础

    RT-Thread文档_内核移植

    RT-Thread文档_内核移植
    发表于 02-22 18:31 2次下载
    <b class='flag-5'>RT-Thread</b>文档_<b class='flag-5'>内核</b>移植

    RT-Thread文档_RT-Thread SMP 介绍与移植

    RT-Thread文档_RT-Thread SMP 介绍与移植
    发表于 02-22 18:31 7次下载
    <b class='flag-5'>RT-Thread</b>文档_<b class='flag-5'>RT-Thread</b> SMP 介绍与移植