找回密码
 立即注册
查看: 53|回复: 13

IAP_09_ISP程序无法成功跳转到iap

[复制链接]
  • 打卡等级:常住居民II
  • 打卡总天数:98
  • 最近打卡:2025-09-13 09:49:07
已绑定手机

18

主题

45

回帖

596

积分

高级会员

积分
596
发表于 3 天前 | 显示全部楼层 |阅读模式
我使用STC8H1K17,升级流程和逻辑大部分是参照官方例程,目前是:

1、上位机发送bin文件
2、如果全部接收完成并且经过了校验(目前是校验bin的前16字节),设置DfuFlag为DFU_TAG,然后软件复位



截图202509111651208257.jpg

截图202509111651357009.jpg
3、软件复位后进行DFU Check

match的作用
我在app的代码中,会对Flash的固定位置写入固定数据,如果mcu已经加载了app,则去读取Flash中的数据,如果匹配,则表示此mcu已经加载过app了,可以直接跳转app

因为现在刚从isp加载了app,还未进入app,所以判断DfuFlag是否为DFU_TAG,如果是,则表示是刚接收完bin文件,经过软复位跳转过来的

截图202509111652146810.jpg
截图202509111652443902.jpg

从打印信息可以看到,DfuFlag等于DFU_TAG,且else if的判断条件也成立。

现在的问题是,既然进入了else if,为什么没有跳转到app,后面还执行了printf("Stay in·ISP mode\r\n"); ?



而且可以看到,我的bin文件前3个字节是:

截图202509111657316189.jpg


已确认首字节0x02(LMP),再确认目标地址(0x1F6F)确实落在APP已写入且未空洞的区域内。

我的isp工程未使用任何中断,且我尝试过在跳转前关闭中断,复位栈指针,关闭看门狗。

我STC8H1K17 app 在keil的设置,大家看看是不是哪里设置错了:

截图202509111655235891.jpg 截图202509111656175880.jpg

附件:




STC8H_APP.ZIP

532.59 KB, 下载次数: 1

STC8H_ISP.ZIP

453.74 KB, 下载次数: 1

花有重开日,人无再少年
回复

使用道具 举报 送花

3

主题

1989

回帖

826

积分

等待验证会员

积分
826
发表于 3 天前 | 显示全部楼层
根据你提供的信息和代码逻辑,我们来逐步分析你当前遇到的问题:IAP09ISP程序无法成功跳转到App。你的整体设计逻辑是合理的,但存在几个可能影响跳转成功的关键点。

一、问题现象总结
DfuFlag 已正确设置为 DFUTAG,复位后也正确识别;
逻辑判断进入了 else if (DfuFlag == DFUTAG) 分支;
但没有执行跳转 App 的操作,而是继续执行了 printf("Stay in·ISP mode\r\n");;
bin 文件前三个字节为 0x02, 0x6F, 0x1F,即目标地址为 0x1F6F;
Keil 设置的 App 起始地址为 0x1F00,与跳转地址一致;
硬件平台为 STC8H1K17。

二、跳转失败的可能原因分析

1. 函数未正确跳转 App

你代码中使用的是:
  1. c
  2. ((void()(void))APPADDR)();
复制代码

这是一种常见的跳转方式,但有几个前提条件必须满足:

✅ 条件一:App 地址是有效的代码入口地址
你提供的 bin 文件首字节为 0x02(LMP),表示这是一个标准的 STC bin 文件格式;
第 2、3 字节是目标地址 0x1F6F,应为跳转地址;
需要确认该地址是否是 App 的合法入口地址(即 ResetHandler 的地址);
建议查看 App 的反汇编文件或 .map 文件确认入口地址是否为 0x1F6F;

✅ 条件二:App 区域已完整写入且未被破坏
你提到已经接收并校验 bin 文件,但需确认是否完整写入 Flash;
特别注意:STC 单片机 Flash 写入前必须先擦除;
若写入时未正确擦除或写入失败,可能导致跳转地址处数据无效;

✅ 条件三:跳转前关闭所有外设中断及系统中断
跳转前应关闭全局中断、定时器、串口等外设中断;
否则在跳转后中断可能触发,导致行为异常;
示例代码建议:
  1. c
  2. EA = 0;        // 关闭全局中断
  3. TM0C &= ~0x40; // 关闭定时器0中断
复制代码

✅ 条件四:跳转函数执行后不应有任何后续代码
你当前的代码结构如下:
  1. c
  2. else if (DfuFlag == DFUTAG)
  3. {
  4.     ((void()(void))APPADDR)();
  5. }
  6. printf("Stay in·ISP mode\r\n");
复制代码
问题在于:C 编译器并不知道 ((void()(void))APPADDR)(); 是一个跳转函数,不会自动优化后续代码;
即使跳转成功,编译器仍然会生成 printf 的代码,可能导致跳转后执行异常;
建议使用 asm("ljmp 0x1F6F") 或 asm("ljmp APPADDR") 来强制跳转,避免编译器优化干扰。

