amobbs.com 阿莫电子技术论坛

标题: ST32 IAP 功能, 要让所有的人都可以轻松搞定 [打印本页]

作者: skype    时间: 2013-8-28 15:40
标题: ST32 IAP 功能, 要让所有的人都可以轻松搞定
高手请直接跳过!

理论上的东西就不写了,自己在论坛上看看! 这里直接讲如何操作的问题!

IAP 应用,首先把FLASH分两个区, 一个iap BOOT区, 一个用户APP应用区.

IAP BOOT区就是 IAP升级程序的大小, 如果你不用STM32 的FLASH做别的应用(如E2PROM),那么剩下的空间都可以作为APP应用程序区!

所以,一个完整带IAP的项目,我们要写两个单片机程序和一个PC升级程序(如果你想用PC对APP升级的话)!


本示例是IAP BOOT用串口接收PC发过来的BIN文件对STM32的APP进行升级!


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
首先,我们要完成IAP BOOT单片机程序, 这个程序很简单,你就当是STM32对自己内部的FLASH的擦写操作!

既然我们要在IAP BOOT中读写FLASH,那么我们先要设置FLASH的大小,我们把STM32的0x08003000之后的地址都作为FLASH(那么IAP BOOT程序要小于12K)
#define ApplicationAddress                                0x08003000                  //APP应用程序起始地址(存放在FLASH前12K)                                                                                                                             //保留0X08000000~0x08003000的空间为IAP使用
       
#define USER_FLASH_SIZE                        42                        //用户APP flashROM大小, 42 PAGE                       
#define FLASH_PAGE_SIZE                        1024//2048                //FLASH 页大小


主程序很简单:

第一步当然是配置系统时钟
[attach]135033[/attach]

第二步: 根据系统时钟频率设置FLASH读写周期:
[attach]135035[/attach]

第三步: 就是初始化串口(uart_init();)
[attach]135036[/attach]
这里串口的发送及接收都是用的阻塞方式,说白了就是死等!

第四步: 单片机向PC上位机发送联机请求: (规定,单片机与上位机通讯一帧数据是260个字节,也就是说,单片机如果要对上位机发送数据就必须是260个字节,接收也是260个字节, 小于260个字节的数据将被抛弃)

/*  上位机与单片机通讯协议如下(一帧数据是260个字节,第一个字节是字头, 第二个字节是命令字, 3~258个字节是要发送的数据, 第259个字节是结束符,最后一个字节是校验字节):   */
1. 下位机请求与上位机联机:
上位机发送: 0x55 , 'C' .....后面的258个字节可以不管

程序中定义:
#define COM_BUF_SIZE                256+4
uint8_t ComBuf[COM_BUF_SIZE];        //0字头0x55/1命令/
数据发送及接收都用ComBuf存储

单片机请求联机::
[attach]135039[/attach]

//联机结果
[attach]135040[/attach]

第五步: 单片机带超时(比如10s)等待上位机命令(没有等到PC消息就跳到APP区运行程序, 有消息就在IAP BOOT区中运行程序):
[attach]135041[/attach]


第六步,擦除FLASH(APP应用区):
[attach]135044[/attach]

第七步: 写FLASH(APP应用 BIN 文件)
[attach]135045[/attach]

呵呵,从上面看,IAP BOOT就两步而已, 一 、擦除FLASH      二 、写FLASH!


MDK都不用设置,编译OK后,把HEX文件下载到FLASH里就OK了!

////////////////////////////////////////////////////////////////////////////////////////
只要注意 #define ApplicationAddress                                0x08003000

就可以了,这个地址我们在APP应用程序中要用到!
/////////////////////////////////////////////////////////////////////////////////////////









作者: skype    时间: 2013-8-28 15:44
上源码!

[attach]135047[/attach]



[attach]135046[/attach]


作者: bbstr    时间: 2013-8-28 15:44
IAP主要讲究的是生产以后,便于升级固件的。MDK的下载那是ICP,属于量产或者调试阶段通过jlink之类的链路来下载。IAP可以是串口,usb,can,网络,等等

有兴趣的话,可以研究下支持多种升级模式,并且代码尺寸尽量小
作者: flytosky8    时间: 2013-8-28 15:47

