我们以前初始化一个接口直接使用调用该初始化函数,这样显式的调用造成的后果是每次使用添加接口的时候都要在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) |