IAP_05_用户AP程序的起始地址
因为我是一个单片机初学者,不懂汇编和计算机原理,所以继IAP功能成功移植到AI8H1K17后,我只能仿照例程一步步改写自己的代码。一、用户AP起始地址
1.1 我需要检查Flash地址
因为我会用主机MCU对AI8H1K17的Flash写入用户AP固件,所以在ISP程序中,我会对来自主机的写地址做检查:
1.2 手册地址是0x1003
但在上述的判断条件中,“if (addr < 0x1000 || addr > 0x3400)”,
我不知道addr < 0x1000还是addr < 0x1003;
因为在例程提供的手册中,eeprom start 地址是0x1003:
二 结合例程代码理解
2.1 查看DFU_Check
在例程的DFU_Check中:
(*(uint8_t code *)(LDR_SIZE) == 0x02)
检查地址0x1000处是否存在长跳转指令(0x02)
(*(uint16_t code *)(LDR_SIZE + 1) >= LDR_SIZE + 3))
跳转的目标地址大于等于0x1003
2.2 猜测代码逻辑
DFU_Check之所以加上长跳转指令的判断和目标地址的判断,再加上教程中Keil中EEPROM START地址的设置,我猜测:
用户程序的布局应该是这样:
地址0x1000:长跳转指令(LJMP)
地址0x1001-0x1002:跳转目标地址的高字节和低字节
地址0x1003及以后:用户程序的实际代码
固件升级过程:
当升级用户程序时,应该从地址0x1000开始写入
首先写入长跳转指令(0x02)
然后写入跳转目标地址(通常是0x1003或更高)
最后写入用户程序的实际代码
三 结论
所以,用户程序的起始点确实是位于地址0x1000处的长跳转指令,这个指令将控制权转移到用户程序的实际入口点。我的Flash地址判断应该这样写:
根据教程资料:
这个上位机应该是指AIAPP -ISP,是指在下载用户AP固件时,AIAPP -ISP自动在输出的HEX文件中加上复位跳转指令。
在单片机开发中,IAP(In-Application Programming)功能允许用户通过应用程序对Flash存储器进行编程,这在固件升级和参数存储等场景中非常有用。对于初学者来说,理解IAP功能的实现细节确实需要一定的耐心和实践。以下是对您提出的问题的详细解答。
一、用户AP起始地址
1.1 检查Flash地址
在IAP功能中,确保用户AP(Application Program)固件被写入正确的Flash地址是至关重要的。您提到的主机MCU对AI8H1K17的Flash写入用户AP固件时,需要对写地址进行检查。您提供的判断条件为:
c
if (addr < 0x1000 || addr > 0x3400)
这个条件的作用是确保写入的地址在允许的范围内。具体来说,addr < 0x1000 表示地址不能低于0x1000,而 addr > 0x3400 表示地址不能高于0x3400。这样做的目的是防止固件被写入到不应该被修改的区域,比如Bootloader区域或其他关键数据区域。
1.2 手册地址是0x1003
您提到手册中EEPROM的起始地址是0x1003,这与您代码中的0x1000有所不同。这里需要明确的是,EEPROM和Flash是两个不同的存储区域,它们的起始地址可能不同。在您的代码中,0x1000是用户AP固件的起始地址,而0x1003是EEPROM的起始地址。因此,addr < 0x1000 是正确的,因为它确保了固件不会被写入到Bootloader区域(假设Bootloader位于0x0000到0x0FFF之间)。
二、结合例程代码理解
2.1 查看DFUCheck
在例程的DFUCheck函数中,您提到以下代码:
c
((uint8t code )(LDRSIZE) == 0x02)
这行代码的作用是检查地址0x1000处是否存在长跳转指令(0x02)。长跳转指令通常用于跳转到用户AP的入口点。如果该地址处的值为0x02,则说明存在长跳转指令。
c
((uint16t code )(LDRSIZE + 1) >= LDRSIZE + 3)
这行代码检查跳转的目标地址是否大于等于0x1003。这里的逻辑是确保跳转的目标地址在用户AP的合法范围内。
2.2 猜测代码逻辑
DFUCheck函数的逻辑是确保用户AP的入口点正确,并且跳转的目标地址在合法范围内。具体来说,它通过检查0x1000地址处的指令和目标地址来验证用户AP的完整性。如果这些检查通过,则说明用户AP可以被正确加载和执行。
三、总结
对于初学者来说,理解IAP功能的实现细节确实需要一定的耐心和实践。在您的代码中,addr < 0x1000 是正确的,因为它确保了固件不会被写入到Bootloader区域。同时,DFUCheck函数通过检查长跳转指令和目标地址来验证用户AP的完整性。
建议您在继续开发过程中,仔细阅读相关手册和例程代码,逐步理解每个细节。同时,可以通过调试工具(如仿真器或调试器)来验证代码的正确性,这将有助于您更好地掌握单片机开发的技巧。
希望以上解答对您有所帮助,祝您在单片机开发的道路上取得更多进展!
[本文内容由国芯人工智能辅助生成,仅供参考]
页:
[1]