作者: 苦行僧    时间: 2013-8-28 15:49
好像很厉害的样子
作者: 32MCU    时间: 2013-8-28 15:58
标记。不错。
作者: skype    时间: 2013-8-28 15:59
本帖最后由 skype 于 2013-8-28 16:02 编辑

App应用程序设置:


呵呵,这个简单了,是人都会写了

还记得IAP BOOT中的这个地址吗?
#define ApplicationAddress                0x08003000

就它了  0x3000    !


APP  三个设置就可以搞定!

1、FLASH偏移量
[attach]135049[/attach]

2、输出BIN文件,把它写入stm32 flash(从ApplicationAddress开始写)
[attach]135050[/attach]

3、 要让APP在应用区(ApplicationAddress)跑起来,一定要加上

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x3000);

[attach]135051[/attach]

其他注意事项:::无无无


////
APP 文件下载
[attach]135052[/attach]
作者: mao001    时间: 2013-8-28 16:02
火钳流氓
作者: graycker    时间: 2013-8-28 16:06
正在学,收藏了
作者: Feco    时间: 2013-8-28 16:10
最近要做这个功能,谢谢LZ分享
作者: qianzeqi    时间: 2013-8-28 16:21
MARK
作者: 凌海滨    时间: 2013-8-28 16:22
支持楼主了
作者: pipi516    时间: 2013-8-28 16:30
支持一下!
作者: 苹果鱼吉    时间: 2013-8-28 16:42
好东西当然要收藏了
楼主威武
作者: john800422    时间: 2013-8-28 16:45
好像很強大
關注
作者: skynet    时间: 2013-8-28 16:45
请问这个和官方的那个  串口下载程序有什么区别嘛??

作者: skype    时间: 2013-8-28 16:51
[attach]135060[/attach]
作者: yss315    时间: 2013-8-28 17:14
这个,上位机都不用写, 偶们用超级终端。
作者: DiaoMao_Huang    时间: 2013-8-28 17:18
收藏先,我弄的时候,步骤是跟你一样的
作者: skype    时间: 2013-8-28 17:19
呵呵,杯具了!
作者: zhangyadong90    时间: 2013-8-28 17:22
mark之,mark之,mark之
作者: mvpgpz    时间: 2013-8-28 17:36
就是过来顶的,话说3年前我曾因前辈做的一个双U的板子升级程序而感到神秘,互相升级,很方便!
一直想自己弄一下,到现在都没着手,哈哈现在被楼主给晒出来了!
作者: skype    时间: 2013-8-28 17:48
是呀,资料上把简单的东西搞得复杂了,好像很神秘,其实它就是很简单。
作者: Appcat    时间: 2013-8-28 17:51
ST发布的AN2557就是一个完整的bootloader,好处是直接用YMODEM协议,上位机直接使用超级终端或者其它支持YMODEM的软件,一个数据包1024字节,速度快。目前我们修改了AN2557,支持AES128加密,这样升级固件就可以放在网站上让用户自己去下载。
AN2557配合PW5(Procomm Plus Connection Manager)软件的脚本功能,实现了全自动灌录固件和测试。

AN2557不是用stm32内部预先固化的那个loader,而是完全源码自己扩展的一个loader,目前加上了AES128,仅仅占0x2000空间。

楼主给的也是好东西,原理步骤一目了然。
作者: wukongli    时间: 2013-8-28 17:55
通讯中没有校验?错一个bit整个就挂了啊
作者: lsy5110    时间: 2013-8-28 17:57

作者: skype    时间: 2013-8-28 18:02
Appcat 发表于 2013-8-28 17:51
ST发布的AN2557就是一个完整的bootloader,好处是直接用YMODEM协议,上位机直接使用超级终端或者其它支持YM ...

谢谢!

这个只是个架构,如果认为下载比较慢的话,就把数据帧缓冲加大就可以了!

如:
#define COM_BUF_SIZE                256+4
uint8_t ComBuf[COM_BUF_SIZE];        //0字头0x55/1命令/

你认为太小的话,

请改成:
#define COM_BUF_SIZE                1024+4     //或改成1024*2+4
uint8_t ComBuf[COM_BUF_SIZE];        //0字头0x55/1命令/

