IAP和USER程序之间除LD文件修改外,还有什么地方要修改的吗?

目前我们是使用两款MCU,CH32V307RTC6  和 CH32V203C8T6。
都在研究如何实现远程升级,刚开始开发,还没有完全弄明白。

计划是如此:
CH32V307RTC6 - 通过网络下载

CH32V203C8T6 - 通过串口下载

思路:1)先把生成的bin文件,在User系统下分块下载放至储存区(user2),每块CRC检验
         2)然后写入升级标识,通过

    //soft - 0x00 run t0 BootLoader

    NVIC_SystemReset();


         3)在boot状态把 储存区的 user2 复制至 运行区(User1)
         4)通过下面的代码跳至 User1 区启动

            // 进 机器模式 跳转到 0x5000;

            NVIC_EnableIRQ(Software_IRQn);

            NVIC_SetPendingIRQ(Software_IRQn);


有3点疑问:

IPA的LD文件的设置如此的:
MEMORY

{

    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 20K

    RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K

}


USER的LD文件的设置如此的:

MEMORY

{

    FLASH (rx) : ORIGIN = 0x00005000, LENGTH = 44K

    RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K

}


但在DEMO文件内,描述写入地址分别是

/*@Note

 *bootloader:0x08000000 - 0x08005000  20K

 *UserCode:  0x08005000 - 0x08010000  44K

 *

 */

----------------------------------
疑问1:USER的起始位置: LD文件的是写 0x00050000,但DEMO代码是0x08005000,两者为什么不一样的?
疑问2:除LD的文件配置写入位置偏移外,还有哪些地方配置才能区分 IAP 和 user 的两个启动入口?
           就是它怎么知道?
               通过 NVIC_SystemReset() 是进入 boot 区
               通过 NVIC_EnableIRQ 和 NVIC_SetPendingIRQ 就是进入user 区。
           DEMO说的注释【进 机器模式 跳转到 0x5000】,除了LD设备外,哪个还要修改?

疑问3:通过MounRiver生成的BIN文件,可以直接下载后,直接写入user区,然后启动吗? 中间需要做什么转换不?


您好,关于你的问题:

(1)关于ld文件中FLASH0x000050000x08005000是一样的,硬件做了00x08000000的映射。

(2)关于IAP升级,首先你的代码区域会被分成两个空间,从0地址开始的那段空间存放IAP的代码,后面那段空间存放APP代码,上电后会直接运行IAP的代码,根据你在程序中所设定的条件进行升级或跳转到APP,因此无论复位或上电都会先运行IAP代码。此外,关于通过NVIC_EnableIRQ ?NVIC_SetPendingIRQ 就是进入user 区,这两个函数分别是开启软件中断和挂起,然后就会触发进入中断函数,如下图,中断函数中会进行跳转,跳转到用户区。

image.png

关于你所说的机器模式,我们目前EVT提供的IAP例程都是在用户模式下即可实现,若需要进入机器模式,在启动文件中修改mstatus的值即可,比如将6088改为7888,关于mstatus寄存器的介绍,可参考内核手册,直接在我司官网搜索qingke即可下载

image.png

(3)关于下载升级流程,一般是先下载IAP程序,然后通过IAP升级的方式下载APP程序,我们EVT IAP文件夹下有对应IAP流程讲解,如下图,可以看一下

image.png

后续若有问题,可通过邮箱(lzs@wch.cn)和我沟通


@TECH62


解析得很清楚。非常感谢!

还有个疑问:
以CH32V307RCT6 (FLASH - 256K)为例,LD文件配置

IAP:

MEMORY

{

? ? FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K

? ? RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K

}


USER:

MEMORY

{

? ? FLASH (rx) : ORIGIN = 0x00005000, LENGTH = 256K

? ? RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K

}


把FLASH分成三大部分:
[0 - 0x00005000] - IAP区
[0x00005000 - 0x00020000] - 用户运行代码区(user1)
[0x00020000 - ] - 临时升级文件储存区(user2)


升级原理:
在用户(user1)运行状态,先下载至第三个区(user2),校验完成后,再切入 boot 状态,先把 user1区 擦掉,再把 user2区 复制至 user1区,并进行校验。通过后,软重启过入 user1区 启动。

疑问1:上面这个分区是否合理?目前IPA编译后大小是15K左右, USER编译后58K左右。
疑问2:这个升级原理是否合理?
疑问3:在通过 MouseRiver (hex文件方式) 或 官方的离线烧录器(bin文件方式),烧录写入IAP程序时,会把其它两个区都擦掉吗?


