我使用标准代码使用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
答案 0 :(得分:0)
.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
EDIT2:
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由BLANCHTO处理,分支机构只是一个尾部优化传递,只是浪费推动lr那里和分支链接然后返回然后弹出然后返回。
可以将分支实现为内联汇编,但内联汇编通常非常难看,不是可移植的,只是乱七八糟,真正的汇编更加优越,还有一些工具链可以让你直接将它提供给编译器是一个你不知道如何调用汇编程序的情况。我几乎从不运行Windows,所以没有像我想的那样安装Kiel(它们曾经包含一个减少的RVCT编译器,这将很有趣)。