这样就可以了,怎么改,相信拿到源码的人都会改!

呵呵,总之,速度不是问题!



作者: skype    时间: 2013-8-28 18:04
wukongli 发表于 2013-8-28 17:55
通讯中没有校验?错一个bit整个就挂了啊

你自己加吧!

你认为呢?
作者: Free_Bird    时间: 2013-8-28 18:15

好像很強大
關注
作者: lyg407    时间: 2013-8-28 18:30
谢谢楼主分享。
作者: mvip    时间: 2013-8-28 20:26
想搞个u盘升级,参考下
作者: HeP028    时间: 2013-8-28 21:08
好安逸的!
作者: mcu005    时间: 2013-8-28 21:54
这是牛啊,下载来学习一下。
作者: zwgmail    时间: 2013-8-28 22:21
既然都这么说了,我还是记一下了。
作者: mint    时间: 2013-8-28 22:46
回去试试,行的回来再顶~~~
作者: sedulity11    时间: 2013-8-28 22:59
还不错哦
作者: peiyan    时间: 2013-8-28 23:20
Mark Mark Mark
作者: 262619890    时间: 2013-8-29 11:33

Mark Mark Mark
作者: JACK847070222    时间: 2013-8-29 12:01
正在用,谢谢
作者: Bicycle    时间: 2013-8-29 12:07
搬凳子学习
作者: skype    时间: 2013-8-29 12:20
增加DOS控制台代码,可以把内存中的BIN文件打印出来,也可以打印数据流,方便连机调试:
[attach]135290[/attach]
作者: 442502587    时间: 2013-8-29 12:24
我测试成功,楼主高人
作者: skype    时间: 2013-8-29 12:30
本帖最后由 skype 于 2013-8-29 12:31 编辑

呵呵,目的就是让所有人可以成功实现IAP, 不要向我刚开始学IAP一样,走了很多弯路,说实话,把时间浪费在IAP这个功能上很不值得!
作者: riptell2008    时间: 2013-8-29 12:35
Mark Mark MarkMark Mark Mark
作者: stely    时间: 2013-8-29 12:38
好好学习。支持楼主。
作者: zl326498096    时间: 2013-8-29 12:43
支持楼主,我有个产品使用DTU,一直想弄远程升级
作者: 气球    时间: 2013-8-29 12:46

作者: 442502587    时间: 2013-8-29 12:47
skype 发表于 2013-8-29 12:30
呵呵,目的就是让所有人可以成功实现IAP, 不要向我刚开始学IAP一样,走了很多弯路,说实话,把时间浪费在IA ...

MFC中  if ((rx.New_cnt >= 260) && (rx.buffer[0] = 0x55))   这里应该是  rx.buffer[0] == 0x55   吧
作者: skype    时间: 2013-8-29 13:08
442502587 发表于 2013-8-29 12:47
MFC中  if ((rx.New_cnt >= 260) && (rx.buffer[0] = 0x55))   这里应该是  rx.buffer[0] == 0x55   吧 ...

谢谢,我应该写成 0x55 == rx.buffer[0]
作者: keinYe    时间: 2013-8-29 13:13
关心下,上位机程序!
作者: whatcanitbe    时间: 2013-8-29 13:16
对啊,干脆上位机程序也开源吧
作者: skype    时间: 2013-8-29 13:19
操,都已开源,是你没有仔细看!
作者: Nexus    时间: 2013-8-29 13:56
skype 发表于 2013-8-28 18:02
谢谢!

这个只是个架构,如果认为下载比较慢的话,就把数据帧缓冲加大就可以了!

我记得这样做了之后,中断的初始地址需要更改的?

作者: jaky80000    时间: 2013-8-29 14:05
非常好,很详细,谢谢!
作者: john800422    时间: 2013-8-29 14:15
Appcat 发表于 2013-8-28 17:51
ST发布的AN2557就是一个完整的bootloader,好处是直接用YMODEM协议,上位机直接使用超级终端或者其它支持YM ...

