MDK编译器中当原函数已经封装成外部库函数不可修改,或者已经编码烧录在rom中的时候,
可以通过"$ sub $ $" 和 " $ super $ $"标识符对原函数进行打补丁操作;
在rtthread中使用其对main函数进行了补丁操作,扩展了main函数,在调用main函数之前先初始化了rtthread系统;
1.1$ Super$$:标识函数原型,目的是标识函数原型给编译器回调;
1.2$ Sub$$: 标识函数原型的补丁函数,编译器会将补丁函数放到原型函数之前执行;
1.3 用法
//以下demo来自arm mdk开发者手册
//这个demo比较清晰地列出了补丁操作的框架,这个操作可以说十分简单但是考验概念理解力;
//执行完sub函数之后,在sub函数中extern一下 super函数,然后调用super函数回到原函数去执行;
extern void ExtraFunc(void); //补丁操作;
extern void $Super$$foo(void):
void $Sub$$foo(void)
{
ExtraFunc(); //补丁操作;
$Super$$foo(); //通过$Super$$foo()调用函数原型;
}
//以下实例位于components.c
#if defined (__CC_ARM)
extern int $Super$$main(void); //通过$Super$$来标识函数扩展函数原型是main函数;
int $Sub$$main(void) //通过$Sub$$对main函数进行打补丁操作;
{
rt_hw_interrupt_disable();
rtthread_startup();
return 0;
}
#elif defined(__ICCARM__)
//此处省略IAR编译器下的代码....
#elif defined(__GNUC__)
//此处省略在GCC编译器下的代码...
#endif
//components.c
#ifndef RT_USING_HEAP
ALIGN(8)
static rt_uint8_t main_stack[RT_MAIN_THREAD_STACK_SIZE];
struct rt_thread main_thread;
#endif
void main_thread_entry(void *parameter)
{
extern int main(void);
extern int $Super$$main(void);
rt_components_init();
#if defined (__CC_ARM)
$Super$$main(); //在$sub$$main中回调执行原封装好的 main 函数;
#elif defined(__ICCARM__) || defined(__GNUC__)
main();
#endif
}