硬汉嵌入式论坛

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

[STM32H7] STM32H723 OTA 手动在固件前加头部后,某些函数无法正常使用

[复制链接]

8

主题

35

回帖

59

积分

初级会员

积分
59
发表于 2024-8-23 10:32:03 | 显示全部楼层 |阅读模式
本帖最后由 SJUMP 于 2024-8-23 11:02 编辑

首先生成了一个 .bin 文件,然后使用上位机C语言,在.bin 前面加了 4K 的头部字节,参考:BSP视频教程第19期:单片机BootLoader的AES加密实战,含上位机和下位机代码全开源_哔哩哔哩_bilibili。然后下载进去,发现程序能正常跳转到 app 运行,但是在详细测试的时候,发现某些函数指针的返回不正常,本来指针返回出来应该是 2 ,结果编程了0。

做了以下几种尝试(下面都是使用的同一个 bin 文件):
1. 放弃头部,直接下载 bin 固件到指定地址,所有函数能正常返回。
2. 先下载头部进去,不擦出 flash ,再把 .bin 文件下载到指定地址,所有函数能正常返回。
3.将 bin 文件和 头部先组合到一起再下载进去,能运行,但是某些函数返回值不正常。
  在 3 的情况下 使用 二进制对比软件看了,除了 头部 4k 不一样,后面的字节全部都是一样的。

异常情况下寄存器值:

异常情况下,进入函数前寄存器值

异常情况下,进入函数前寄存器值

异常情况下,退出函数后寄存器值

异常情况下,退出函数后寄存器值


正常情况下寄存器的值:

正常情况下,进入函数前寄存器值

正常情况下,进入函数前寄存器值

正常情况下,退出函数后寄存器值

正常情况下,退出函数后寄存器值


在 map 文件里面找到 R3 的地址:
屏幕截图 2024-08-23 110120.jpg
[C] 纯文本查看 复制代码
#define SET_VECTOR_TABLE (1)
#define ENABLE_INT() __set_PRIMASK(0)
#define DISABLE_INT() __set_PRIMASK(1)
void jump_to_app(uint32_t app_boot_address)
{
        uint32_t i=0;

        static void (*SysMemBootJump)(void);  

        static __IO uint32_t BootAddr;
        BootAddr = app_boot_address+CODE_BEGIN_OFFSET; 

        DISABLE_INT();

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

        /* 设置所有时钟到默认状态,使用 HSI 时钟 */
        HAL_RCC_DeInit();
        HAL_DeInit();

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

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

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

#if(SET_VECTOR_TABLE)
    SCB->VTOR = BootAddr;
#endif
        
        /* 设置主堆栈指针 */
        __set_MSP(*(uint32_t *)BootAddr);
        
        /* 在 RTOS 工程,这条语句很重要,设置为特权级模式,使用 MSP 指针 */
        __set_CONTROL(0);

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

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

        }
}




回复

使用道具 举报

8

主题

35

回帖

59

积分

初级会员

积分
59
 楼主| 发表于 2024-8-23 14:53:10 | 显示全部楼层
在情况3,使用 cubeprogrammer 将程序读取出来对比,也是一模一样的。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117564
QQ
发表于 2024-8-23 15:11:28 | 显示全部楼层
SJUMP 发表于 2024-8-23 14:53
在情况3,使用 cubeprogrammer 将程序读取出来对比,也是一模一样的。

已经测试分别下载和组合下载后,读取出来完全一样,这个已经确定了吧。

如果已经确定了,那基本可以确信你的程序是有问题。下载版本后,把下载器等所有外挂从板子端拔掉,重新上电试试。
回复

使用道具 举报

8

主题

35

回帖

59

积分

初级会员

积分
59
 楼主| 发表于 2024-8-23 15:59:11 | 显示全部楼层
eric2013 发表于 2024-8-23 15:11
已经测试分别下载和组合下载后,读取出来完全一样,这个已经确定了吧。

如果已经确定了,那基本可以确 ...


