博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SylixOS钩子函数浅析
阅读量:6539 次
发布时间:2019-06-24

本文共 5070 字,大约阅读时间需要 16 分钟。

1 使用背景

对定时器做相关配置,使得每隔时间T,触发定时器中断,可以在定时器中断处理函数处理算法,这样就可以周期性的执行特定的任务。但如果不想在定时器中断处理函数中添加算法,比如说用户只想在应用程序里面执行他们的任务,那么钩子函数就是一个不错的选择。
2 钩子函数的原理
本章以定时器中断为例说明SylixOS钩子的使用方法。
2.1 API_InterVectorIsr函数
函数原型如程序清单 2.1
程序清单 2.1
#include <SylixOS>
irqreturn_t API_InterVectorIsr (ULONG ulVector);
API_InterVectorIsr该内核接口是向量中断的总服务入口,根据中断号得到对应的中断服务函数链表,找到具体中断服务函数。流程图如图 2.1 所示。
SylixOS钩子函数浅析
图 2.1 中断向量处理流程
从流程图可以看到,该函数入口处调用LW_CPU_INT_ENTER_HOOK。该宏的定义如程序清单 2.2所示。这就是钩子函数的调用流程,其实就是调用一个函数指针指向的函数。
程序清单 2.2
#define
LW_CPU_INT_ENTER_HOOK(ulVector, ulNesting) \
if (_K_hookKernel.HOOK_CpuIntEnter) { \
_K_hookKernel.HOOK_CpuIntEnter(ulVector, ulNesting); \
}

2.2 钩子的设置函数

SylixOS内核提供了钩子的设置接口API_KernelHookSet,函数的实现如程序清单 2.3所示。
程序清单 2.3
LW_API
ULONG API_KernelHookSet (LW_HOOK_FUNC hookfuncPtr, ULONG ulOpt)
{
INTREG iregInterLevel;

iregInterLevel = __KERNEL_ENTER_IRQ();                              /*  进入内核同时关闭中断        */switch (ulOpt) {case LW_OPTION_THREAD_CREATE_HOOK:                                  /*  线程建立钩子                */    _K_hookKernel.HOOK_ThreadCreate = hookfuncPtr;    break;case LW_OPTION_THREAD_DELETE_HOOK:                                  /*  线程删除钩子                */    _K_hookKernel.HOOK_ThreadDelete = hookfuncPtr;    break;case LW_OPTION_THREAD_SWAP_HOOK:                                    /*  线程切换钩子                */    _K_hookKernel.HOOK_ThreadSwap = hookfuncPtr;    break;case LW_OPTION_THREAD_TICK_HOOK:                                    /*  系统时钟中断钩子            */    _K_hookKernel.HOOK_ThreadTick = hookfuncPtr;    break;case LW_OPTION_THREAD_INIT_HOOK:                                    /*  线程初始化钩子              */    _K_hookKernel.HOOK_ThreadInit = hookfuncPtr;    break;case LW_OPTION_THREAD_IDLE_HOOK:                                    /*  空闲线程钩子                */    _K_hookKernel.HOOK_ThreadIdle = hookfuncPtr;    break;case LW_OPTION_KERNEL_INITBEGIN:                                    /*  内核初始化开始钩子          */    _K_hookKernel.HOOK_KernelInitBegin = hookfuncPtr;    break;case LW_OPTION_KERNEL_INITEND:                                      /*  内核初始化结束钩子          */    _K_hookKernel.HOOK_KernelInitEnd = hookfuncPtr;    break;case LW_OPTION_KERNEL_REBOOT:                                       /*  内核重新启动钩子            */    _K_hookKernel.HOOK_KernelReboot = hookfuncPtr;    break;case LW_OPTION_WATCHDOG_TIMER:                                      /*  看门狗定时器钩子            */    _K_hookKernel.HOOK_WatchDogTimer = hookfuncPtr;    break;case LW_OPTION_OBJECT_CREATE_HOOK:                                  /*  创建内核对象钩子            */    _K_hookKernel.HOOK_ObjectCreate = hookfuncPtr;    break;case LW_OPTION_OBJECT_DELETE_HOOK:                                  /*  删除内核对象钩子            */    _K_hookKernel.HOOK_ObjectDelete = hookfuncPtr;    break;case LW_OPTION_FD_CREATE_HOOK:                                      /*  文件描述符创建钩子          */    _K_hookKernel.HOOK_FdCreate = hookfuncPtr;    break;case LW_OPTION_FD_DELETE_HOOK:                                      /*  文件描述符删除钩子          */    _K_hookKernel.HOOK_FdDelete = hookfuncPtr;    break;case LW_OPTION_CPU_IDLE_ENTER:                                      /*  CPU 进入空闲模式            */    _K_hookKernel.HOOK_CpuIdleEnter = hookfuncPtr;    break;case LW_OPTION_CPU_IDLE_EXIT:                                       /*  CPU 退出空闲模式            */    _K_hookKernel.HOOK_CpuIdleExit = hookfuncPtr;    break;case LW_OPTION_CPU_INT_ENTER:                                       /*  CPU 进入中断(异常)模式      */    _K_hookKernel.HOOK_CpuIntEnter = hookfuncPtr;    break;case LW_OPTION_CPU_INT_EXIT:                                        /*  CPU 退出中断(异常)模式      */    _K_hookKernel.HOOK_CpuIntExit = hookfuncPtr;    break;case LW_OPTION_STACK_OVERFLOW_HOOK:                                 /*  堆栈溢出                    */    _K_hookKernel.HOOK_StkOverflow = hookfuncPtr;    break;case LW_OPTION_FATAL_ERROR_HOOK:                                    /*  致命错误                    */    _K_hookKernel.HOOK_FatalError = hookfuncPtr;    break;case LW_OPTION_VPROC_CREATE_HOOK:                                   /*  进程建立钩子                */    _K_hookKernel.HOOK_VpCreate = hookfuncPtr;    break;case LW_OPTION_VPROC_DELETE_HOOK:                                   /*  进程删除钩子                */    _K_hookKernel.HOOK_VpDelete = hookfuncPtr;    break;default:    __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核同时打开中断        */    _ErrorHandle(ERROR_KERNEL_OPT_NULL);    return  (ERROR_KERNEL_OPT_NULL);}__KERNEL_EXIT_IRQ(iregInterLevel);                                  /*  退出内核同时打开中断        */return  (ERROR_NONE);

}

