按照相同机制自己写的代码见文末尾
是把函数的地址定义在指定的sec
tion下,按照顺序连续排列,使用指针一个一个偏移读出函数指针的值(也就是函数入口),进行执行。
函数指针的定义
1.熟悉函数指针
2.熟悉typedef
typedef int (*Led_ptr)(void);
typedef 返回类型(*新类型)(参数表)
typedef char (*PTRFUN)(int);
PTRFUN pFun;
char glFun(int a){ return;}
void main()
{
pFun = glFun;
(*pFun)(2);
}
typedef的功能是定义新的类型。第一句就是定义了一种PTRFUN的类型,并定义这种类型为指向某种函数的指针,这种函数以一个int为参数并返回char类型。后面就可以像使用int,char一样使用PTRFUN了。
第二行的代码便使用这个新类型定义了变量pFun,此时就可以像使用形式1一样使用这个变量了。
函数指针因为函数所占用空间的不同而无法使用 自加,自减操作。
所以需要定义一个指向函数指针的指针(二重指针)
Led_ptr *program1;
__attribute__((used))Led_ptr (p1) __attribute__((section(".ledsection.")))= LED_state1;
__attribute__((used))Led_ptr (p2) __attribute__((section(".ledsection")))= LED_state2;
__attribute__((used))Led_ptr (p3) __attribute__((section(".ledsection")))= LED_state3;
然后把函数的地址装填到指定的section下,按照装填的顺序连续存放。
这里存放的是每个函数的函数入口
其大小为 4个字节
使用MDK 自带的工具 fromelf 输入命令 : fromelf --text -a rt-thread.axf >ex.txt
这里看到三个函数的入口已经按照顺序连续排列,在对比Map文件中的地址 一致,存放于指定的.ledsection中
program1 变量为指向指针的指针。用于遍历section.
int LED_state1(void)
{
rt_thread_sleep(1200);
rt_pin_write(LED0_PIN,1);
rt_pin_write(LED1_PIN,1);
rt_pin_write(LED2_PIN,1);
rt_thread_sleep(1000);
rt_pin_write(LED0_PIN,0);
rt_pin_write(LED1_PIN,1);
rt_pin_write(LED2_PIN,1);
return 0;
}
int LED_state2(void)
{
rt_thread_sleep(1000);
rt_pin_write(LED0_PIN,1);
rt_pin_write(LED1_PIN,1);
rt_pin_write(LED2_PIN,1);
rt_thread_sleep(1000);
rt_pin_write(LED0_PIN,1);
rt_pin_write(LED1_PIN,0);
rt_pin_write(LED2_PIN,1);
return 0;
}
int LED_state3(void)
{
rt_thread_sleep(1000);
rt_pin_write(LED0_PIN,1);
rt_pin_write(LED1_PIN,1);
rt_pin_write(LED2_PIN,1);
rt_thread_sleep(1000);
rt_pin_write(LED0_PIN,1);
rt_pin_write(LED1_PIN,1);
rt_pin_write(LED2_PIN,0);
return 0;
}
typedef int (*Led_ptr)(void);
Led_ptr program;
Led_ptr *program1;
__attribute__((used))Led_ptr (p1) __attribute__((section(".ledsection.")))= LED_state1;
__attribute__((used))Led_ptr (p2) __attribute__((section(".ledsection")))= LED_state2;
__attribute__((used))Led_ptr (p3) __attribute__((section(".ledsection")))= LED_state3;
/*
i.LED_state1 0x080026ea Section 0 main.o(i.LED_state1)
i.LED_state2 0x08002730 Section 0 main.o(i.LED_state2)
i.LED_state3 0x08002776 Section
p1 0x20000244 Data 4 main.o(.ledsection)
p2 0x20000248 Data 4 main.o(.ledsection)
p3 0x2000024c Data 4 main.o(.ledsection)
*/
void app_user_process(void)
{
int i;
while(1)
{
#if 0
for(i=0;i<3;i++)
{
if(i ==0) program = p1;
if(i ==1) program = p2;
if(i ==2) program = p3;
rt_kprintf("program add:%x value %x rn",&program,program);
(*program)();
}
#else
program1 = &p1;
for(i=0;i<3;i++)
{
(*program1)();
program1++;
rt_kprintf(" II program add:%x value %x rn",&program1,program1);
rt_thread_sleep(1000);
}
#endif
}
}
原作者:dengjingg