嵌入式C语言用keil开发
遇到一个以前同事写的程序 ,有一个现象不知道他是怎么做到的
程序分成两个程序 一个是底层程序 这个已经找不到源代码了,只有hex文件,一个是顶层程序
这个产品只有 经历 擦除->>下底层程序->>下顶层程序 才好用,而且走完流程之后 不能再下程序,也不能调试,我想改程序都不好改,只能先暂时新建一个项目重新挪进去
就下面这个照片这个语句我不懂是什么意思,其他的我基本都看了就是一些外设调用,没啥作用. 不知道以前同事是怎么做到这个现象流程的


嵌入式C语言用keil开发
遇到一个以前同事写的程序 ,有一个现象不知道他是怎么做到的
程序分成两个程序 一个是底层程序 这个已经找不到源代码了,只有hex文件,一个是顶层程序
这个产品只有 经历 擦除->>下底层程序->>下顶层程序 才好用,而且走完流程之后 不能再下程序,也不能调试,我想改程序都不好改,只能先暂时新建一个项目重新挪进去
就下面这个照片这个语句我不懂是什么意思,其他的我基本都看了就是一些外设调用,没啥作用. 不知道以前同事是怎么做到这个现象流程的


下午好🌅🌅🌅
本答案参考通义千问
你提到的现象,是典型的嵌入式系统中使用多个程序(或固件)进行引导和切换的场景。这种情况在一些需要多阶段启动(如 Bootloader + Application)的系统中非常常见。
你提到:
.hex 文件,没有源码;这是最常见的实现方式:
| 步骤 | 操作 | 作用 | |------|------|------| | 1 | 擦除整个 Flash | 清除旧程序 | | 2 | 下载 Bootloader | 引导程序,负责加载 Application | | 3 | 下载 Application | 主程序,执行具体功能 | | 4 | 跳转到 Application | 启动主程序 |
注意: 一旦 Bootloader 和 Application 都写入 Flash,通常不能直接重新下载,除非 Bootloader 具备重新烧录的功能(例如通过串口、USB 等)。
这可能是因为:
FLASH_LOCK 或 PWR_LOCK);你提到“下面这个照片这个语句我不懂”,虽然没有图片,但我们可以推测几种可能性:
__attribute__((section(".bootloader"))) void JumpToApp(void) {
uint32_t appAddr = *(uint32_t*)(APP_ADDR);
void (*appEntry)(void) = (void (*)(void))appAddr;
appEntry();
}
__attribute__((section(".bootloader"))):将函数放入特定的段(section),用于链接器脚本定位。APP_ADDR:定义为 Application 的起始地址(如 0x08008000)。JumpToApp():跳转到 Application 的入口函数。重点: 这个函数的作用是让 Bootloader 在完成初始化后,跳转到 Application 的起始地址,从而开始运行主程序。
如果你要自己实现类似功能,可以参考以下步骤:
Bootloader 项目:
.hex 文件;Application 项目:
.hex 文件;APP_ADDR 为合适的地址;在 .ld 文件中指定 Application 的起始地址:
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}
SECTIONS
{
.text : {
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
*(.text*)
. = ALIGN(4);
} > FLASH
.bootloader : {
. = ALIGN(4);
KEEP(*(.bootloader))
. = ALIGN(4);
} > FLASH
.data : {
. = ALIGN(4);
* (.data)
} > RAM AT> FLASH
.bss : {
. = ALIGN(4);
* (.bss)
} > RAM
}
注意: 你需要确保 Bootloader 和 Application 的地址不重叠。
你可以通过以下方法实现:
在 Bootloader 中添加如下代码:
FLASH_Unlock();
FLASH_ErasePage(0x08000000); // 擦除整个 Flash
FLASH_Lock();
或者使用芯片厂商提供的 API 来锁定 Flash。
例如,在 STM32 中,可以通过设置 Option Bytes 来禁止 Flash 写入:
// 设置读保护
HAL_FLASH_OB_Unlock();
OB_DeferredConfig[0] = OB_RDP_LEVEL_1; // 设置为 RDP Level 1
HAL_FLASH_OB_Program(&OB_DeferredConfig);
HAL_FLASH_OB_Lock();
注意: 设置 RDP Level 1 后,Flash 将无法通过 JTAG/SWD 下载,除非使用特定工具解除保护。
| 原因 | 说明 |
|------|------|
| Bootloader + Application 架构 | 使用 Bootloader 负责引导和跳转到 Application |
| Flash 地址分配 | Bootloader 放在低地址,Application 放在高地址 |
| 写保护机制 | 通过 Flash 锁定或 Option Bytes 禁止再次下载 |
| 跳转指令 | 使用 JumpToApp() 函数跳转到 Application 入口 |
objdump 或 Keil 自带工具查看其内容;如果你能提供那句“不懂的语句”的具体内容(如 C 代码或汇编),我可以进一步帮你分析它的作用。