gpt4 book ai didi

c - 将程序计数器跳转到新位置

转载 作者:行者123 更新时间:2023-11-30 16:48:09 25 4
gpt4 key购买 nike

我正在使用 keil uvision 使用标准代码将其他程序闪存到我的 stm32f4 板的闪存中。我需要将这两个代码都放在我的板上。但是我如何才能将程序计数器从一个位置转移到另一个位置以便在需要时执行这两个程序。
下面是我正在使用的代码片段,但 PC 没有跳转。我认为跳转到应用程序有问题

#include "usbh_core.h"
#include "usbh_usr.h"
#include "usbh_msc_core.h"
#include "flash_if.h"

USB_OTG_CORE_HANDLE USB_OTG_Core;
USBH_HOST USB_Host;

pFunction Jump_To_Application;
uint32_t JumpAddress;


int main(void)
{

BSP_Init();


FLASH_If_FlashUnlock();



if (STM_EVAL_PBGetState(BUTTON_USER) == Bit_RESET)
{
/* Check Vector Table: Test if user code is programmed starting from address
"APPLICATION_ADDRESS" */
if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
Jump_To_Application = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
__set_PSP(*(__IO uint32_t*) APPLICATION_ADDRESS);

Jump_To_Application();
}
}

/* Init Host Library */
USBH_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USB_Host, &USBH_MSC_cb, &USR_Callbacks);

while (1)
{
/* Host Task handler */
USBH_Process(&USB_OTG_Core, &USB_Host);
}
}


#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{

/* Infinite loop */
while (1)
{}
}
#endif

最佳答案

.global BRANCHTO
BRANCHTO:
bx r0

编辑

用几秒钟的谷歌搜索找到了函数指针基础知识(在 StackOverflow 上也不少)

void (*funadd) ( void );
void fun ( void )
{
funadd=(void *)0x12345678;
(*funadd)();
}

00000000 <fun>:
0: e59f2008 ldr r2, [pc, #8] ; 10 <fun+0x10>
4: e59f1008 ldr r1, [pc, #8] ; 14 <fun+0x14>
8: e5821000 str r1, [r2]
c: e12fff11 bx r1
10: 00000000 andeq r0, r0, r0
14: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000

正如我的汇编函数所示,它做了同样的事情(基本上是尾部优化)

但是如果你想看到它设置一个返回地址,那么你必须强制这样做

unsigned int (*funadd) ( void );
unsigned int fun ( void )
{
funadd=(unsigned int *)0x12345678;
return((*funadd)()+1);
}

00000000 <fun>:
0: e59f201c ldr r2, [pc, #28] ; 24 <fun+0x24>
4: e59f101c ldr r1, [pc, #28] ; 28 <fun+0x28>
8: e92d4010 push {r4, lr}
c: e5821000 str r1, [r2]
10: e1a0e00f mov lr, pc
14: e12fff11 bx r1
18: e8bd4010 pop {r4, lr}
1c: e2800001 add r0, r0, #1
20: e12fff1e bx lr
24: 00000000 andeq r0, r0, r0
28: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000

编辑2:

void BRANCHTO ( unsigned int );
void fun ( void )
{
BRANCHTO(0x12345678);
}

00000000 <fun>:
0: e92d4010 push {r4, lr}
4: e59f0008 ldr r0, [pc, #8] ; 14 <fun+0x14>
8: ebfffffe bl 0 <BRANCHTO>
c: e8bd4010 pop {r4, lr}
10: e12fff1e bx lr
14: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000

LR 由 bl 处理到 BRANCHTO,branchto 只是一个尾部优化传递,只会浪费将 lr 推到那里然后分支链接然后返回然后弹出然后返回。

可以将分支实现为内联汇编,但内联汇编一般来说非常丑陋,不那么可移植,只是一团糟,真正的汇编要优越得多,并且有一个 somet 工具链,允许您将其直接提供给编译器(如果它是)是您不知道如何调用汇编器的情况。我几乎从不运行 Windows,所以没有像我希望的那样安装 Kiel(它们曾经包含一个简化的 RVCT 编译器,使用起来会很有趣)。

关于c - 将程序计数器跳转到新位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43076908/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com