ST 的 AN2557 不錯
作者: 了无    时间: 2013-8-29 14:25
楼主讲的很通俗啊。。。
作者: skype    时间: 2013-8-29 14:31
本帖最后由 skype 于 2013-8-29 14:45 编辑
Nexus 发表于 2013-8-29 13:56
我记得这样做了之后,中断的初始地址需要更改的?


#define BIN_Len                256                           //代替上下位机程序中的256
#define Protocol_Len                4+BIN_Len                  //代替上下位机程序中的260

以后你要加大缓冲区这样改就可以:
[attach]135318[/attach]

下位机:
[attach]135320[/attach]

这样的话,一帧数据是256还是1024你自己定就可以了


作者: Nexus    时间: 2013-8-29 14:37
skype 发表于 2013-8-29 14:31
#define BIN_Len                256                           //代替上下位机程序中的256
#define Protocol_Len                4+B ...

好像是有个4B的空隙。。。后面再试试。。。
作者: skype    时间: 2013-8-29 14:40
BIN_Len+4

其中4BYTE是给你做协议用的,比如加字头,做CRC校验!
呵呵,你懂的!!
作者: stely    时间: 2013-8-29 14:40
skype 发表于 2013-8-29 14:31
#define BIN_Len                256                           //代替上下位机程序中的256
#define Protocol_Len                4+B ...

楼主APP里面那个 little_os 还有点意思。自己写的么?
作者: skype    时间: 2013-8-29 14:46
stely 发表于 2013-8-29 14:40
楼主APP里面那个 little_os 还有点意思。自己写的么?

是的,无聊的时候玩玩就可以了!不要太执着自己写OS!
作者: whatcanitbe    时间: 2013-8-29 14:47
skype 发表于 2013-8-29 13:19
操,都已开源,是你没有仔细看!

确实没仔细看,人才。
作者: justdomyself    时间: 2013-8-29 15:13
skype 发表于 2013-8-29 12:20
增加DOS控制台代码,可以把内存中的BIN文件打印出来,也可以打印数据流,方便连机调试:
...

这个方法好   调试的时候很烦方便
作者: Excellence    时间: 2013-8-29 15:31
下载收藏。谢谢。
作者: coslight_dt    时间: 2013-8-29 15:41
很强大~~~关注
作者: powerlabor001    时间: 2013-8-29 15:47
mark mark,以后有用。
作者: wicy001    时间: 2013-8-29 16:24
很有用的东西。mark
作者: ronic    时间: 2013-8-29 16:25
不错,谢谢楼主
作者: jackwang123    时间: 2013-8-29 16:47
谢谢楼主了,前段时间有个产品需要这个IAP功能,正好研究研究。
作者: skype    时间: 2013-8-29 16:55
jackwang123 发表于 2013-8-29 16:47
谢谢楼主了,前段时间有个产品需要这个IAP功能,正好研究研究。

希望对你的项目有参考价值!
作者: ANDR0ID    时间: 2013-8-29 22:13
wukongli 发表于 2013-8-28 17:55
通讯中没有校验?错一个bit整个就挂了啊

嗯,的确应该增加一个校验功能。否则如果出错会死机的。
作者: CJQ-ENJOY    时间: 2013-8-30 08:02
mark
作者: wzhenhua    时间: 2013-8-30 08:56
值的学习,收藏
作者: skype    时间: 2013-8-30 08:58
ANDR0ID 发表于 2013-8-29 22:13
嗯,的确应该增加一个校验功能。否则如果出错会死机的。

本贴目的是如何简单快速实现IAP,请不要在此讨论这种如果的问题!
要想丰衣足食,那只有自动手了!

