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 页大小
主程序很简单:
第一步当然是配置系统时钟
第二步: 根据系统时钟频率设置FLASH读写周期:
第三步: 就是初始化串口(uart_init();)
这里串口的发送及接收都是用的阻塞方式,说白了就是死等!
第四步: 单片机向PC上位机发送联机请求: (规定,单片机与上位机通讯一帧数据是260个字节,也就是说,单片机如果要对上位机发送数据就必须是260个字节,接收也是260个字节, 小于260个字节的数据将被抛弃)
/*上位机与单片机通讯协议如下(一帧数据是260个字节,第一个字节是字头, 第二个字节是命令字, 3~258个字节是要发送的数据, 第259个字节是结束符,最后一个字节是校验字节): */
1. 下位机请求与上位机联机:
上位机发送: 0x55 , 'C' .....后面的258个字节可以不管
程序中定义:
#define COM_BUF_SIZE 256+4
uint8_t ComBuf; //0字头0x55/1命令/
数据发送及接收都用ComBuf存储
单片机请求联机::
//联机结果
第五步: 单片机带超时(比如10s)等待上位机命令(没有等到PC消息就跳到APP区运行程序, 有消息就在IAP BOOT区中运行程序):
第六步,擦除FLASH(APP应用区):
第七步: 写FLASH(APP应用 BIN 文件)
呵呵,从上面看,IAP BOOT就两步而已, 一 、擦除FLASH 二 、写FLASH!
MDK都不用设置,编译OK后,把HEX文件下载到FLASH里就OK了!
////////////////////////////////////////////////////////////////////////////////////////
只要注意 #define ApplicationAddress 0x08003000
就可以了,这个地址我们在APP应用程序中要用到!
/////////////////////////////////////////////////////////////////////////////////////////
来个IAP升级演示视频:
http://v.youku.com/v_show/id_XNjAzODIwMDA0.html 上源码!
IAP主要讲究的是生产以后,便于升级固件的。MDK的下载那是ICP,属于量产或者调试阶段通过jlink之类的链路来下载。IAP可以是串口,usb,can,网络,等等
有兴趣的话,可以研究下支持多种升级模式,并且代码尺寸尽量小{:lol:} {:dizzy:}{:curse:}{:curse:}{:mad:}{:mad:}{:mad:} 好像很厉害的样子{:lol:} 标记。不错。 本帖最后由 skype 于 2013-8-28 16:02 编辑
App应用程序设置:
呵呵,这个简单了,是人都会写了
还记得IAP BOOT中的这个地址吗?
#define ApplicationAddress 0x08003000
就它了0x3000 !
APP三个设置就可以搞定!
1、FLASH偏移量
2、输出BIN文件,把它写入stm32 flash(从ApplicationAddress开始写)
3、 要让APP在应用区(ApplicationAddress)跑起来,一定要加上
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x3000);
其他注意事项:::无无无
////
APP 文件下载
火钳流氓 正在学,收藏了 最近要做这个功能,谢谢LZ分享 MARK{:smile:} 支持楼主了 支持一下! 好东西当然要收藏了
楼主威武 好像很強大
關注{:biggrin:} 请问这个和官方的那个串口下载程序有什么区别嘛??
这个,上位机都不用写, 偶们用超级终端。 收藏先,我弄的时候,步骤是跟你一样的 呵呵,杯具了! mark之,mark之,mark之 就是过来顶的,话说3年前我曾因前辈做的一个双U的板子升级程序而感到神秘,互相升级,很方便!
一直想自己弄一下,到现在都没着手,哈哈现在被楼主给晒出来了! 是呀,资料上把简单的东西搞得复杂了,好像很神秘,其实它就是很简单。 ST发布的AN2557就是一个完整的bootloader,好处是直接用YMODEM协议,上位机直接使用超级终端或者其它支持YMODEM的软件,一个数据包1024字节,速度快。目前我们修改了AN2557,支持AES128加密,这样升级固件就可以放在网站上让用户自己去下载。
AN2557配合PW5(Procomm Plus Connection Manager)软件的脚本功能,实现了全自动灌录固件和测试。
AN2557不是用stm32内部预先固化的那个loader,而是完全源码自己扩展的一个loader,目前加上了AES128,仅仅占0x2000空间。
楼主给的也是好东西,原理步骤一目了然。 通讯中没有校验?错一个bit整个就挂了啊 {:smile:}{:smile:} Appcat 发表于 2013-8-28 17:51 static/image/common/back.gif
ST发布的AN2557就是一个完整的bootloader,好处是直接用YMODEM协议,上位机直接使用超级终端或者其它支持YM ...
谢谢!
这个只是个架构,如果认为下载比较慢的话,就把数据帧缓冲加大就可以了!
如:
#define COM_BUF_SIZE 256+4
uint8_t ComBuf; //0字头0x55/1命令/
你认为太小的话,
请改成:
#define COM_BUF_SIZE 1024+4 //或改成1024*2+4
uint8_t ComBuf; //0字头0x55/1命令/
这样就可以了,怎么改,相信拿到源码的人都会改!
呵呵,总之,速度不是问题!
wukongli 发表于 2013-8-28 17:55 static/image/common/back.gif
通讯中没有校验?错一个bit整个就挂了啊
你自己加吧!
你认为呢?
好像很強大
關注{:lol:} 谢谢楼主分享。 想搞个u盘升级,参考下 好安逸的! 这是牛啊,下载来学习一下。 既然都这么说了,我还是记一下了。 回去试试,行的回来再顶~~~ 还不错哦 Mark Mark Mark
Mark Mark Mark 正在用,谢谢 搬凳子学习 增加DOS控制台代码,可以把内存中的BIN文件打印出来,也可以打印数据流,方便连机调试:
我测试成功,楼主高人 本帖最后由 skype 于 2013-8-29 12:31 编辑
呵呵,目的就是让所有人可以成功实现IAP, 不要向我刚开始学IAP一样,走了很多弯路,说实话,把时间浪费在IAP这个功能上很不值得! Mark Mark MarkMark Mark Mark{:shy:}{:shy:} 好好学习。支持楼主。 支持楼主,我有个产品使用DTU,一直想弄远程升级 {:lol:}{:lol:}{:lol:}{:lol:}{:lol:} skype 发表于 2013-8-29 12:30 static/image/common/back.gif
呵呵,目的就是让所有人可以成功实现IAP, 不要向我刚开始学IAP一样,走了很多弯路,说实话,把时间浪费在IA ...
MFC中if ((rx.New_cnt >= 260) && (rx.buffer = 0x55)) 这里应该是rx.buffer == 0x55 吧 442502587 发表于 2013-8-29 12:47 static/image/common/back.gif
MFC中if ((rx.New_cnt >= 260) && (rx.buffer = 0x55)) 这里应该是rx.buffer == 0x55 吧 ...
谢谢,我应该写成 0x55 == rx.buffer 关心下,上位机程序! 对啊,干脆上位机程序也开源吧 操,都已开源,是你没有仔细看! skype 发表于 2013-8-28 18:02 static/image/common/back.gif
谢谢!
这个只是个架构,如果认为下载比较慢的话,就把数据帧缓冲加大就可以了!
我记得这样做了之后,中断的初始地址需要更改的?
非常好,很详细,谢谢! Appcat 发表于 2013-8-28 17:51 static/image/common/back.gif
ST发布的AN2557就是一个完整的bootloader,好处是直接用YMODEM协议,上位机直接使用超级终端或者其它支持YM ...
ST 的 AN2557 不錯 {:smile:} 楼主讲的很通俗啊。。。 本帖最后由 skype 于 2013-8-29 14:45 编辑
Nexus 发表于 2013-8-29 13:56 static/image/common/back.gif
我记得这样做了之后,中断的初始地址需要更改的?
#define BIN_Len 256 //代替上下位机程序中的256
#define Protocol_Len 4+BIN_Len //代替上下位机程序中的260
以后你要加大缓冲区这样改就可以:
下位机:
这样的话,一帧数据是256还是1024你自己定就可以了
skype 发表于 2013-8-29 14:31 static/image/common/back.gif
#define BIN_Len 256 //代替上下位机程序中的256
#define Protocol_Len 4+B ...
好像是有个4B的空隙。。。后面再试试。。。 BIN_Len+4
其中4BYTE是给你做协议用的,比如加字头,做CRC校验!
呵呵,你懂的!! skype 发表于 2013-8-29 14:31 static/image/common/back.gif
#define BIN_Len 256 //代替上下位机程序中的256
#define Protocol_Len 4+B ...
楼主APP里面那个 little_os 还有点意思。自己写的么? stely 发表于 2013-8-29 14:40 static/image/common/back.gif
楼主APP里面那个 little_os 还有点意思。自己写的么?
是的,无聊的时候玩玩就可以了!不要太执着自己写OS! skype 发表于 2013-8-29 13:19 static/image/common/back.gif
操,都已开源,是你没有仔细看!
确实没仔细看,人才。 skype 发表于 2013-8-29 12:20 static/image/common/back.gif
增加DOS控制台代码,可以把内存中的BIN文件打印出来,也可以打印数据流,方便连机调试:
...
这个方法好 调试的时候很烦方便 下载收藏。谢谢。 很强大~~~关注 mark mark,以后有用。 很有用的东西。mark 不错,谢谢楼主 谢谢楼主了,前段时间有个产品需要这个IAP功能,正好研究研究。 jackwang123 发表于 2013-8-29 16:47 static/image/common/back.gif
谢谢楼主了,前段时间有个产品需要这个IAP功能,正好研究研究。
希望对你的项目有参考价值! wukongli 发表于 2013-8-28 17:55 static/image/common/back.gif
通讯中没有校验?错一个bit整个就挂了啊
嗯,的确应该增加一个校验功能。否则如果出错会死机的。 mark{:huffy:}{:biggrin:} 值的学习,收藏 ANDR0ID 发表于 2013-8-29 22:13
嗯,的确应该增加一个校验功能。否则如果出错会死机的。
本贴目的是如何简单快速实现IAP,请不要在此讨论这种如果的问题!
要想丰衣足食,那只有自动手了!
谢谢 学习了 呵呵 好···有一个usmart 的 东西,大家也可以参考一下·· MARK 非常感谢! 加上GPRS模块,可以实现远程升级了的吧 加上GPRS模块,可以实现远程升级了的吧 就是要远程升级才搞IAP 顶楼主,希望更多人看到 好好学习一下 这个简单实用就好,可以以此为基础版本,大家有更好的想法可以在上面扩充 mk谢谢{:smile:}{:smile:}{:smile:}{:smile:}{:smile:} 是很好的学习模块。 STM32第一次运行后要给FLASH设置读禁止:
OB_TypeDef obTmp;
void ReadinfoByte(void)
{
un_word tmp;
uint32_t ChipUniqueID;
uint32_t OptionBytes;
FlagStatus readoutstatus = RESET;
readoutstatus = FLASH_GetReadOutProtectionStatus();
if (SET == readoutstatus)
{//已写读保护
ComBuf= 0x55;
ComBuf= '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 = *(__IO u32*)(0X1FFFF7E8); // H 谢谢分享!!! 好贴要顶{:lol:}{:lol:}{:lol:}{:lol:}{:lol:}{:lol:} markIAP STM32{:smile:} 厉害!学习了! 不错,学习一下 也是刚开始学STM32,对它的FLASH特性还不是很了解,这次就在IAP上测试了一下!
呵呵,这次给出的IAP架构还是很强大地!! 试试看,不错的
学习学习 非常不错 好,正需要这个。修改下。哈哈。多谢。 {:smile:}{:smile:}{:smile:}{:smile:} mark 一下
学习了,用得上