2. App 地址设置错误或偏移问题
你 Keil 设置的 App 起始地址为 0x1F00,但跳转地址为 0x1F6F;
需要确认 0x1F6F 是否确实是 App 的 ResetHandler 地址;
可以通过 Keil 的 .map 文件查看 App 的入口地址;
若 App 的入口地址不是 0x1F6F,则跳转失败;

3. DfuFlag 清除时机问题
你设置了 DfuFlag = DFUTAG,然后软复位;
复位后进入 DFU Check,判断 DfuFlag == DFUTAG;
但如果你没有在跳转前清除 DfuFlag,下次复位还会进入 DFU 模式;
建议在跳转前清除标志位,防止死循环;

三、建议修改方案

✅ 修改跳转方式为汇编跳转
  1. c
  2. if (DfuFlag == APPVALIDTAG)
  3. {
  4.     asm("ljmp 0x1F6F"); // 使用汇编跳转
  5. }
复制代码

✅ 清除 DfuFlag 标志
  1. c
  2. if (DfuFlag == DFUTAG)
  3. {
  4.     DfuFlag = 0;
  5.     WriteFlashFlag(); // 将标志写入 Flash 或 EEPROM
  6.     asm("ljmp 0x1F6F");
  7. }
复制代码

✅ 关闭中断及外设
  1. c
  2. EA = 0;
  3. TM0C &= ~0x40;
  4. TM1C &= ~0x40;
复制代码

四、App 编译配置建议
App 起始地址应设置为 0x1F00;
中断向量表偏移应设置为 0x1F00;
Keil 中应勾选“Use Memory Layout from Target Dialog”;
确保链接脚本或 scatter 文件正确配置了 App 地址空间;
生成的 bin 文件应使用 fromelf 或 sreccat 工具验证起始地址;

五、其他调试建议

1. 使用调试器查看跳转地址内容:
打开 Keil uVision,进入 Memory 窗口;
查看 0x1F6F 地址处是否有合法的指令码(如 LJMP、MOV 等);
若为 0xFF 或其他无效码,说明 App 写入失败;

2. 验证 Flash 写入流程:
确认写入前是否擦除了目标扇区;
写入过程中是否发生错误(如地址越界、长度错误);

3. 使用串口打印辅助调试:
在跳转前加入 printf("Jump to App at 0x1F6F\r\n");;
若该打印出现但未跳转,说明跳转失败;

六、总结

你当前的跳转失败,主要可能原因如下:

| 原因 | 说明 | 建议 |
|------|------|------|
| 跳转方式问题 | C 函数跳转不可靠 | 改为汇编 ljmp |
| App 地址不匹配 | 跳转地址非合法入口 | 检查 .map 文件 |
| App 写入失败 | Flash 写入未完成或出错 | 检查写入流程 |
| 中断未关闭 | 跳转后中断干扰 | 跳转前关闭中断 |
| DfuFlag 未清除 | 导致反复进入 DFU | 跳转前清除标志 |

七、结语

IAP 开发是一个涉及 Bootloader、Flash 操作、地址跳转、中断管理等多个模块的复杂过程,建议你在调试过程中:
使用调试器辅助分析;
保持代码逻辑清晰;
逐步验证每个模块的功能;
最终确保跳转流程完全可靠。

如需进一步协助,欢迎提供 .map 文件片段、bin 文件写入流程代码、Flash 写入函数等详细信息。

祝你调试顺利!

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:297
  • 最近打卡:2025-09-13 09:56:50
已绑定手机

82

主题

3111

回帖

6879

积分

荣誉版主

无情的代码机器

积分
6879
发表于 3 天前 | 显示全部楼层
方便上传完整工程看看?

这个APP主程序什么都没干就退出了?
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:98
  • 最近打卡:2025-09-13 09:49:07
已绑定手机

18

主题

45

回帖

596

积分

高级会员

积分
596
发表于 3 天前 | 显示全部楼层
erci*** 发表于 2025-9-11 17:21
方便上传完整工程看看?

这个APP主程序什么都没干就退出了?

您好,iap和app已经补充到文末
花有重开日,人无再少年
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:297
  • 最近打卡:2025-09-13 09:56:50
已绑定手机

82

主题

3111

回帖

6879

积分

荣誉版主

无情的代码机器

积分
6879
发表于 3 天前 | 显示全部楼层
1.将与APP IAP跳转无关功能暂时注释掉,调通功能后再联调,减少耦合影响。

2.关注一下告警,APP中未定义DFUFLAG
3.建议全局变量在主函数内初始化,而不是声明时初始化,尤其是data空间内的
4.读取APP位置前12个字节不应该这么多0,ISP+APP联合烧录方法参考我此贴:
一种简单合并ISP和APP程序文件的方法 - ISP下载/做自己的ISP 国芯人工智能技术交流网站 - AI32位8051交流社区
截图202509111802359283.jpg

