硬汉嵌入式论坛

 找回密码
 立即注册
查看: 591|回复: 9
收起左侧

[BOOT/IAP] Bootloader无法跳转掉带有RTX系统的App中的问题

[复制链接]

20

主题

94

回帖

154

积分

初级会员

积分
154
发表于 2024-2-18 20:21:20 | 显示全部楼层 |阅读模式
本帖最后由 ifree 于 2024-2-18 20:25 编辑

调试一天,发现一个Bootloader无法跳转掉带有RTX系统的App中的问题。


1、Bootloader代码
BootTest.zip (13.15 MB, 下载次数: 0)
[C] 纯文本查看 复制代码
#define AppAddr                0x08100000
void DirectJumpToApp(void)
{
        void (*AppJump)(void);         /* 声明一个函数指针 */
        /* 跳转到应用程序,首地址是MSP,地址+4是复位中断服务程序地址 */
        AppJump = (void (*)(void)) (*((uint32_t *) (AppAddr + 4)));
        /* 设置主堆栈指针 */
        __set_MSP(*(uint32_t *)AppAddr);
        
        __set_CONTROL(0);
        
        /* 跳转到系统App */
        AppJump(); 
}

/*
*********************************************************************************************************
*        函 数 名: main
*        功能说明: c程序入口
*        形    参: 无
*        返 回 值: 错误代码(无需处理)
*********************************************************************************************************
*/
int main(void)
{
        DirectJumpToApp();
        bsp_Init();                /* 硬件初始化 */
        DemoFatFS();    /* SD卡测试 */
}

作为测试,main一加载就直接跳转到App中,这样的话应该算“干净”的Bootloader了。

2、裸机工程

BootAppTest.zip (9.1 MB, 下载次数: 0)
直接改工程ROM到0x08100000,测试中,Bootloader可以正常跳转到该测试工程中运行。

3、用RTE创建的测试工程
RTX_AppTest.zip (2.37 MB, 下载次数: 0)
(1)软件版本
MDK 5.38
ARM CMSIS 5.8.0
ARM_Compiler 1.7.2
MDK_Middleware 7.16.0
STM32H7xx DFP 2.8.0
(2) 测试1
该工程闪烁一个LED,通过串口每秒输出字符串"test app"。
将代码ROM设置为 0x0800 0000,下载到开发板,可以正常运行,实现功能。
(3) 测试2
将代码ROM设置为 0x0810 0000,下载到开发板,通过调试代码,发现最终直接停到这个main里面的while(1), 并不跳转到AppTaskStart任务当中去运行。
[C] 纯文本查看 复制代码
int main (void) 
{ 
        /* HAL库,MPU,Cache,时钟等系统初始化 */
        System_Init();

        /* 内核开启前关闭HAL的时间基准 */
        HAL_SuspendTick();
        
        /* 内核初始化 */
        osKernelInitialize();                                  

/* 创建启动任务 */
        ThreadIdStart = osThreadNew(AppTaskStart, NULL, &ThreadStart_Attr);  

        /* 开启多任务 */
        osKernelStart();
        
        while(1);
}

这里看上去是osKernelStart直接返回了,然后就卡到后面的while(1)里面了。

大佬们,可以帮忙看看到底是什么问题吗?

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106738
QQ
发表于 2024-2-19 01:23:00 | 显示全部楼层
这个例子有参考过没。

分享个基于STM32H7的BOOT和APP代码都使用RTX5的案例,相互之间任意跳转
https://www.armbbs.cn/forum.php? ... 7247&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

20

主题

94

回帖

154

积分

初级会员

积分
154
 楼主| 发表于 2024-2-19 05:50:52 | 显示全部楼层
谢谢硬汉哥。参考上面的例子,终于找到问题。

[C] 纯文本查看 复制代码
/************************* Miscellaneous Configuration ************************/
/*!< Uncomment the following line if you need to use initialized data in D2 domain SRAM (AHB SRAM) */
/* #define DATA_IN_D2_SRAM */

/* Note: Following vector table addresses must be defined in line with linker
         configuration. */
/*!< Uncomment the following line if you need to relocate the vector table
     anywhere in FLASH BANK1 or AXI SRAM, else the vector table is kept at the automatic
     remap of boot address selected */
#define USER_VECT_TAB_ADDRESS

#if defined(USER_VECT_TAB_ADDRESS)
#if defined(DUAL_CORE) && defined(CORE_CM4)
/*!< Uncomment the following line if you need to relocate your vector Table
     in D2 AXI SRAM else user remap will be done in FLASH BANK2. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS   D2_AXISRAM_BASE   /*!< Vector Table base address field.
                                                       This value must be a multiple of 0x400. */
#define VECT_TAB_OFFSET         0x00000000U       /*!< Vector Table base offset field.
                                                       This value must be a multiple of 0x400. */
#else
#define VECT_TAB_BASE_ADDRESS   FLASH_BANK2_BASE  /*!< Vector Table base address field.
                                                       This value must be a multiple of 0x400. */
#define VECT_TAB_OFFSET         0x00000000U       /*!< Vector Table base offset field.
                                                       This value must be a multiple of 0x400. */
#endif /* VECT_TAB_SRAM */
#else
/*!< Uncomment the following line if you need to relocate your vector Table
     in D1 AXI SRAM else user remap will be done in FLASH BANK1. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS   D1_AXISRAM_BASE   /*!< Vector Table base address field.
                                                       This value must be a multiple of 0x400. */
