Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
内核
RT-Thread新版本中Hook的使用方法
5.00
发布于 2022-04-09 07:34:17 浏览:2325
订阅该版
[tocm] ## 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`(或其直接、间接包含的头文件)中按照如下的格式定义插入宏: ```c #define __on_<锚点名称>(<形参列表>) \ do { \ /* 你要插入的任意代码 */ \ } while(0) ``` 以内核的调度锚点`rt_scheduler_hook`为例,它的"等效"函数原型如下: ```c void __on_rt_scheduler_hook(struct rt_thread *from, struct rt_thread *to); ``` 因此,我们只需要在`rtconfig.h`(或其直接、间接包含的头文件)中定义如下的宏: ```c #define __on_rt_scheduler_hook(__from, __to) \ do { \ /* 你要插入的任意代码 */ \ } while(0) ``` 就可以将任意代码插入到锚点`rt_scheduler_hook`在scheduler.c中的对应位置上。实际上,**所有锚点的名称都与过去函数指针的名称相同**。 除了插入代码块以外,一般插入宏会被用来将目标锚点直接替换为“对用户指定函数的调用”,比如,在上述例子中,假设用户想在调度器切换线程时调用一个指定的函数`my_scheduler_notifier()`,则可以修改插入宏为: ```c #define __on_rt_scheduler_hook(__from, __to) \ my_scheduler_notifier((__from), (__to)) ``` 这里存在一个明显的问题,即,一般来说锚点所在的c源文件并不知道用户目标函数的原型(***function prototype***),因此编译器会报告"***implicit function declaration***" 一类的警告,甚至会将其视作编译错误。为了避免这类情况的发生,我们可以在定义插入宏时顺便引入对应的函数原型: ```c 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的头文件,比如: ```c //! rtconfg.h ... #include “user_hook.h” ``` - 在编译选项中以全局头文件包含的形式将专门存放用户HOOK的头文件引用进来,比如: 在**gcc**、**clang**和**arm compiler 6**中使用 `-include "<头文件>"`的方式: ```c -include "user_hook.h" ``` 在**arm compiler 5**中使用`--preinclude=头文件`的方式: ```c --preinclude="user_hook.h" ```
3
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
Gorgon_Meducer
这家伙很懒,什么也没写!
文章
1
回答
0
被采纳
0
关注TA
发私信
相关文章
1
rt-thread的学习疑惑
2
基于stm32的RTT在RTT Studio IDE环境中的启动顺序求解
3
关于 rt_object_detach 脱离内核对象函数的作用求解
4
RT-Thread内核什么时候考虑加入MPU功能?
5
rt_hw_board_init中开中断后,触发SysTick_Handler
6
Cortex-M0在bootloader环境下的上下文切换问题?
7
关于ART-PI的bootloader是怎么烧写进去的
8
为什么内核代码和bootloader的代码一样的
9
线程对象结构体为什么不直接选择继承内核对象?
10
使用rt_memset给线程栈初始化,为什么选择字符‘#’,而不是‘\0’?
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
freemodbus
PWM
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
中断
编译报错
Debug
SFUD
rt_mq_消息队列_msg_queue
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
4
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
Ryan_CW
4
个答案
1
次被采纳
xiaorui
1
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
Woshizhapuren
1
篇文章
5
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部