作者: linshengttt    时间: 2013-8-30 15:14
谢谢 学习了 呵呵
作者: kalo425    时间: 2013-8-30 15:35
好···有一个usmart 的 东西,大家也可以参考一下··
作者: spint    时间: 2013-8-30 16:31
MARK 非常感谢!
作者: yalihendaya    时间: 2013-8-30 16:49
加上GPRS模块,可以实现远程升级了的吧
作者: yalihendaya    时间: 2013-8-30 16:49
加上GPRS模块,可以实现远程升级了的吧
作者: skype    时间: 2013-8-30 18:17
就是要远程升级才搞IAP
作者: tdh03z    时间: 2013-8-30 19:44
顶楼主,希望更多人看到
作者: sk_2006_ren    时间: 2013-8-30 22:13
好好学习一下
作者: coding2011    时间: 2013-8-30 22:48
这个简单实用就好,可以以此为基础版本,大家有更好的想法可以在上面扩充
作者: ztg328    时间: 2013-8-30 23:06
mk  谢谢
作者: xizi    时间: 2013-8-31 00:26
是很好的学习模块。
作者: skype    时间: 2013-8-31 11:35
STM32第一次运行后要给FLASH设置读禁止:
[attach]135714[/attach]

        OB_TypeDef obTmp;
void ReadinfoByte(void)
{
        un_word tmp;
        uint32_t ChipUniqueID[3];
        uint32_t OptionBytes[4];

        FlagStatus readoutstatus = RESET;
        readoutstatus = FLASH_GetReadOutProtectionStatus();
        if (SET == readoutstatus)
        {  //已写读保护
                ComBuf[0]= 0x55;
                ComBuf[1]= 'b';
                USART_string(ComBuf, COM_BUF_SIZE);
                ZeroMemory(ComBuf, COM_BUF_SIZE);
        }
        else
        {
                obTmp = *OB;
                FLASH_Unlock();
                FLASH_EraseOptionBytes();
                FLASH_ReadOutProtection(ENABLE);
                FLASH_ProgramOptionByteData((u32)(&(OB->Data0)), 0x1e);  //0x1ffff804
                //恢复其它的option bytes
                FLASH_ProgramOptionByteData((u32)(&(OB->RDP)), obTmp.RDP);  //0x1ffff800
                FLASH_ProgramOptionByteData((u32)(&(OB->USER)), obTmp.USER);  //0x1ffff802
                FLASH_ProgramOptionByteData((u32)(&(OB->Data1)), obTmp.Data1);  //0x1ffff806
                FLASH_ProgramOptionByteData((u32)(&(OB->WRP0)), obTmp.WRP0);  //0x1ffff808
                FLASH_ProgramOptionByteData((u32)(&(OB->WRP1)), obTmp.WRP1);  //0x1ffff80a
                FLASH_ProgramOptionByteData((u32)(&(OB->WRP2)), obTmp.WRP2);  //0x1ffff80c
                FLASH_ProgramOptionByteData((u32)(&(OB->WRP3)), obTmp.WRP3);  //0x1ffff80e
                FLASH_Lock();
                obTmp = *OB;
                //96bits ID               
                ChipUniqueID[0] = *(__IO u32*)(0X1FFFF7E8);          //         H
作者: WITSOFT    时间: 2013-8-31 15:09
谢谢分享!!!
作者: diysh    时间: 2013-8-31 21:26
好贴要顶
作者: qfmcu    时间: 2013-8-31 21:38
mark  IAP STM32
作者: 追寻cheney    时间: 2013-8-31 21:41
厉害!学习了!
作者: bbsview    时间: 2013-8-31 21:48
不错,学习一下
作者: skype    时间: 2013-8-31 22:48
也是刚开始学STM32,对它的FLASH特性还不是很了解,这次就在IAP上测试了一下!

[attach]135790[/attach]



[attach]135791[/attach]


[attach]135792[/attach]

呵呵,这次给出的IAP架构还是很强大地!!
作者: hncjs    时间: 2013-8-31 23:52
试试看,不错的

作者: n_mos    时间: 2013-9-1 00:05
学习学习
作者: touch_mcu    时间: 2013-9-1 00:07
非常不错
作者: skype    时间: 2013-9-1 21:12
来个IAP升级演示视频:
http://v.youku.com/v_show/id_XNjAzODIwMDA0.html
作者: guozs1984    时间: 2013-9-4 13:34
好,正需要这个。修改下。哈哈。多谢。
作者: yfgww    时间: 2013-9-4 15:28

作者: lzyr    时间: 2013-9-4 15:38
mark 一下

作者: 8s209    时间: 2013-9-4 15:40
学习了,用得上




欢迎光临 amobbs.com 阿莫电子技术论坛 (https://www.amobbs.com/) Powered by Discuz! X3.4