SylixOS钩子函数浅析

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

图 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》

原文地址:http://blog.51cto.com/12142768/2162820

时间: 2024-10-10 23:28:16

SylixOS钩子函数浅析的相关文章

vue2.0项目实战(3)生命周期和钩子函数详解

最近的项目都使用vue2.0来开发,不得不说,vue真的非常好用,大大减少了项目的开发周期.在踩坑的过程中,因为对vue的生命周期不是特别了解,所以有时候会在几个钩子函数里做一些事情,什么时候做,在哪个函数里做,我们不清楚. 下面来总结一下vue的生命周期. vue生命周期简介 咱们从上图可以很明显的看出现在vue2.0都包括了哪些生命周期的函数了. 生命周期探究 对于执行顺序和什么时候执行,看上面两个图基本有个了解了.下面我们将结合代码去看看钩子函数的执行. <!DOCTYPE html>

php 钩子函数原理 解析

目前对钩子的理解:<转载:http://www.cnblogs.com/del/archive/2008/02/25/1080825.html> 譬如我们用鼠标在某个窗口上双击了一次, 或者给某个窗口输入了一个字母 A; 首先发现这些事件的不是窗口, 而是系统! 然后系统告诉窗口: 喂! 你让人点了, 并且是连续点了两鼠标, 你准备怎么办? 或者是系统告诉窗口: 喂! 有人向你家里扔砖头了, 不信你看看, 那块砖头是 A. 这时窗口的对有些事件会忽略.对有些事件会做出反应: 譬如, 可能对鼠标

用Delphi实现Windows的鼠标钩子函数

Delphi是基于PASCAL语言的Windows编程工具,功能十分强大.然而在Delphi的帮助文件中,对Windows API函数的说明沿袭了 VC 的格式,和VC一样,对很多API函数的用法没有举例子详细说明,对一些深入系统内部的API函数更是语焉不详,给编程者带来不便.笔者仅就在Windows编程中鼠标钩子函数(HOOK)的实现,举例作一说明.   鼠标钩子函数也可叫做鼠标消息过滤器,是一种回调(CALLBACK)函数,归系统调用.如果用SetWindowsHook或SetWindows

主题:钩子函数简析及实例

钩子函数.回调函数.注冊函数.挂钩子这些我们代码中常常涉及到的东西,是否已经困扰你非常久了?它们到底是怎么回事,到底怎么用?以下我来为你一一解答. 什么是钩子函数? 钩子函数也叫回调函数,是通过函数指针来实现的.那我们来看看什么是函数指针. 首先看看下面样例: int *p; int a,b. 我们能够让指针p先后指向a, b,这样,p就先后代表了不同变量的地址 p = &a; p = &b; 相同地.函数的指针能够指向不同的函数,从而完毕不同的功能. 比如,定义函数指针: int (*

Vue源码后记-钩子函数

vue源码的马拉松跑完了,可以放松一下写点小东西,其实源码讲20节都讲不完,跳了好多地方. 本人技术有限,无法跟大神一样,模拟vue手把手搭建一个MVVM框架,然后再分析原理,只能以门外汉的姿态简单过一下~ 想到什么写什么了,这节就简单说说钩子函数吧! vue中的钩子函数主要包含初始化的beforeCreated/created,Virtual Dom更新期间的beforeUpdate/updated,页面渲染期间的beforeMount/mounted,组件销毁期间的beforeDestroy

(转)Vue2.X的路由管理记录之 钩子函数(切割流水线)

$route可以在子组件任何地方调用,代表当前路由对象,这个属性是只读的,里面的属性是 immutable(不可变) 的,不过你可以 watch(监测变化)它. 导航和钩子函数: 导航:路由正在发生改变   关键字:路由  变 钩子函数:在路由切换的不同阶段调用不同的节点函数(钩子函数在我看来也就是:某个节点和时机触发的函数) 两者关系: 钩子函数 ---> 导航 :     钩子函数   主要用来拦截导航,让它完成跳转或取消,在导航的不同阶段来执行不同的函数 ,最后钩子函数的执行结果会告诉导航

回调函数以及钩子函数的概念

钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统.每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权.这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递.对每种类型的钩子由系统来维护一个钩子链,最近安装的钩子放在链的开始,而最先安装的钩子放在最后,也就是后加入的先获得控制权.要实现Win32的系统钩子,必须调用SDK中的API函数SetWindowsHookEx来安装这个钩子函数,这个函数的原型是

PHP.25-TP框架商城应用实例-后台1-添加商品功能、钩子函数、在线编辑器、过滤XSS、上传图片并生成缩略图

添加商品功能 1.创建商品控制器[C] /www.test.com/shop/Admin/Controller/GoodsController.class.php <?php namespace Admin\Controller; use Think\Controller; //后台添加商品功能控制器 class GoodsController extends Controller { //显示和处理表单 public function add() { //判断用户是否提交了表单(如果提交了,就

钩子函数 和回调函数

http://blog.csdn.net/lipeionline/article/details/6369657  转自 也可以这样,更容易理解:回调函数就好像是一个中断处理函数,系统在符合你设定的条件时自动调用.为此,你需要做三件事: 1.       声明: 2.       定义: 3.       设置触发条件,就是在你的函数中把你的回调函数名称转化为地址作为一个参数,以便于系统调用. 钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统.每当特定的消息发出,在没有到达目的窗口前