查看: 320|回复: 12
收起左侧

GD32的RTC及flash模拟EEROM是否可靠??

[复制链接]
     

11

主题

277

帖子

853

积分

高级技术员

 楼主| 发表于 2017-10-9 16:15 | 显示全部楼层 |返回版面|阅读模式
       我原来是用STM32的,别人类似的产品都是用外部RTC及外部EEROM的,我相当相信STM,就直接用了STM的内部RTC及用flash模拟EEROM,现在几万台产品出厂后,总有部份产品会在这俩个地方出问题,现在只能把这俩部份功能关掉不用了。
好像GD32比STM32技术更新。我新方案能否还用芯片内部的呢,还是老实发点钱用外部扩展的。这个现象不是全部都出问题,也不好直接就试出来,第二次改版总不能在几万台后再发现吧。。。。
    各位批量用过GD32的前辈指点一二,在下先谢了。。。
  

86

主题

4072

帖子

1万

积分

资深工程师

发表于 2017-10-9 23:04 | 显示全部楼层 |返回版面
模拟的eeprom还是有缺陷的,慎用
     

5

主题

28

帖子

84

积分

初级技术员

发表于 2017-10-9 23:32 | 显示全部楼层 |返回版面
用FLASH模拟EEPROM 这个概念第1次听说, 个人建议 把你需要保存的数据,封装到1个完整的结构体里, 每次有1个数据变化,先擦,确保不掉电下,写入。 page操作即可!! 虽然擦写会消耗ms级的时间,但利于代码编写。
EEPROM是可以单个字节直接写的,而FLASH要对已经写过的位置重新写入数值的话,就要先擦除,再写入。
#define  UNREGISTERED                          0x00
#define  FACTORY_FLASH_ADDRESS  0x800BC00                  //16KB的最后一页  15K不允许修改代码+1KB做EEPROM,以及后16KB升级代码区。
#define  NEED_SAVE_WORDS           80              //1页即可满足我们应用
typedef struct SystermInfO{
    u8  factory_recovery;   
        u8  gps_reporting_interval; //1~255S [配置错误0S 则为1]
   u16  user_uart_ttl_baudrate; //用户串口波特率  默认9600
    u8  use_mainandbkup_ipordomain;//高半字节[非0]表示主服务器使用的是IP(0表示域名), 低半字节[非0]表示备用服务器使用IP
        char server_ip[16];            //字符串形式的IP地址,结尾 ‘/0’ 保存在EEPROM中
        char server_domain[40];        //服务器域名  【域名前面不能加 www 否则无法建立TCPIP链接!!!】        
        char server_port[6];           //字符串形式的端口号, ‘/O‘ 结尾哦!便于后续使用
    char bkup_server_ip[16];   
        char bkup_server_domain[40];
        char bkup_server_port[6];
        u8   province;                 //省份
        u8   devID[4];                 //4字节为整型
        char gps_register_**;         //已经注册过的话
    u16  can0_baudrate;            //
        u16  can1_baudrate;            //
        u8   energy_subsystem;         //可充电储能子系统数
    /*以上需要掉电保存*/
        u8   rtc_time[6];              //依次年 17年  月  日 小时 分钟 秒
        char conncet_step;
   float  vin_value;      //输入电源电压  的格数
        //led
    u8  led_gprs_show_type ;// 0表示灭  1表示间隔1定时单位翻转  
        u8  led_gprs_times_ctr ;// 计数   
        u8  led_gprs_level_flip;// 记录前1次电平  0==低电平 1==高电平
        u8  led_gps_show_type ; // 0表示灭   1表示间隔1定时单位翻转  
        u8  led_gps_times_ctr ; // 计数   
        u8  led_gps_level_flip; // 记录前1次电平  0==低电平 1==高电平8  
}systerm_info_t;

extern systerm_info_t Sysinfo;
这个是我自己工程喜欢的用法, 系统管理结构体,开始的成员变量是掉电保存的!希望这个方式对你有用。
     

0

主题

9

帖子

27

积分

实习生

发表于 2017-10-10 16:19 | 显示全部楼层 |返回版面
本帖最后由 onz 于 2017-10-10 16:34 编辑

楼主的意思是数据访问上出了问题?
用flash和用EEROM都一样需要先擦除再写入,外部扩展只会增加环境干扰。
数据的稳定安全都需要在软件上加强:
1、比如写过程中途掉电必然令数据不完整甚至完全丢失,就需要考虑这种情况的补救:每次上电初始或运行中某一特定时刻对数据校验,若校验错误则恢复默认数据或备份数据等等。
2、比如写过程考虑屏蔽一些可能会产生较大电气干扰的的中断程序等等。
3、曾经遇到一个案例---设计要求按键触发擦写数据,但按键采样的电气设计没搞好,产品掉电过程令按键误触发擦写数据,数据又没写完就没电了。
     

5

主题

28

帖子

84

积分

初级技术员

发表于 2017-10-11 16:46 | 显示全部楼层 |返回版面
EEPROM 是不用先擦的,/*以下是STM8S内置EEPROM*/
void EEPROM_write_Nbytes(u32 addr, u8 *p, u8 len)
{  
    u8 n;  
    FLASH_Unlock(FLASH_MEMTYPE_DATA);
   
    while(FLASH_GetFlagStatus(FLASH_FLAG_DUL)==RESET);
    for(n=0; n<len; n++)
    {
        FLASH_ProgramByte(addr+n, *p++);
        while(FLASH_GetFlagStatus(FLASH_FLAG_EOP)==RESET);
    }
   
    FLASH_Lock(FLASH_MEMTYPE_DATA);
}

2. 按键一般建议 外部加RC硬件消抖,到哪都好使。
     

0

主题

9

帖子

27

积分

实习生

