前言
上篇提到rtthread有很多使用钩子函数的地方,比如在内核对象创建的过程中,当对象创建、删除等会触发相应的钩子函数。钩子函数可以体现rtthread的面向对象c的思想。本篇主要记录rtthread钩子函数的使用及解决上一篇的遗留问题。
上篇链接:https://blog.csdn.net/m0_64899535/article/details/140594269
钩子函数使用
在rtdet.h文件中,有如下定义:
#ifdef RT_USING_HOOK
#define RT_OBJECT_HOOK_CALL(func, argv) \
do { if ((func) != RT_NULL) func argv; } while (0)
同样,如果开启了rtconfig.h中开启了钩子函数,那么这个宏定义也会被定义。
在object.c中的使用示例如下:
RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object));
上述的代码发生在当创建一个新的内核对象,例如信号,线程等等,需要将内核对象附在内核对象信息表中。此时如果你已经定义了钩子函数,那么这个钩子函数就会被自动调用。
上篇遗留问题
object.c中除了定义了静态钩子函数指针外,还提供了全局钩子函数指针和相应的xxx_setxxx函数。
void (*rt_object_trytake_hook)(struct rt_object *object);
void (*rt_object_take_hook)(struct rt_object *object);
void (*rt_object_put_hook)(struct rt_object *object);
void rt_object_trytake_sethook(void (*hook)(struct rt_object *object))
{
rt_object_trytake_hook = hook;
}
void rt_object_take_sethook(void (*hook)(struct rt_object *object))
{
rt_object_take_hook = hook;
}
void rt_object_put_sethook(void (*hook)(struct rt_object *object))
{
rt_object_put_hook = hook;
}
既然定义了全局的钩子函数指针,那么就给了其它模块直接赋值的可能。 在内核中使用时,静态函数指针和全局钩子函数在内核中使用的主要区别在ipc.c文件中。
#ifdef RT_USING_HOOK
extern void (*rt_object_trytake_hook)(struct rt_object *object);
extern void (*rt_object_take_hook)(struct rt_object *object);
extern void (*rt_object_put_hook)(struct rt_object *object);
#endif
我的理解
从内核层面来说,不管是静态函数指针还是非静态函数指针,共同点是在内核代码中都不会采用set系函数进行设置。不同点是后者在内核其它代码中会使用。
从用户层面来说,全局函数指针采用set设置肯定没有问题,但是直接赋值好像也没什么毛病。