16回答

3收藏

[分享] 五、GD32F207的IAP下载

 

GD32 GD32 12586 人阅读 | 16 人回复 | 2016-02-29

本帖最后由 9robot 于 2016-3-3 19:03 编辑

昨天把GD32F207的内部FLASH学习了一下,掌握了简单的页擦除和flash编程(32位数据)。今天迫不及待地想试试GD32用iap的方式下载应用程序。要想实现该功能,最重要的是制作一个bootloader。
bootloader程序中使用到的知识主要有串口(我用的是串口,当然也可以是USB、IIC、SPI等通讯方式)、内部FLASH编程,还有比较重要的是C中指针的知识,指针功能太强大了,也就让它的使用变得很复杂,一不小心会出错,扯远了。利用指针可以指向一个函数来实现程序的跳转,类似于调用。这部分知识,我参考了C primer plus 第五版第413页函数和指针的知识。
正常的代码执行流程如下图


iap程序是在FMC程序的基础上编写的,只有两个函数,一个函数是将串口接收到的bin文件写到设定好的flash地址中,第二个函数是跳转到app程序中,需要对中断向量表进行偏移设置。
  1. void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 appsize)
  2. {
  3.         u32 t;
  4.         u16 i=0;
  5.         u32 temp;
  6.         u32 fwaddr=appxaddr;//
  7.         u8 *dfu=appbuf;
  8.         for(t=0;t<appsize;t+=4)
  9.         {
  10.         
  11.                 temp=(u32)dfu[3]<<24;
  12.                 temp|=(u32)dfu[2]<<16;
  13.                 temp|=(u32)dfu[1]<<8;
  14.                 temp|=(u32)dfu[0];
  15.                 dfu+=4;//
  16.                 iapbuf[i++]=temp;
  17.                 if(i==512)
  18.                 {
  19.                   i=0;
  20.                         GD32FMC_Write(fwaddr,iapbuf,512);
  21.                         fwaddr+=2048;//
  22.                 }        
  23.         }
  24.         if(i)
  25.                         GD32FMC_Write(fwaddr,iapbuf,i);//
  26. }
复制代码
  1. void iap_load_app(u32 appxaddr)
  2. {
  3.         if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)
  4.         {
  5.                 jump2app=(iapfun)*(vu32*)(appxaddr+4);
  6.                 MSR_MSP(*(vu32*)appxaddr);
  7.                 jump2app();
  8.         }
  9. }               
复制代码

bootloader是从0x0800000开始烧录的,那么app程序就必须另外开始烧录。bootloader会占据一定空间,所以app从0x08000000开始烧录,设置完之后,还需要将.hex文件转换为.bin文件
D:\Keil_v5\ARM\ARMCC\bin\fromelf.exe   --bin -o  ..\USER\Objects\Template.bin ..\USER\Objects\Template.axf
这是我的工程中需要设置的参数


同时,在app程序的主函数中做如下设置:

最后编译app程序,然后可以在工程设置的文件目录中找到.bin文件。完成上述工作后,找个串口调试助手,发送.bin文件就大功告成

我自己的总结,对于iap这部分,这次是照葫芦画瓢,参考了STM32的iap程序,区别是:参考的STM32工程对flash采用了半字编程,而GD32F207的库函数中只有对字的编程,但它是支持半字编程的,没有去自己重新写用半字编程的函数,修改了iap文件中的部分代码。GD32默认采用了小端模式,符合一般逻辑,操作起来也比较容易。另外,一开始在调试的时候总是出现问题,最后确定是串口部分的原因,串口只需要开接收中断就可以了,我开了串口的另一个中断,一开始没当回事,也是教训,没必要的东西千万别打开!


GD32_IAP.zip

352.06 KB, 下载次数: 316

分享到:
回复

使用道具 举报

回答|共 16 个

倒序浏览

沙发

yanhaijian

发表于 2016-2-29 22:42:42 | 只看该作者

几个注意点都提到了。
板凳

黑溱郎

发表于 2016-3-1 08:55:29 | 只看该作者

学习了,谢谢分亨。
地板

Paderboy

发表于 2016-3-1 09:17:53 | 只看该作者

学习学习。。
5#

党国特派员

发表于 2016-3-1 09:19:56 | 只看该作者

这个要学习下。。。
喜欢在构思妙想,电子产品DIY是工作,也是一种爱好。
6#

trochili

发表于 2016-3-1 10:14:41 | 只看该作者

本帖最后由 trochili 于 2016-3-1 10:16 编辑

这个我写了好久,如果下载的bin很大超过sarm大小,你怎么处理的?
eeboard大力支持的开源RTOS -- Trochili RTOS
7#

9robot

发表于 2016-3-1 11:02:16 | 只看该作者

我也是刚开始学习这个,采用的是最简单的方式,就是把接收的数据放在sram中,其限制就是bin文件和bootloader所占ram总和必须小于芯片总的ram,论坛里采用的方式有:.bin分多次发送,芯片多次接收,接收以此写一次。不过我还没去尝试
8#

糖悦之果飞

发表于 2016-3-1 13:52:47 | 只看该作者

亲,可以将内容一并发到经验频道,很有机会获得每月之星的呢http://jingyan.eeboard.com/
9#

trochili

发表于 2016-3-3 15:27:47 | 只看该作者

9robot 发表于 2016-3-1 11:02
我也是刚开始学习这个,采用的是最简单的方式,就是把接收的数据放在sram中,其限制就是bin文件和bootloade ...

这个功能我实现,在190的活动中我会放出代码来。
eeboard大力支持的开源RTOS -- Trochili RTOS
10#

9robot

发表于 2016-3-3 17:04:02 | 只看该作者

trochili 发表于 2016-3-3 15:27
这个功能我实现,在190的活动中我会放出代码来。

十分期待trochili大神将iap做的更完美,功能更强大!最近导师催论文,只能过段时间再搞了
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条