发表于 2017-10-12 00:15 | 显示全部楼层 |返回版面
本帖最后由 onz 于 2017-10-12 00:56 编辑
lvben5d 发表于 2017-10-11 16:46
EEPROM 是不用先擦的,/*以下是STM8S内置EEPROM*/
void EEPROM_write_Nbytes(u32 addr, u8 *p, u8 len)
{   ...

好像跑题了。不过有兴趣探讨一下,欢迎指正:

没用过stm8s,但曾经浏览过其参考手册关于编程操作的内容,没记错的话,机制大概是:写入一个字节前,硬件自动判断你定义的写入初地址的字(u32*)(addr+n)(4个字节:(u8*)(addr+n)、(u8*)(addr+n+1)、(u8*)(addr+n+2)、(u8*)(addr+n+3))是否为0,是则直接写入该“字节”,否则硬件自动先擦除该“字”(4个字节),再写入该“字节”----两种情况都是要求此4个字节都已事先擦除为0,两种情况的结果都是----4个字节:(u8*)(addr+n) = *p、(u8*)(addr+n+1) = 0、(u8*)(addr+n+2) = 0、(u8*)(addr+n+3) = 0。
所以,stm8s的eeprom同样必须遵循先擦后写,最小擦除单位是一个字(4个字节),只不过有硬件自动完成,用户代码无需显性擦除而已。
FLASH_ProgramByte(addr+n, *p++);   /* 功能:每次自检4个字节是否全被擦除为0,否则先自动擦除,然后写入1个字节 */

FLASH_ProgramByte(addr++, *p++);  /* 功能:同上 */

关于上面提到的按键,是1个AD脚串带10个按键,当然并了C, 但问题不在消抖,软件滤波很稳定,不并C完全没问题。
     

16

主题

1166

帖子

3571

积分

中级工程师

发表于 2017-10-12 09:00 | 显示全部楼层 |返回版面
flash模拟eeprom需要注意的是
1、写入函数定义到sram中,这样写入flash的时候不用再读flash指令,否则容易出问题;
2、flash写入是需要先页擦除的,也就是读--修改---擦除--写的过程。
     

11

主题

277

帖子

853

积分

高级技术员

 楼主| 发表于 2017-10-12 09:51 | 显示全部楼层 |返回版面
谢谢楼上几位热心的朋友,flash模拟eeprom这个我了解一些。
现在主要是想听听各位对GD芯片的认可,STM32这个芯片,是真的有点问题,举个例子,当STM32死机时,强行复位芯片复位脚,芯片也复位不了,只得重新上电才能正常工作,芯片复位都复位不了,软件什么手段都没用,软件的无非就是看门狗复位,然后进行数据纠错,现在程序都不运行了,就谈不上这些手段了。
     

0

主题

9

帖子

27

积分

实习生

发表于 2017-10-12 12:59 | 显示全部楼层 |返回版面
确定是程序死机?还是芯片振荡根本没起振?其实你也没找到bug。
一般是一个牌子芯片的产品成熟后,才考虑移植另一个牌子芯片,带病移植病还在。
STM32在市场这么多年了,官方勘误表和网络上的讨论也没提及复位有什么问题。
泛泛的讲MCU复位有好几种配置,不同的复位对RAM的影响可能不同,不保证复位后都硬件初始化RAM, 所以软件手动初始化重要的RAM是良好的习惯。
     

11

主题

277

帖子

853

积分

高级技术员

 楼主| 发表于 2017-10-13 09:48 | 显示全部楼层 |返回版面
go onz
是在工作过程出现的死机。程序在芯片中运行出现问题,无非是硬件问题或软件问题,就当是我软件问题,出现死机时哪种芯片直接强行复位复位脚,芯片是不能复位的?
芯片没有起振,不存在,因为是运行过程中出现的,就当是晶振及外围电路运行过程中出现问题,断电重启又正常了噢。
对于手动初始化重要的RAM是良好的习惯,这个有些书上也见过,但一直不太理解。
是指芯片自带寄存器?可寄存器都有一个上电默认值。在用C时,变量肯定都是先斌值再使用。
     

0

主题

9

帖子

27

积分

实习生

发表于 2017-10-13 17:04 | 显示全部楼层 |返回版面
本帖最后由 onz 于 2017-10-13 18:02 编辑

主电源是否稳定?开看门狗了没?芯片跑的是os还是单个程序?死机会不会是掉进Fault_Handler异常中断处理函数中了?至少要找到死机死在程序的哪个可能的部分吧?

结合顶楼的内容,我的做法是:出了问题的部件不该屏蔽不用,而是相反,把没问题的部件屏蔽以减少误判,集中力量debug问题部件。
比如若是怀疑复位脚有问题,就专门做个小程序测试复位脚功能是否正常咯。

断电重启和复位脚复位是不同的,你说的现象也证实了这点。以下是个人理解,欢迎指正:
一般MCU复位后其特殊寄存器都会硬件完成初始化默认值(个别位除外,见stm32参考手册),而对RAM(存放程序的临时数据、变量的值等)是不管的。
复位脚复位属于“系统复位”之一,特殊寄存器被硬件初始化,但RAM没掉电,复位之前的用户数据都在。如果不对这些RAM手动初始化,程序可能会发生因数据错误导致的故障。

78

主题

3590

帖子

1万

积分

资深工程师

发表于 2017-10-13 22:41 | 显示全部楼层 |返回版面
直接采用内部的flash进行设计的是可以的

24

主题

1420

帖子

4261

积分

中级工程师

发表于 2017-10-15 21:32 | 显示全部楼层 |返回版面
这个在新方案的时候把 这两两方面的要预留上
您需要登录后才可以回帖 登录 | 注册 手机登录

本版积分规则

分享 快速回复 返回顶部 返回列表