是的,已经把整个 flash 读取出来对比了,程序部分是没有任何区别的。
拔掉下载器,重新上电都试过,没用。
如果是程序问题,应该都不行才对呀!为什么单独下载就能行呢?


经过测试发现,只有在指定的地址(图中圈红部分),有 0x6B 出现,才会出现这个情况,把 0x6b 换成其它数字,或者将 0x6b 放到其它位置都是没有问题的。
圈红部分:
0xFF6B0000 不行

0xFF6A0000 可以

0xFF220000 可以



0xFF006B00 可以
0xFF00006B 可以



图中的基地址是 0x08020000 。
01.png 02.png
回复

使用道具 举报

8

主题

35

回帖

59

积分

初级会员

积分
59
 楼主| 发表于 2024-8-23 16:47:47 | 显示全部楼层
在情况1 ,直接把程序下载指定偏移地址,然后 bootloader 直接跳转过来。在这个基础上,加一个写入 0x6b ,到出问题的地址。
第一个循环,没有写入 0x6b ,函数正常,o_stream.bytes_written==2。第二个循环过来时,已经写入 0x6b ,此时函数已经异常,o_stream.bytes_written==0。

03.png


回复

使用道具 举报

8

主题

35

回帖

59

积分

初级会员

积分
59
 楼主| 发表于 2024-8-23 19:05:47 | 显示全部楼层

不知道为什么这些内存的值在 写入 0x6b 之后,就变成了 0xffffffff 。
0xa5a5a5a5 是正常的。
0xffffffff 是异常的。
zzz01.jpg zzz02.jpg
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117564
QQ
发表于 2024-8-24 08:55:54 | 显示全部楼层
SJUMP 发表于 2024-8-23 15:59
是的,已经把整个 flash 读取出来对比了,程序部分是没有任何区别的。
拔掉下载器,重新上电都试过, ...

这个位置应该是中断向量表的保留位置。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117564
QQ
发表于 2024-8-24 08:56:26 | 显示全部楼层
SJUMP 发表于 2024-8-23 19:05
不知道为什么这些内存的值在 写入 0x6b 之后,就变成了 0xffffffff 。
0xa5a5a5a5 是正常的。
0xffffff ...

通过你的这些描述,我觉得你程序应该是有问题的。
回复

使用道具 举报

8

主题

35

回帖

59

积分

初级会员

积分
59
 楼主| 发表于 2024-8-24 13:11:40 | 显示全部楼层
eric2013 发表于 2024-8-24 08:55
这个位置应该是中断向量表的保留位置。

中断向量表我是放在 0x08021000 的位置,偏移了 4KB。 中断向量表还会自己再保留一份在 0x08020000 吗?
回复

使用道具 举报

8

主题

35

回帖

59

积分

初级会员

积分
59
 楼主| 发表于 2024-8-24 13:13:44 | 显示全部楼层
eric2013 发表于 2024-8-24 08:56
通过你的这些描述,我觉得你程序应该是有问题的。

哥,这个可能会是那些原因导致的呢?能说一些可能的原因吗?
回复

使用道具 举报

8

主题

35

回帖

59

积分

初级会员

积分
59
 楼主| 发表于 2024-8-24 16:37:06 | 显示全部楼层
eric2013 发表于 2024-8-24 08:56
通过你的这些描述,我觉得你程序应该是有问题的。


找了半天,确实是程序的问题。
0x6b 是一个标志位, 那个位置是 0x6b 就会判断是有效的,而有效的枚举值就是 0 。
这算是 protobuf 的一个小坑吧,它规定枚举值必须要从 0 开始,但是它没有介绍说枚举值为 0  时,序列化之后数据长度是 0 ,导致我以为是哪里有问题。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117564
QQ
发表于 2024-8-25 10:20:27 | 显示全部楼层
SJUMP 发表于 2024-8-24 13:11
中断向量表我是放在 0x08021000 的位置,偏移了 4KB。 中断向量表还会自己再保留一份在 0x08020000 吗?

忘了你的问题了,你的前面还有4K的bin
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-14 21:04 , Processed in 0.061453 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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