一、简介
官方说明链接:https://developer.arm.com/documentation/dui0377/g/pge1362065967698
ARM链接器提供$Super$$ 和$Sub$$ 关键字用来为一些无法修改的函数打补丁。 这是一种特殊模式:用于有一个已经存在且不能被改变的函数的情况(比如不能更改的库函数);使用这两个模式可以帮原函数打补丁,如存在一个函数foo() ;
$Sub$$foo :定义的新功能函数,在foo() 函数之前/后使用$Sub$$foo 可以添加一些新的程序代码。
$Super$$foo :就是原始的未修补的foo函数,使用这个$Super$$foo 函数将直接跳转到foo() 函数。
二、测试
1、创建一个工程,使用串口发送"$Super$$foo(void)\r\n" 字符串。
void foo(void){
HAL_UART_Transmit(&huart1,(uint8_t*)"-----------------\r\n",19,100);
HAL_UART_Transmit(&huart1,(uint8_t*)"$Super$$foo(void)\r\n",19,100);
HAL_UART_Transmit(&huart1,(uint8_t*)"-----------------\r\n",19,100);
}
2、在main 函数中调用
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
foo();
while (1)
{
}
}
3、编译、烧录、启动,在串口输出信息如下 4、在main 函数外添加补丁函数,main 函数调用foo 函数
void $Sub$$foo(void)
{
HAL_UART_Transmit(&huart1,(uint8_t*)"====================\r\n",22,100);
HAL_UART_Transmit(&huart1,(uint8_t*)"void $Sub$$foo(void)\r\n",22,100);
HAL_UART_Transmit(&huart1,(uint8_t*)"====================\r\n",22,100);
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
foo();
while (1)
{
}
}
5、串口输入信息如下 通过以上输出发现,只执行补丁函数,而未执行原来foo函数。 6、在补丁函数中调用原来函数,在代码中添加如下信息
extern void $Super$$foo(void);
void $Sub$$foo(void)
{
HAL_UART_Transmit(&huart1,(uint8_t*)"====================\r\n",22,100);
HAL_UART_Transmit(&huart1,(uint8_t*)"void $Sub$$foo(void)\r\n",22,100);
$Super$$foo();
HAL_UART_Transmit(&huart1,(uint8_t*)"====================\r\n",22,100);
}
7、串口输出信息如下 通过以上输出信息,可以看出先执行foo补丁函数,再执行foo函数,执行完foo函数后再次执行补丁函数。 8、调整补丁函数执行顺序
extern void $Super$$foo(void);
void $Sub$$foo(void)
{
HAL_UART_Transmit(&huart1,(uint8_t*)"====================\r\n",22,100);
HAL_UART_Transmit(&huart1,(uint8_t*)"void $Sub$$foo(void)\r\n",22,100);
HAL_UART_Transmit(&huart1,(uint8_t*)"====================\r\n",22,100);
$Super$$foo();
}
9、串口输出信息如下
三、总结
通过以上分析,可以通过ARM链接器提供$Super$$ 和$Sub$$ 功能在原有函数前或后插入其他代码,对原有函数打补丁。
|