Chinaunix首页 | 论坛 | 博客
  • 博客访问: 104681
  • 博文数量: 11
  • 博客积分: 2520
  • 博客等级: 少校
  • 技术积分: 172
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-17 09:26
文章分类
文章存档

2009年(11)

我的朋友

分类:

2009-05-30 16:31:21

我们以前初始化一个接口直接使用调用该初始化函数,这样显式的调用造成的后果是每次使用添加接口的时候都要在C主函数中添加该初始化函数,现在我就利用GCC的特性简化该过程。
关于linux内核中该方法的使用请看链接:
下面是本人做的实验。
下面是全部代码:
文件: int.tar.bz2
大小: 7KB
下载: 下载
下面是initcall.h文件。
 

  1 /*
  2 * booktree.zhou@gmail.com
  3 * 注释掉的留在这里以后添加支持。

  4 */
  5 #ifndef __INITCALL_H
  6 #define __INITCALL_H
  7 /*
  8 * used to initilize calls
  9 */

 10 typedef void (*initcall_t)(void);
 11 #if 0
 12 typedef void (*exitcall_t)(void);
 13 #endif
 14 #define __init __attribute__((__section__(".init.text")))
 15 #if 0
 16 #define __exit __attribute__((__section__(".exit.text")))
 17 #endif
 18 extern initcall_t __initcall_start[];
 19 extern initcall_t __initcall_end[];
 20 #if 0
 21 extern exitcall_t __exitcall_start[];
 22 extern exitcall_t __exitcall_end[];
 23 #endif
 24 #define module_init(fn) \
 25 static initcall_t __initcall_##fn \
 26 __attribute__((__used__)) __attribute__((__section__(".initcall_.text"))) = fn
 27 #if 0
 28 #define module_exit(fn) \
 29 static exitcall_t __initcall_##fn \
 30 __attribute__((__used__)) __attribute__((__section__(".exitcall_.text"))) = fn
 31 #endif
 32 void do_initcalls(void);
 33 #if 0
 34 void do_exitcalls(void);
 35 #endif
 36 #endif /*__INITCALL_H*/

下面是initcall.c文件

  1 /*
  2 *booktree.zhou@gmail.com
  3 */

  4 #include "initcall.h"
  5 /*
  6 * do all initialize calls
  7 */

  8 void do_initcalls(void) 该函数是提供给主控C函数调用用来初始化模块使用的
  9 {
 10 initcall_t *call;
 11 call = &(*__initcall_start);
 12 while(call < &(*__initcall_end))
 13 {
 14 (*call)();
 15 call++;
 16 }
 17 }
 18
 19 /*
 20 * supported later 以后支持
 21 */

 22 #if 0
 23 /*
 24 *do all exit calls
 25 */

 26 void do_exitcalls(void)
 27 {
 28 exitcall_t *call;
 29 call = &(*__exitcall_start);
 30 while(call < &(*__initcall_end))
 31 {
 32 (*call)();
 33 call++;
 34 }
 35 }
 36 #endif

上面的代码使用示例

在主控函数中,使用如下:

...
  3 #include "initcall.h"
...
  8
  9 void start_main(void)
 10 {
 11 unsigned char c;
 12 do_initcalls();//就可以初始化每个模块了
...

在模块中使用示例:

 3 #include "initcall.h"

...

 9 void __init key_init(void)  注意这里的__init的使用
 10 {
 11 S3C2440_GPIO *const gpio = S3C2440_GetBase_GPIO();
 12 gpio->GPFCON = GPF0_in & GPF2_in;
 13 gpio->GPGCON = GPG3_in & GPG11_in;
 14 }

...

 47 module_init(key_init);   注意这里

还有一个重要的一点就是要修改连接脚本

 ...

 15 .text : AT(4096)
 16 {
 17 *(.text)
 18 . = ALIGN(4);
 19 *(.init.text)/*我们自己定义的*/
 20 . = ALIGN(4);
 21 __initcall_start = .;do_initcalls()函数使用
 22 *(.initcall_.text)
 23 __initcall_end = .;
 24 }

...

阅读(2029) | 评论(0) | 转发(0) |
0

上一篇:printk函数实现

下一篇:没有了

给主人留下些什么吧!~~