C - 将全局变量存储在闪存中?

时间:2015-09-22 08:33:57

标签: c embedded

正如标题所暗示的那样,我目前在我的程序中缺少SRAM,我找不到减少全局变量的方法。是否有可能将全局变量带入闪存?由于这些变量经常被读写,对于nand flash是否有害,因为它们的读/写周期有限?

如果闪光灯无法处理此问题,EEPROM会是一个不错的选择吗?

编辑: 对不起那些含糊不清的人。我正在使用Atmel AVR ATmega32HVB,它具有:   2K字节的SRAM,   1K字节的EEPROM   32K字节的FLASH

编译器:AVR C / C ++

平台:IAR Embedded AVR

我想摆脱的全局变量是:

uint32_t capacityInCCAccumulated[TOTAL_CELL];

int32_t AccumulatedCCADCvalue[TOTAL_CELL]; 

代码段:

  int32_t AccumulatedCCADCvalue[TOTAL_CELL];
    void CCGASG_AccumulateCCADCMeasurements(int32_t ccadcMeasurement, uint16_t slowRCperiod)
{ 
    uint8_t cellIndex;
    // Sampling period dependant on configuration of CCADC sampling..
    int32_t temp = ccadcMeasurement * (int32_t)slowRCperiod;

    bool polChange = false;
    if(temp < 0) {
        temp = -temp;
        polChange = true;
    }

    // Add 0.5*divisor to get proper rounding
    temp += (1<<(CCGASG_ACC_SCALING-1));
    temp >>= CCGASG_ACC_SCALING;

    if(polChange) {
        temp = -temp;
    }
    for (cellIndex = 0; cellIndex < TOTAL_CELL; cellIndex++)
    {
        AccumulatedCCADCvalue[cellIndex] += temp;
    }

    // If it was a charge, update the charge cycle counter
    if(ccadcMeasurement <= 0) {
        // If it was a discharge, AccumulatedCADCvalue can be negative, and that
        // is "impossible", so set it to zero
        for (cellIndex = 0; cellIndex < TOTAL_CELL; cellIndex++)
        {
            if(AccumulatedCCADCvalue[cellIndex] < 0) 
            {
                AccumulatedCCADCvalue[cellIndex] = 0;
            }
        }
    }   
}

这个

uint32_t capacityInCCAccumulated[TOTAL_CELL];
void BATTPARAM_InitSramParameters() {
        uint8_t cellIndex;
        // Active current threshold in ticks
    battParams_sram.activeCurrentThresholdInTicks = (uint16_t) BATTCUR_mA2Ticks(battParams.activeCurrentThreshold);

        for (cellIndex = 0; cellIndex < TOTAL_CELL; cellIndex++) 
        {
    // Full charge capacity in CC accumulated
            battParams_sram.capacityInCCAccumulated[cellIndex] = (uint32_t) CCGASG_mAh2Acc(battParams.fullChargeCapacity);
    }
    // Terminate discharge limit in CC accumulated
    battParams_sram.terminateDischargeLimit = CCGASG_mAh2Acc(battParams.terminateDischargeLimit);

    // Values for remaining capacity calibration
    GASG_CalculateRemainingCapacityValues();
}

2 个答案:

答案 0 :(得分:3)

  

对nand flash来说会不好,因为它们的数量有限   读/写周期?

是的,使用闪存来频繁修改数据并不是一个好主意。 从闪存中只读不会缩短闪存的使用寿命。擦除和写入将缩短闪存寿命。

与传统存储器相比,从闪存读取和写入速度要慢得多。

要写入一个字节,必须擦除整个块并重新写入闪存。

答案 1 :(得分:1)

任何类型的Flash都不适合用于频繁更改值:

  • 有限数量的擦除/写入周期,请参见数据表。
  • 非常慢的擦除/写入(擦除可以是~1s),参见数据表。
  • 你需要一个特殊的序列来擦除然后写(没有语言支持)。
  • 虽然最多阻止了对Flash的擦除或写入访问,但有些人根本不需要访问Flash(未定义的行为)。
  • 无法按字节/字自由写入Flash单元。大多数必须每页写入(例如64字节)并在更大的单位(段/块/扇区)中擦除大多数时间。

对于NAND闪存,与NOR闪存相比,耐用性更低,并且单元不太可靠(位可能偶尔翻转或有缺陷),因此您必须添加错误检测和纠正。这很可能是你不应该去的方向。

真正的EEPROM共享大多数问题,但它们可能是字节/字逐句(内部擦除)。

请注意,现代MCU集成&#34; EEPROM&#34;大多数时候也是Flash。一些实现仅使用稍微更可靠的单元(比程序闪存大约十十倍的擦除/写入周期)和允许任意字节/字写入(自动擦除)的附加硬件。但这仍然不足以进行频繁的更改。

但是,您首先应验证您的应用程序是否可以容忍长时间的写入/擦除时间。你能接受阻止这么长时间的进程,还是重写你的程序?如果答案是&#34; no&#34;,你甚至应该停止对这个方向的进一步调查。否则,您应计算预期寿命期间的更新次数,并与数据表中的信息进行比较。还有一些方法可以减少擦除周期,但是引线太远了。

如果可以选择外部设备(I2C / SPI),则可以使用串行SRAM。虽然更好(也可能更便宜)的方法是更大的MCU,或者考虑将数据存储在SRAM中更有效(即更少RAM,更多代码)的方式。