[开发工具] MDK的进阶用法,Sub与Super关键字的使用

[复制链接]
226|3
手机看帖
扫描二维码
随时随地手机跟帖
凉白开|  楼主 | 2022-6-22 14:41 | 显示全部楼层 |阅读模式
本帖最后由 凉白开 于 2022-6-22 14:41 编辑

功能介绍:
      
$Sub$$ $Super$$ MDKARMCC)上特有的关键字,主要作用是替代某个函数和继承原有函数的功能。
l  $Sub$$func()
用于替代func函数,$Sub$$func()函数被定义后,程序中所有调用func()函数的地方将会被替换成$Sub$$func()函数。
l  $Super$$func()
在$Sub$$func()内部使用,在func()被替换后,使用$Sub$$func()可以调用原有func()函数的功能。
应用场景:
l  对于无法修改或重新编译现有符号的情况,可以使用$Sub和$Super链接机制。例如,它位于外部库或ROM代码中。在这种情况下,您可以使用$Super$$和$Sub$$模式来修补现有的符号。
l  通常,将所有系统初始化代码与主应用程序分开是有益的。但是,系统初始化的某些组件,例如缓存和中断的启用,必须在执行 C 库初始化代码之后发生。
l  在进入main函数前,需要对系统进行初始化(时钟、中断、动态内存堆、定时器、调度器、main线程、idle线程等),使用$Sub$$main先调用一些要补充在main之前的功能函数,然后在再调用$Super$$main转到main函数执行。
示例代码:
//  在main函数前初始化底层硬件
void $Sub$main(void)
{
    extern int $Super$main(void);
    USART_Config_T usartConfigStruct;

    /** USART configuration */
    USART_ConfigStructInit(&usartConfigStruct);
    usartConfigStruct.baudRate = 115200;
    usartConfigStruct.mode = USART_MODE_TX_RX;
    usartConfigStruct.parity = USART_PARITY_NONE;
    usartConfigStruct.stopBits = USART_STOP_BIT_1;
    usartConfigStruct.wordLength = USART_WORD_LEN_8B;
    usartConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;

    /** COM1 init*/
    APM_MINI_COMInit(COM1, &usartConfigStruct);
    $Super$main();
}
//在外部库的函数中插入参数判断避免程序出错
int $Sub$ble_send_data(uint8_t *buf , int len)
{
      extern int $Super$ble_send_data(void);
      if(len <= 20)
      {
            return $Super$ble_send_data();
      }
      return 0;
}
//在外部库的函数前插入调试信息
void $Sub$light_lum_ct_set(int lum, int ct)
{
    printf("lum=%d,ct=%d\r\n"mlum,ct);
    $Super$light_lum_ct_set(lum,ct);
}
//代替外部库中的校验功能,绕过芯片校验
int $Sub$chip_id_check(void)
{
      return 1;
}
注意事项:
l  $Sub与$Super要成对使用,而且要在$Sub$$foo中调用$Super$$foo,不能直接调用foo,否则会一直卡在$Sub$$foo中,找不到出口,陷入死循环。
l  在$Super$$foo函数调用上方需要用extern关键字外部声明它,即extern void $Super$$foo(void)。
l  $Sub$$foo、$Super$$foo可以与原函数foo放在不同的C文件中,而且放在同一个C文件中也没有先后顺序之分。
l  不能在原函数foo中,调用$Sub$$foo和$Super$$foo,这属于递归调用。
l  $Sub和$Super机制只在静态链接时起作用,$Super引用不能导入或导出到动态符号表中。
l  foo函数必须是全局或弱定义,如果编译器内联了一个函数,那么就不可以再用替换函数$Sub来修补内联的函数。
l  $Sub和$Super链接器机制只能对工具可见的符号定义和引用进行操作。例如,编译器可以在C程序中将对printf("Hello\n")的调用替换为puts("Hello")。只有对符号puts的引用对链接器可见,因此定义$Sub$$printf不会重定向此调用。

使用特权

评论回复
guijial511| | 2022-6-22 18:57 | 显示全部楼层
了解了,谢谢分享。

使用特权

评论回复
WoodData| | 2022-6-22 23:45 | 显示全部楼层
谢谢分享。

使用特权

评论回复
peipei880| | 2022-6-23 16:28 | 显示全部楼层
谢谢大佬

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则