您好,先说一下我对你这流程的理解:

按照我的理解,你的意思是将FLASH分为3个区域(flash1,flash2,flash3),首先将IAP升级代码下载到flash1,然后通过IAP升级的方式将用户代码下载到flash3并进行校验,若检验没问题,再次将程序搬运到flash2区域。

关于你这个流程,可以理解为需要进行两次IAP,且每次IAP跳转的地址是不一样的,该功能理论应该是可以实现的,但没有这么操作过,不懂为何要这么操作,因为正常在进行IAP的时候,写入完成之后通常都会进行校验的,一次就可以了。

关于你的问题:

1、若你IAP固件大小为15K,APP大小为58K,这分区是没问题的,0x5000大小为20K,0x20000大小是128K,是可以容纳你的固件的;

2、关于升级原理,具有操作可行性,但个人感觉没必要这么操作,若是我的理解有问题,你可以通过邮箱和我沟通说明一下;

3、关于烧写流程,就上我上面说的那样,正常你应该先下载IAP程序,然后通过IAP去进行升级,而不是都通过MRS去下载,目前MRS不支持修改地址下载,若你要通过MRS下载,需要进调试模式且需要进行一些修改,建议你直接通过IAP升级的方式。

以上是我的理解和对你问题的回答,若理解有误或后续若有相关问题,可通过邮箱(lzs@wch.cn)和我沟通



关于为什么分成三个区,目前是这样想的:

flash1:仅有一个检测是否需要升级的逻辑,如果有,就从flash3搬至flash2,不含网络连接、下载bin文件等逻辑。
flash2:放平时的运行代码,包含连网、业务逻辑、以及下载bin文件,并放在flash3区。
flash3:仅是临时放远程升级包

flash2的代码是正在运行中的,应该不能一边运行自己一边下载并覆盖自己吧?(我理解是不可以的)
另外,不太想在IAP里面实现下载的逻辑,所以就是flash2里面实现升级下载bin的逻辑。

-------------------
我以为有两种网络远程升级的方式,是这样?
1、在flash2中实现下载代码,在提供业务服务的同时,下载升级bin文件并临时储存至flash3,校验完成后,重启进入flash1,把flash3搬到flash2。
2、从flash2远程重启至flash1,由flash1的代码实现下载,校验完成后,引导至flash2 (不存在flash3)


您好,按照你的描述,我的理解是:

flash1:里面程序仅仅用作判断,产生判断标志以表示是否升级;

flash2:存放了IAP程序+APP程序,根据flash1产生的判断标志判断是运行APP还是IAP;

flash3:存放了待升级的APP程序

首先关于你上面这个逻辑,若flash3仅用于存放待升级固件,那么升级写入的时候写入的APP存放于哪个区域呢?操作逻辑肯定是不能一边运行一边覆盖自己的,只能另外有一个单独的空间。此外,若要进行IAP升级,没必要预先将固件存放在flash3,你在远程进行IAP升级时将所需的固件数据传输过来写入到某个区域就好了,感觉你把这流程搞的有点复杂了,而且IAP程序一般和APP程序都是单独放的。按照你的逻辑,那flash2应该也要被分为两个区域,IAP(包含IAP和的APP)一个区域,APP(存放升级后的flash3中的固件)一个区域。建议你可以去具体了解一下IAP升级的整个过程,然后再考虑一下是否用这种方式,可能是我对于具体产品应用了解较少,不太明白你这种方式的意图,但我目前遇到使用IAP升级方式的一般都是前面所说过的那种思路。关于判断标志以及IAP,完全可以放在一个程序里,我们EVT例程就是,比如通过按键是否按下判断是否要进行升级,若按键按下,则进行升级,没有按下,则直接跳转到APP运行,很简单的一步程序。若要进行IAP升级,比如通过串口,将固件通过上位机传输给单片机,在IAP程序中进行写入编程操作,将APP固件写入到指定区域即可,在写入完成后,可通过读取flash地址数据进行校验,一个IAP,没必要搞的那么复杂。




非常感谢耐心回复,我自行先梳理一下。

现在遇到IAP程序无法跳至 0x5000 (sw_handler没有被调用),要先解决此问题


您好,无法跳转问题参考该帖回复

/bbs/thread-107982-1.html

 



只有登录才能回复,可以选择微信账号登录