Flash擦写操作导致USART接收丢数据的话题
问题:
该问题由客户提出,发生在STM32F103VDT6器件上。据客户工程师讲述,在其产品设计中使用了STM32片上Flash模拟了EEPROM的功能,用于存贮数据。在软件调试时,发现开启此功能,会影响到USART通信,导致偶尔发生个别数据接收不到的现象。
调研:
检查其软件代码,发现其中对Flash上数据的更新操作分为如下几个步骤:
1. 保存Flash页上的数到RAM中;
2. 擦除Flash页;
3. 修改RAM中的数据;
4. 将RAM中的数据写回Flash页上;
对照STM32的数据手册,查找到相关的数据:
1. 字写入时间 40uS ~ 70uS;
2. 页擦除时间40mS;
检查软件代码,找到对USART的设置:
1. 波特率115200BPS;
2. 帧格式为1 个起始位,8个数据位,2个停止位;
检查软件代码,发现其对USART的接收数据采用中断的方式进行读取。
结论:
通过计算,USART的每个帧的传输时间为:
该时间大于Flash的字写入时间,小于Flash的页擦除时间。所以,在Flash页擦除期间有可能发生多次字节帧的传输。而在此其间,由于Flash接口不可用,CPU不能取指令,导致中断得不到及时响应,从而发生接收到的数据未及时读走而被覆盖的现象。
处理:
在内存中建立循环缓冲区,开启DMA 通道。一旦USART 有数据收到,DMA 负责将其传输至循环缓冲区中。软件定期检测循环缓冲区中是否有接收到的数据,如果有则加以处理。
建议:
在只有一个Flash 模块的STM32 中,CPU对 Flash 接口的使用具有独占性。该接口不能同时进行多个操作,比如,在写操作的同时进行读取操作,或在擦除操作的同时进行读取操作,即便读、写操作的地址不同,或者所读数据不在被擦除的页上也不行。因此,当程序运行在Flash 上情况下,在对Flash 进行写入、擦除操作时,往往会因为CPU 取不到指令而造成程序执行的停顿。这一现象会引发系统对外部事件响应上的不及时,必须采取相应的措施加以避免。
通常,对于通信接收数据这类事件,可以使用DMA 进行辅助,避免数据被覆盖。对于外部中断、定时事件等必须要软件及时响应的事件来说,可以将中断向量表转移到 RAM 中,同时将中断服务程存放在 RAM 中执行。CPU 的VTOR 寄存器用来存放中断向量表的偏移地址,修改该寄存器的值,可以改变中断向量表在内存空间中存放的地址,详见Cortex-M3 的技术参考手册。
在IAR 开发工具下,定义一个在RAM 中执行的函数,可以使用其扩展关键字__ramfunc,举例如下:
__ramfunc void EXTI9_5_IRQHandler(void)
{
If (EXTI_GetITStatus(EXTI_Line9)!=RESET)
{ /*clearthe EXTI line9 pending bit*/
EXTI_ClearITPendingBit(EXTI_Line9);
……
}
}
在Keil MDK 中,可以将相关的中断服务程序单独放在一个“.c”文件中,然后通过修改scatter 文件来实现在RAM中执行,例如中断服务程序放在“exti9.c”中:
LD_ROM 0x8000000 0x10000
{
EX_ROM 0x08000000 0x10000
{
Startup.o(RESET,+FIRST)
ANY(+RO)
}
EX_RAM 0x20000000
{
exti9.o(+RO) ;将中断服务函数放在RAM中
}
RW_RAM +O
{
startup.o(STACK,+ZI)
.ANY(+RW,+ZI).
}
}
话题延伸:
我们就上面问题做进一步的思考和探讨,抛砖引玉吧。
显然,导致程序发生执行停顿的一个关键原因是对Flash 进行了写或者擦除操作。如果排除这一原因,也就不会发生程序执行停顿了。所以,要解决这一问题,可以将数据暂存在RAM 中,而不用每次修改后立刻更新Flash。比方可以利用STM32 的PVD 功能监控电源电压,发现有掉电倾向时启动写Flash 操作,将RAM中暂存的数据写到Flash 。这样,在整个STM32 运行期间,只有到了最后时刻才对Flash进行了写操作,而这时也不需要再响应什么事件了(也没时间响应了)。这是一个不错的思路,当然,很多细节需要仔细斟酌。
首先,为节约这最后时刻的每一个微秒时间,Flash页面的擦除操作要提前完成。将这一操作放在STM32 开始监控各种事情以后自然不妥,因为同样会造成事件响应不及时。看来,最佳时间段只有系统初始化阶段了。
其次,在擦除Flash 期间发生掉电要如何处置?这时,备份在RAM 中的数据会来不及写回Flash 而丢失。为了避免这一情况的发生,可以使用双页交替存贮的方式(传说中的乒乓操作)保存数据。两个Flash 页上分别存有两个版本的数据,一新一旧,并在最后附有版本号及校验和。系统初始化时,选择的旧版本页面或无效页面进行擦除。这样,既便此时发生掉电,也无须向Flash 写回备份数据,因为最新数据仍在Flash中。而每次向Flash 更新数据时,都以更新的版本号进行标注,原来的新本数据自然的变成了旧版本。
再次,为了尽量延长最后的可用于写Flash 的时间,尽量降低系统功耗是非常有必要的。关掉PLL,直接使用OSC 送来的时钟作为系统时钟,可以明显的降低功耗。关掉所有外设的时钟可以进一步降低系统的功耗。根据片外电路的特性,调整I/O 的输出状还能进一步降低系统功耗。
=============================
往期话题链接:
推荐帖子
- mega这么容易解密,改Xmega如何?
- 老板最近让我们改用xmega128a3u,说是可以直接用USB下载显示内容而且暂时无法解密。原来的设计让深圳给仿了,没多少利润了。xmega对我这种小鸟有点困难,有大侠用过吗?给些快速进入状态的方法。mega这么容易解密,改Xmega如何?XMEGA备有一个支持高级加密标准(AES)和数据加密标准(DES)的硬件加密引擎。对于XMEG没啥了解,最好还是直接咨询代理商
- bluefox2000 Microchip MCU
- 关于CE下应用程序、驱动程序同步调试问题
- 请问各位如何做CE的应用程序、驱动程序的调试(无仿真器)在网上看到Mrocrosoft有个调试工具MrocrosoftActiveSync我下载安装了这个软件但是不能跟板子连接我用的串口连接方式请问各位都是用哪些调试工具,具体操作是怎么样的啊???关于CE下应用程序、驱动程序同步调试问题ActiveSync一般用USB连接,CE设备是Client端,PC机是HOST端。CE设备定制系统时,需要加入CoreOS-WindowsCEDevice-Application
- xtechman 嵌入式系统
- 急招Windows CE/Mobile驱动开发(南京5000-9000)
- 工作地点:南京待遇:5K-9KWindowsCE/Mobile驱动开发:要求:1.精通C/C++,理解面向对象思想,有良好的编程习惯;2.有WindowsMobile开发经验,对WindowsCE/Mobile系统有深入理解;3、具备独立的需求分析和设计能力4、终端软件性能调优5、掌握相关网络通讯协议(WIFI等)6、触摸屏和设备底层API7、文件解析和查询文件内容8、熟悉MFC有意者请发送简历至:yjwang5@isoftstone.c
- gorey 嵌入式系统
- 多路电流检测
- 各位友友,如果想同时检测16路电流或电压,有没有简单方便的电路设计,请指教(初步想法单片机+AD芯片)多路电流检测同时检测没有什么简单的办法,需要16路完整的前向通道和ADC。 你好,那有没有资料或设计参考呢为什么要同时检测?两路信号之间相差数微秒就不行吗?如果允许相差数微秒,那就容易多了。一定要同时,可以考虑用多片采样-保持芯片,同时采样,轮流检测。 这个去找找工控方面的书看看吧,多路数据采集系统是工控领域很常见的产品。stmcu上的多
- xxhhzz stm32/stm8
- 碳弧老化试验箱在汽车行业的应用
- 碳弧老化试验箱在汽车行业的应用 碳弧老化试验箱主要应用日本标注,大家知道日本的企业工业是比较发达,而且其他行业对于老化的测试实验都有用到碳弧老化试验箱,目前我国的较多企业同日本企业有合作,所以碳弧老化试验箱的使用较大,今天标准集团(香港)有限公司小编来讲讲碳弧老化试验箱在汽车内饰行业的实验检测标准。 汽车零件,高分子材料,耐候性检测也称为可靠性检测,是指材料如涂料、建筑用塑料、橡胶制品等因受到阳光照射,温度变化,风吹雨淋等外界条件的影响,而出现的褪色,变色,龟裂,粉化和强度下降等一系
- standard123 汽车电子
- 超声波接收电路设计
- 掌握超声波接收电路的设计、仿真与调试,门宽和门前沿都在10~100μs可调,增益50~1000倍可调,峰值检波输出最大可达4.7V,其中时间精度高于5%,增益精度高于10%;超声波接收电路设计门宽和门前沿都在10~100μs可调,增益50~1000倍可调webmaster090发表于2015-1-1721:31门宽和门前沿都在10~100μs可调,增益50~1000倍可调 是啊,你会吗?
- hua365737717 stm32/stm8