该函数可以设置各种类型钩子函数,由此可见,只要调用API_KernelHookSet设置中断相关的钩子函数,当进入中断入口的函数的入口时都会调用钩子。
2.3 钩子函数的定义
假设设置了中断的钩子函数,那么任何中断都会调用这个钩子函数。现在只关心定时器中断,因此需要用中断号来过滤不关心的中断。例程如程序清单 2.4所示。
程序清单 2.4
#define TIMER_INTVECTOR 69
void HookFun(ULONG ulVector,ULONG ulnest)
{
if(TIMER_INTVECTOR != ulVector)
{
return;
}

/* 用户在此添加自己算法*//* 注意:不要调用中断上下文不能执行的语句,比如sleep,printf等*/

}

这样,系统会周期性的进入定时器中断,处理 HookFun函数。只要知道中断号,就可以不用知晓定时器驱动的实现机制,直接挂接想要处理的任务。
3 参考资料
《SylixOS_driver_usermanual》

转载于:https://blog.51cto.com/12142768/2162820

你可能感兴趣的文章
c++ 类型定义
查看>>
C#开发微信门户及应用(5)--用户分组信息管理
查看>>
怎样实现前端裁剪上传图片功能
查看>>
程序员提高工作效率的15个技巧【Facebook】
查看>>
ffmpeg+SDL2实现的视频播放器「退出、暂停、播放」
查看>>
2011/7/3 第二次评审
查看>>
Openvswitch手册(2): OpenFlow Controller
查看>>
Cocos2d-JS项目之二:studio基础控件的使用
查看>>
tar解压
查看>>
inheritprototype原型继承封装及综合继承最简实例
查看>>
【磁耦隔离接口转换器】系列产品选型指南
查看>>
Apriori 关联算法学习
查看>>
二叉树、红黑树、伸展树、B树、B+树
查看>>
Junit核心——测试集(TestSuite)
查看>>
MVPArms官方首发一键生成组件化,体验纯傻瓜式组件化开发
查看>>
Log4j_学习_00_资源帖
查看>>
制作iso镜像U盘自动化安装linux系统
查看>>
JSLint的使用
查看>>
命令行常用命令--软连接
查看>>
HTTP POST GET 本质区别详解
查看>>