stm32f103c8 跳转到应用程序不起作用
stm32f103c8 jump to application doesn't work
我写了一个UART引导stm32f103c8的编程器
当通过 MCS bootloader(media uart) 提交 app.bin 文件并进入 stm32f103c8 时,提供成功的数据,然后通过 jumpToApp() 函数 运行 app.bin 。但是 jumpToApp() 不能正常工作。
引导程序代码(写入闪存):
#define APP1_START (0x08005000) //Origin + Bootloader size (20kB)
#define FLASH_BANK_SIZE (0XB000) //44kB
#define FLASH_PAGE_SIZE_USER (0x400) //1kB
unlockFlashAndEraseMemory();
for(iloop=0 ; iloop < 128; iloop+=4)
{
if(Buf[iloop]!=0x1a)
{
flashWord((Buf[iloop+3]<<24)|(Buf[iloop+2]<<16)|(Buf[iloop+1]<<8)|(Buf[iloop]));
}
}
bootloader代码(跳转到app函数):
typedef struct
{
uint32_t stack_addr; // Stack Pointer
application_t* func_p; // Program Counter
} JumpStruct;
void jumpToApp(const uint32_t address)
{
//application_t jump_to_app;
const JumpStruct* vector_p = (JumpStruct*)address;
deinitEverything();
__set_MSP(*(volatile uint32_t*)vector_p->stack_addr);
vector_p->func_p();
}
应用代码:
MX_GPIO_Init();
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_9, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5|GPIO_PIN_7, GPIO_PIN_SET);
while (1)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_9);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5|GPIO_PIN_7);
HAL_Delay(500);
}
应用设置
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS SRAM_BASE
#define VECT_TAB_OFFSET 0x00000000U
#else
#define VECT_TAB_BASE_ADDRESS FLASH_BASE
#define VECT_TAB_OFFSET 0x00005000U
#define FLASH_BASE 0x08005000
app.bin 文件在 flash micro 上正确获取和写入,但它没有 运行。
我在 this link 中使用了一些代码并在 keil ide
中工作
一个可能的问题是,您在 jumpToApp 中设置了堆栈指针,然后从 C 中将重置处理程序作为函数调用。
从 C 调用函数几乎总是涉及调整堆栈指针,这将使其不正确。您需要自动设置堆栈指针,然后跳转到该函数,中间不可能做任何事情。
使用这样的函数从汇编中执行:
Header:
void __attribute__((noreturn)) jumpToApp(uint32_t vector);
来源:
jumpToApp:
ldr r1, [r0]
ldr r2, [r0, 4]
msr msp, r1
mov lr, r2
bx lr
我假设您的 VECT_TAB_OFFSET
设置导致目标应用程序将其自己的向量 table 设置为 SCB-VTOR
。如果没有,那么 jumpToApp 也需要这样做。
我写了一个UART引导stm32f103c8的编程器 当通过 MCS bootloader(media uart) 提交 app.bin 文件并进入 stm32f103c8 时,提供成功的数据,然后通过 jumpToApp() 函数 运行 app.bin 。但是 jumpToApp() 不能正常工作。
引导程序代码(写入闪存):
#define APP1_START (0x08005000) //Origin + Bootloader size (20kB)
#define FLASH_BANK_SIZE (0XB000) //44kB
#define FLASH_PAGE_SIZE_USER (0x400) //1kB
unlockFlashAndEraseMemory();
for(iloop=0 ; iloop < 128; iloop+=4)
{
if(Buf[iloop]!=0x1a)
{
flashWord((Buf[iloop+3]<<24)|(Buf[iloop+2]<<16)|(Buf[iloop+1]<<8)|(Buf[iloop]));
}
}
bootloader代码(跳转到app函数):
typedef struct
{
uint32_t stack_addr; // Stack Pointer
application_t* func_p; // Program Counter
} JumpStruct;
void jumpToApp(const uint32_t address)
{
//application_t jump_to_app;
const JumpStruct* vector_p = (JumpStruct*)address;
deinitEverything();
__set_MSP(*(volatile uint32_t*)vector_p->stack_addr);
vector_p->func_p();
}
MX_GPIO_Init();
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_9, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5|GPIO_PIN_7, GPIO_PIN_SET);
while (1)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_9);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5|GPIO_PIN_7);
HAL_Delay(500);
}
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS SRAM_BASE
#define VECT_TAB_OFFSET 0x00000000U
#else
#define VECT_TAB_BASE_ADDRESS FLASH_BASE
#define VECT_TAB_OFFSET 0x00005000U
#define FLASH_BASE 0x08005000
app.bin 文件在 flash micro 上正确获取和写入,但它没有 运行。 我在 this link 中使用了一些代码并在 keil ide
中工作一个可能的问题是,您在 jumpToApp 中设置了堆栈指针,然后从 C 中将重置处理程序作为函数调用。
从 C 调用函数几乎总是涉及调整堆栈指针,这将使其不正确。您需要自动设置堆栈指针,然后跳转到该函数,中间不可能做任何事情。
使用这样的函数从汇编中执行:
Header:
void __attribute__((noreturn)) jumpToApp(uint32_t vector);
来源:
jumpToApp:
ldr r1, [r0]
ldr r2, [r0, 4]
msr msp, r1
mov lr, r2
bx lr
我假设您的 VECT_TAB_OFFSET
设置导致目标应用程序将其自己的向量 table 设置为 SCB-VTOR
。如果没有,那么 jumpToApp 也需要这样做。