stm32函数放入段section中
到了map文件最后移除了未用到的段。但是可以通过加—keep字段进行保留,让其最后不再删除。
对于本例程的用法是:
--keep=__myFun*
当然了,按照map文件的提示,是将used文件变为unused,进而删除了,那么可以做一个操作:
#define INIT_FUN(fn,level) \
const MyFun __myFun_##fn __attribute__((section(".myFun."level))) __attribute__((used)) = fn
就是加: __attribute__((used))变为显示的使用了这个段,那它就不会被删除了吧,测试可行!!其实这个在linux上可以找到相关的参考。
内核版本linux3.0.1.。
在main.c(init)这个文件中,
有:
extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
static void __init do_initcalls(void)
{
initcall_t *fn;
for (fn = __early_initcall_end; fn < __initcall_end; fn++)
do_on
}
在init.h中有:
typedef int (*initcall_t)(void);
在vmlinux.lds.h中有:
#define INIT_CALLS \
VMLINUX_SYMBOL(__initcall_start) = .; \
INITCALLS \
VMLINUX_SYMBOL(__initcall_end) = .;
#define INITCALLS \
*(.initcallearly.init) \
VMLINUX_SYMBOL(__early_initcall_end) = .; \
*(.initcall0.init) \
*(.initcall0s.init) \
*(.initcall1.init) \
*(.initcall1s.init) \
*(.initcall2.init) \
*(.initcall2s.init) \
*(.initcall3.init) \
*(.initcall3s.init) \
*(.initcall4.init) \
*(.initcall4s.init) \
*(.initcall5.init) \
*(.initcall5s.init) \
*(.initcallrootfs.init) \
*(.initcall6.init) \
*(.initcall6s.init) \
*(.initcall7.init) \
*(.initcall7s.init)
很简单,写的函数在段.initcall0.init-----initcall7s.init中,那么遍历的时候,框头框尾,中间函数明显就能调用到。
然后在init.h中有
#define __init __section(.init.text)
#define __initdata __section(.init.da
#define __exitdata __section(.exit.da
#define __exit_call __used __section(.exitcall.exit)
同样在段上加了一个__used修饰。猜测来的,所以加上了__attribute__((used))
上代码:
static int init_begin(void)
{
printf("----fun init start---\r\n");
return 0;
}
INIT_FUN(init_begin,"0");
static int init_fun1(void)
{
printf("----fun init fun1---\r\n");
return 0;
}
INIT_FUN(init_fun1,"0s");
static int init_fun2(void)
{
printf("----fun init fun2---\r\n");
return 0;
}
INIT_FUN(init_fun2,"2");
static int init_end(void)
{
printf("----fun init end---\r\n");
return 0;
}
INIT_FUN(init_end,"7");
上面一系列函数中:
init_begin函数和init_end属于框头框尾,遍历时候,就作为边界即可
于是,就形成:
const MyFun *vMyFun;
for( vMyFun = &__myFun_init_begin; vMyFun <= &__myFun_init_end; vMyFun ++)
{
(*vMyFun)();
}
从而达到效果。
第二种办法:
只有段的概念,不用计算多少个函数,由编译器来动作即可。
typedef int (*FunInit)(void);
#define INIT_FUNCTION(func) \
FunInit __Fun_##func __attribute__((section("mySection"))) = func
void InitFun1(void)
{
printf("InitFun1 init\r\n");
}
INIT_FUNCTION(InitFun1);
void InitFun2(void)
{
printf("InitFun2 init \r\n");
}
INIT_FUNCTION(InitFun2);
extern int mySection$$Base;
extern int mySection$$Length;
FunInit *initFunc = (FunInit *)&mySection$$Base;
int count = (int)(&mySection$$Length)/sizeof(FunInit);
while(count--) {
(*initFunc)();
initFunc++;
}
就这样,可以遍历整个段中定义好的函数了。
代码下载:
http://download.csdn.net/detail/wit_yuan/9010727中关于section的部分。
stm32函数段sectio 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)