#define VECT_TAB_OFFSET         0x00000000U       /*!< Vector Table base offset field.
                                                       This value must be a multiple of 0x400. */
#else
#define VECT_TAB_BASE_ADDRESS   FLASH_BANK1_BASE  /*!< Vector Table base address field.
                                                       This value must be a multiple of 0x400. */
#define VECT_TAB_OFFSET         0x00100000U       /*!< Vector Table base offset field.
                                                       This value must be a multiple of 0x400. */
#endif /* VECT_TAB_SRAM */
#endif /* DUAL_CORE && CORE_CM4 */
#endif /* USER_VECT_TAB_ADDRESS */
/******************************************************************************/


需要在system_stm32h7xx.c这个文件里面修改VECT_TAB_OFFSET 宏,修改向量表所在地址,把这个给忘了,导致浪费时间。
裸机的工程是用的您的示例工程修改的,修改向量表的宏已经改过了,RTX的工程是从头创建的。

PS:我另一个年前创建的工程,用Bootloader跳转到0x08100000,使用仿真可以跑起来,但是直接运行却跑不起来,好奇怪。
回复

使用道具 举报

20

主题

94

回帖

154

积分

初级会员

积分
154
 楼主| 发表于 2024-2-19 12:48:22 | 显示全部楼层
这个Bootloader还是有问题。问题表现为

1、当App功能比较简单时,可以正常跳转运行。
2、当App引入功能比较多后,Bootloader跳转到App后运行不起来。
3、App修改了两个地方,第一个是ROM地址配置为0x0810_0000,第二个地方是上面提到的VECT_TAB_OFFSET。
4、为了查找问题方便,Bootloader已经写成进入到main没有其他任何操作,直接跳转到App。在App里,有时候通过Debug来仿真运行,程序可以跑起来,有时候不断点复位,App连main都进不去。
5、App把ROM和VECT_TAB_OFFSET改回到正常的0x0800_0000,程序可以正常运行。

不知道Bootloader和App是不是还有什么东西需要注意。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106738
QQ
发表于 2024-2-20 00:13:01 | 显示全部楼层
ifree 发表于 2024-2-19 12:48
这个Bootloader还是有问题。问题表现为

1、当App功能比较简单时,可以正常跳转运行。

APP运行卡住位置能锁定不,还是说这个位置是随机的。
回复

使用道具 举报

5

主题

192

回帖

212

积分

高级会员

积分
212
发表于 2024-2-20 09:42:58 | 显示全部楼层
ifree 发表于 2024-2-19 12:48
这个Bootloader还是有问题。问题表现为

1、当App功能比较简单时,可以正常跳转运行。

我之前也遇到过,改动了下硬汉的跳转函数就没问题了

[C] 纯文本查看 复制代码
/* 开关全局中断的宏 */
#define ENABLE_INT()    __set_PRIMASK(0) /* 使能全局中断 */
#define DISABLE_INT()   __set_PRIMASK(1) /* 禁止全局中断 */

static void JumpToBootloader(void)
{
    uint32_t i = 0;
    /* 声明一个函数指针 */
    void (*SysMemBootJump)(void);
    /* APP 地址 */
    __IO uint32_t BootAddr = FLASH_USER_START_ADDR;
    
    /* 设置所有时钟到默认状态,使用HSI时钟 */
    HAL_RCC_DeInit();
    
    /* 关闭全局中断 */
    DISABLE_INT(); 

    /* 关闭滴答定时器,复位到默认值 */
    SysTick->CTRL = 0;
    SysTick->LOAD = 0;
    SysTick->VAL = 0;

    /* 关闭所有中断,清除所有中断挂起标志 */
    for (i = 0; i < 8; i++)
    {
        NVIC->ICER[i]=0xFFFFFFFF;
        NVIC->ICPR[i]=0xFFFFFFFF;
    }

    /* 使能全局中断 */
    ENABLE_INT();

    /* 跳转到系统BootLoader,首地址是MSP,地址+4是复位中断服务程序地址 */
    SysMemBootJump = (void (*)(void)) (*((__IO uint32_t *) (FLASH_USER_START_ADDR + 4)));

    /* 设置主堆栈指针 */
    __set_MSP(*(uint32_t *)FLASH_USER_START_ADDR);

    /* 在RTOS工程,这条语句很重要,设置为特权级模式,使用MSP指针 */
    __set_CONTROL(0);

    /* 跳转到系统BootLoader */
    SysMemBootJump(); 

    /* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */
    while (1)
    {

    }
}
回复

使用道具 举报

3

主题

1222

回帖

1231

积分

至尊会员

积分
1231
发表于 2024-2-20 14:14:29 | 显示全部楼层
这是改动了哪里?
回复

使用道具 举报

20

主题

94

回帖

154

积分

初级会员

积分
154
 楼主| 发表于 2024-2-24 17:24:42 | 显示全部楼层
eric2013 发表于 2024-2-20 00:13
APP运行卡住位置能锁定不,还是说这个位置是随机的。

App运行卡住,调试器完全无法调试了,只能点运行和停止,但停下来也不知道停在什么地方。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106738
QQ
发表于 2024-2-26 08:20:00 | 显示全部楼层
ifree 发表于 2024-2-24 17:24
App运行卡住,调试器完全无法调试了,只能点运行和停止,但停下来也不知道停在什么地方。

那只能排查法了。
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2024-3-5 17:48:47 | 显示全部楼层
尝试使用全局静态变量存储SysMemBootJump , 一般是 改了堆栈指针,导致跳转地址被破坏了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-3 02:16 , Processed in 0.346958 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表