STM32IAP升级-----编写IAP升级遇到的问题总结
IAP的源代码等资料我上传了,压缩包内有12个文件。,http://download.csdn.net/detail/f907279313/7524849(要积分的辛苦收集的你们就给点积分吧)
还有还有一篇博客总结的IAP:http://blog.csdn.net/super_demo/article/details/32133257
一,串口通信问题
1,串口通信两端的TTL电平要一致,看选用的芯片,要么都是3.3V要么都是5V。。当两端电平不一致时一般是收不到数据的。。
当检測程序等都没有问题可是依旧收不到数据时。考虑检測一下两端的电平是否一致。。可用示波器查看收发数据时的电平
2,在写IAP是使用的官方的库函数,结果串口一直收不到正确的数据。无论我发什么,收到的都是0x58或者0xF6,并且我发5个字节仅仅能收到2个。
。确定自己的程序逻辑没问题,然后怀疑是使用的库函数有问题。使用beyond compare挨着对比了一下曾经写过的正确的程序。。发现系统初始化时外部晶振没有改。。在SystemInit();时就是为了/* 配置系统时钟为168M 使用外部8M晶体+PLL*/ 在函数内有一个宏定义#define PLL_M 25.。
。
。
库函数默认的是25可是我们必须要使用8M的晶振。
。所以要把25改成8.。
。。
。。
。改完測试通过。。。
。
。
3,在问题2的时候自己犯了个错误。当时我把还有一个程序的库文件都拷过来了替换了原来的库文件,结果直接进不了中断了。有中断程序就死了。
。。如图所看到的
有中断时汇编显示就跳到了黄色的那句话。
然后程序就死了。
。事实上进不了中断首先想到的是中断向量表的问题。当时一着急没想到这个问题。
。复制过来的库文件是我写的IAP的APP程序,我把当中的中断向量表改了。我不是在main函数中改的。我是直接改的库函数中的偏移量,然后就把这个问题给忘了,导致找了半天最终意识到是中断向量表出了问题。。。
4。串口一上电未初始化时就開始疯狂的发乱码。等初始化完毕之后就不发了。如图
解决方法:我是看的官方的例程,假设须要更新再初始化串口,假设不须要更新的话就不初始化串口。
所以把串口初始化部分写在了后面的推断中。。。这样操作会出现上述问题。
把串口的初始化部分写到main函数的前端就不会出现这个问题了。
。至于详细为什么会这种原因还没搞明确。。
。
经过询问大神们说不初始化的时候会有浮空电平,有时出现乱发一些数据也正常。。
。。
5,我在写iap升级的时候,使用的是一次性所有接收完70K的bin文件,再去升级。。
后期程序越写越多,最后编译完的bin文件大于了70K导致升级不能成功。前面的$HEAD命令能接收。发完bin文件后$TAIL命令接收不到。。。
。。这是由于bin文件的大小超过了70k大小的buff后面的内容无法接收了。
。
。
。。。。。。。
。。。正规的升级应该接收10k或者多少就编程一次。。
。。。。。。
二,FLASH问题
1,flash的擦除
实际上是把flash的内容所有写1(擦除完再读的话读出来的全是0XFF),flash的编程要按字(32位)或半字(16位)编程。当接收的数据是奇数位是要补上0,凑够半字来编程。
2。写进flash跟读出来的不一样
注意编程flash时变量的存储接收等要用unsigned类型的。
存储接收的变量类型要一致。
以免造成越界问题,导致看到的数不一致
3,flash做存储用时
当时写了个程序,用flash来存数据,然后再读出来,遇到的问题是设备不断电时能够完整的读出来,设备断电后读不出了。
要读多少个数我是把个数也存储在flash中的。最终发现问题是程序中一个标志位的操作有问题,每次断电后再上电会自己主动把这个个数写为0,导致每次都读不出来数
三。数组越界问题
1,嵌入式程序通常要求少占内存,通常变量能定义8位不定义16位。。一定要注意变量的最大值。(细心一点)。。在越界问题上,吃亏了好几次了。。。。
eg:①,我定义了一个int16_t的变量来接收flash中的一个变量值0xABCD。
。结果非常显然越界了。。换成uint16_t就可以
②,定义了一个串口接收数据计数器uint16_t 的变量,要接收60k的APP程序,自觉得足够用了,可是串口发送60K大小的文件发送的字节数大于了65535,,,又耽误了好久时间。。。
谨记:要细心
四,关于APP与IAP互跳之间的中断处理问题
跳转时中断问题还是一个比較棘手的问题。。常常跳转之后无法进入中断。然后百度了一下。自己理解大概是,跳转时仅仅是强制改变了PC指正的位置。可是里面的中断寄存器什么的都没有变。这样中断存在,可是中断函数什么的都没有了。造成程序死掉。
。
我在写的过程中也遇到了问题,第一次从iap跳到app正常。可是从app跳回iap的时候由于残留的中断太多,在iap中程序死了。我的处理方式是把app中的跳转命令换成了系统复位NVIC_SystemReset();(不同的固件库可能函数名不同)其它的处理理的方式据我所知还有有①跳转之前复位或者关闭所有打开的中断②跳转后在初始化时加入RCC_DeInit();,,NVIC_DeInit ();等让中断恢复默认值。。详细可參考以下这篇文章http://dzdesigned80.blog.163.com/blog/static/203259238201272425313152/ 总之要注意中断寄存器的复位。
也能够直接软件复位管他什么中断寄存器残留的.从iap跳到app前能够用USART_ITConfig(USART1,
USART_IT_RXNE, DISABLE);来关闭串口接收中断。
从app跳转回iap能够用软件复位。
五,总结一下在IAP升级中APP程序的中断向量表的偏移
1. 关于APP程序的中断向量表地址偏移(三种方法。stm32F2与F4系列通用。三种方法本质一样仅仅是看到网上的各种例程的表现形式不一样)
① 直接操作寄存器
在APP程序的main函数的开头设置中断向量表偏移
SCB->VTOR = FLASH_BASE | 0x10000;
当中0x10000是偏移量。
。也就是前面的IAP程序所占用的空间大小。要是你的main函数中有SystemInit();的话要在SystemInit();之后加入。
由于SystemInit();中有中断向量表的偏移操作
在void SystemInit (void)系统初始化函数中有初始化中断向量表的语句
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* 使用内部SRAM启动设置这一句. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* 使用内部FLASH启动设置这句*/
#endif
能够直接改动VECT_TAB_OFFSE的值,这个值代表偏移量。不建议这么改。不建议改动库文件,应为后面其它程序用的话常常忘了这里动过中断向量表。导致中断不能正常执行(我就由于这个浪费了快一天时间。串口就是进不了中断)
当中
#define FLASH_BASE ((uint32_t)0x08000000) /*!<FLASH base address in the alias region */
#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM baseaddress in the alias region */
相应keil设置中的(这是一般程序默认的,IAP升级中APP程序的这个地方还得依据中断偏移量改)
② 使用库函数设置偏移量
在库文件里有专门的一个函数
在APP程序初始化时调用函数NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x10000);
当中/* Vector Table Base----------------------------------*/
#define NVIC_VectTab_RAM ((u32)0x20000000)
#define NVIC_VectTab_FLASH ((u32)0x08000000)
/***********************************************************************
Function Name : NVIC_SetVectorTable
* Description : Sets the vector table location andOffset.
* Input : - NVIC_VectTab: specifies if thevector table is in RAM or
* FLASH memory.
**********************************************************************/
void NVIC_SetVectorTable (u32NVIC_VectTab, u32 Offset)
{
/* Check the parameters */
assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
assert_param(IS_NVIC_OFFSET(Offset));
SCB->VTOR = NVIC_VectTab | (Offset & (u32)0x1FFFFF80);
}
③改动库文件(不建议使用)
直接改动固件库里面的数值。
在void SystemInit(void)下的
/* Configure the Vector Table location add offsetaddress ------------------*/
#ifdefVECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;/* Internal SRAM */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;/* Internal FLASH */
#endif
直接改动
#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
This valuemust be a multiple of 0x200. */
为
#define VECT_TAB_OFFSET 0x10000 /*!< Vector Table base offsetfield.
This valuemust be a multiple of 0x200. */
2.关于IAP程序与APP程序keil中的设置
Stm32的flash都是从0x8000000開始的,结束地址看片子的flash大小
Stm32的sram都是从0x2000000開始的,结束地址看片子的sram大小
IAP程序基本默认就可以,跟普通程序一样
在APP程序中须要设置一下偏移量
默认的条件下,图中IROM1的起始地址(Start)一般为0X08000000,大小(Size)为0X100000。即从0X08000000開始的1M空间为我们的程序存储(由于我们的STM32F4的FLASH大小是1M)。而图中,我们设置起始地址(Start)为0X08010000,即偏移量为0X10000(64K字节)。因而。留给APP用的FLASH空间(Size)仅仅有0X100000-0X10000=0XF0000(960K字节)大小了。设置好Start和Szie,就完毕APP程序的起始地址设置。
这里的64K字节。须要大家依据Bootloader程序大小进行选择,比方我们本章的Bootloader程序为22K左右,理论上我们仅仅须要确保APP起始地址在Bootloader之后,并且偏移量为0X200的倍数就可以(相关知识,请參考:http://www.openedv.com/posts/list/392.htm)。这里我们选择64K(0X10000)字节,留了一些余量。方便Bootloader以后的升级改动。
注意:设置的起始地址要与程序中设置的中断向量表的偏移量相应起来(假设给IAP程序64k的空间则APPkeil中起始地址为0x8010000相应的程序中中断向量偏移0x10000)我用的1M flash大小的片子。。详细的大小设置,看自己的片子。。
STM32IAP升级-----编写IAP升级遇到的问题总结的更多相关文章
- STM32 Bootloader基于ymodem传输协议串口IAP升级详解
硬件:stm32f103cbt6 软件:STM32F10x_StdPeriph_Lib_V3.5.0 文章目录 1 预备知识 2 Bootloader 2.1 启动流程 2.2 校验跳转地址是否有效 ...
- STM32 IAP 升级官方资料汇总
整理了一下SMT32标准外设库进行IAP升级的官方demo: 标准库版本 STM32F10xxx in-application programming using the USART (AN2557) ...
- Android应用程序的自动更新升级(自身升级、通过tomcat)(转)
Android应用程序的自动更新升级(自身升级.通过tomcat) http://blog.csdn.net/mu0206mu/article/details/7204746 刚入手android一个 ...
- Web工程软件升级之数据库升级(一)
1. 首先检查oracle数据库版本是否正确 (可以使用方法 lsinventory来实现) 2. 检查oracle连接是否成功 3. 解压升级包,放到特定目录 4. 做升级前数据备份,备份主要业务数 ...
- 采用MySQL_upgrade升级授权表方式升级
1.7.1 采用MySQL_upgrade升级授权表方式升级(1) 这种升级方式比较省事,通过MySQL_upgrade命令即可完成.下面来演示一下整个升级过程. 1)修改my.cnf配置文件,因为M ...
- django升级2.1python升级3.7时出现的错误:"trying to load '%s': %s" % (entry[1], e) django.template.library.InvalidTemplateLibrary:
django升级2.1python升级3.7时出现如下的错误: "trying to load '%s': %s" % (entry[1], e) django.template. ...
- 4-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案升级篇(远程升级WIFI内部程序)
https://www.cnblogs.com/yangfengwu/p/10360618.html 演示视频: https://www.bilibili.com/video/av54894356/ ...
- IAP升级功能编写初期的一些困惑与疑问---完毕功能后的总结
IAP的源代码等资料我上传了,压缩包内有12个文件,,http://download.csdn.net/detail/f907279313/7524849(要积分的辛苦收集的你们就给点积分吧) 还有还 ...
- STM32 IAP升级
STM32 IAP在线升级,用Jlink设置读保护后前5K字节是默认加了写保护的,导致IAP升级时擦除和写入FLASH不成功,可以做两个boot,前5k为第一个boot程序,上电时负责跳转到APP还是 ...
随机推荐
- mybatis批量插入、批量删除
mybatis 批量插入 int addBatch(@Param("list")List<CustInfo> list); <insert id="ad ...
- 拥抱Mac之码农篇
拥抱Mac之码农篇 使用Mac大概两年时间.之前用着公司配的一台27寸的iMac.无奈机械硬盘严重拖慢速度,影响工作心情.于是入手Macbook Retina 13.这两年的开发工作所有在Mac上完毕 ...
- Unity5.1 新的网络引擎UNET(七) UNET 单人游戏转换为多人
单人游戏转换为多人 孙广东 2015.7.12 本文档描写叙述将单人游戏转换为使用新的网络系统的多人游戏的步骤.这里描写叙述的过程是简化,对于一个真正的游戏事实上须要更高级别版本号的实际 ...
- java应用集锦9:httpclient4.2.2的几个常用方法,登录之后访问页面问题,下载文件
转账注明出处:http://renjie120.iteye.com/blog/1727933 在工作中要用到android,然后进行网络请求的时候,打算使用httpClient. 总结一下httpCl ...
- hdoj--1028--Ignatius and the Princess III(母函数)
Ignatius and the Princess III Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- netty结构
一.先纵览一下Netty,看看Netty都有哪些组件? 为了更好的理解和进一步深入Netty,我们先总体认识一下Netty用到的组件及它们在整个Netty架构中是怎么协调工作的.Netty应用中必不可 ...
- oracle (9I/10G/11G)数据库日志挖掘(审计误操作)
文档结构: 资料来自官方网站: https://docs.oracle.com/cd/E11882_01/server.112/e22490/logminer.htm#SUTIL019 来自论坛: h ...
- jQuery进度条设置
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta http-equiv="con ...
- UVa512 追踪电子表格中的单元格
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- PHP配置优化:php-fpm配置解读
PHP-FPM是一个PHP FastCGI管理器,php-fpm.conf配置文件用于控制PHP-FPM管理进程的相关参数,比如工作子进程的数量.运行权限.监听端口.慢请求等等. 我们在编译安装PHP ...