截图202509111754523088.jpg

截图202509111756125948.jpg
截图202509111756584893.jpg
截图202509111757135495.jpg
新手必读!新手必读!新手必读!新手必读!新手必读!新手必读!新手必读!新手必读! - 老鸟反刍/吐槽,新手乐园,毕业设计 国芯人工智能技术交流网站 - AI32位8051交流社区
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:98
  • 最近打卡:2025-09-13 09:49:07
已绑定手机

18

主题

45

回帖

596

积分

高级会员

积分
596
发表于 前天 09:43 | 显示全部楼层
erci*** 发表于 2025-9-11 18:03
1.将与APP IAP跳转无关功能暂时注释掉,调通功能后再联调,减少耦合影响。

2.关注一下告警,APP中未定义DF ...

会不会是我的hex转bin工具,导致bin文件出错了?你们是怎么将stc的hex文件转成bin文件的?

点评

使用ISP加载hex,点击保存数据,再用winhex编辑也可自己定义程序读写合并。 可以先用我上面发的合并烧录方法验证 [attachimg]114830[/attachimg]  详情 回复 发表于 前天 09:48
花有重开日,人无再少年
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:297
  • 最近打卡:2025-09-13 09:56:50
已绑定手机

82

主题

3111

回帖

6879

积分

荣誉版主

无情的代码机器

积分
6879
发表于 前天 09:48 | 显示全部楼层
zho*** 发表于 2025-9-12 09:43
会不会是我的hex转bin工具,导致bin文件出错了?你们是怎么将stc的hex文件转成bin文件的? ...

使用ISP加载hex,点击保存数据,再用winhex编辑也可自己定义程序读写合并。
可以先用我上面发的合并烧录方法验证

截图202509120947225063.jpg

三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:98
  • 最近打卡:2025-09-13 09:49:07
已绑定手机

18

主题

45

回帖

596

积分

高级会员

积分
596
发表于 前天 10:24 | 显示全部楼层
erci*** 发表于 2025-9-12 09:48
使用ISP加载hex,点击保存数据,再用winhex编辑也可自己定义程序读写合并。
可以先用我上面发的合并烧录 ...

我使用你发送的合并烧录方法,结果还是没有跳转到app。

先确认下操作:

1、按照合并烧录方法,得到一份all.bin文件
我的app.hex还是按照之前的方法编译得到的
截图202509121022264022.jpg 截图202509121022467455.jpg

2、按照之前的isp加载app教程,设置stcisp,烧录isp.hex


截图202509121019546898.jpg

3、上位机发送all.bin

看下是不是这3个步骤哪里错了。我感觉是有问题的,因为app.bin是从EEPROM的0地址写入,现在的all.bin还增加了isp的部分,再从EEPROM的0地址写入,这不是额外增加了数据吗


花有重开日,人无再少年
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:297
  • 最近打卡:2025-09-13 09:56:50
已绑定手机

82

主题

3111

回帖

6879

积分

荣誉版主

无情的代码机器

积分
6879
发表于 前天 10:31 | 显示全部楼层
1、按照合并烧录方法,得到一份all.bin文件
2、按照之前的isp加载app教程,设置stcisp,烧录isp.hex

这个表述到底是烧录all.bin还是isp.hex呢,楼上的合并烧录有操作视频,应该就EEPROM大小选项不一样而已,可以按照视频操作。

另外EEPROM的IAP操作由0开始,但是现在APP在EEPROM区,所以要自己偏移APP大小,不然APP程序代码就被破坏。

可以发下修改后的工程我试下
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:98
  • 最近打卡:2025-09-13 09:49:07
已绑定手机

18

主题

45

回帖

596

积分

高级会员

积分
596
发表于 前天 10:37 | 显示全部楼层
erci*** 发表于 2025-9-12 10:31
1、按照合并烧录方法,得到一份all.bin文件
2、按照之前的isp加载app教程,设置stcisp,烧录isp.hex

单片机肯定要有程序来接收我电脑发送的bin文件,所以我得到all.bin后,给stc烧录了isp.hex,用来接收电脑发送的all.bin


STC8H_APP.ZIP

190.81 KB, 下载次数: 1

STC8H_ISP.ZIP

56.54 KB, 下载次数: 1

点评

单片机不接收all.bin! ISP区不可改写,单片机程序只修改APP区! 另外直接直接ISP烧录all.bin先测~,这又加进来个上位机因素,上位机有没有测过功能是否正常呢? 各个功能能独立调试的,调试完成再进行联调,  详情 回复 发表于 前天 10:40
花有重开日,人无再少年
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-9-14 06:24 , Processed in 0.158704 second(s), 110 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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