C - Store global variables in flash?

左心房为你撑大大i 提交于 2021-01-29 02:30:43

问题


As the title may suggest, I'm currently short on SRAM in my program and I can't find a way to reduce my global variables. Is it possible to bring global variables over to flash memory? Since these variables are frequently read and written, would it be bad for the nand flash because they have limited number of read/write cycle?

If the flash cannot handle this, would EEPROM be a good alternative?

EDIT: Sorry for the ambiguity guys. I'm working with Atmel AVR ATmega32HVB which has: 2K bytes of SRAM, 1K bytes of EEPROM 32K bytes of FLASH

Compiler: AVR C/C++

Platform: IAR Embedded AVR

The global variables that I want to get rid of are:

uint32_t capacityInCCAccumulated[TOTAL_CELL];

and

int32_t AccumulatedCCADCvalue[TOTAL_CELL]; 

Code snippets:

  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;
            }
        }
    }   
}

And this

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();
}

回答1:


Any kind of Flash is a bad idea to be used for frequently changing values:

  • limited number of erase/write cycles, see datasheet.
  • very slow erase/write (erase can be ~1s), see datasheet.
  • You need a special sequence to erase then write (no language support).
  • While erasing or writing accesses to Flash are blocked at best, some require not to access the Flash at all (undefined behaviour).
  • Flash cells cannot freely be written per-byte/word. Most have to be written per page (e.g. 64 bytes) and erased most times in much larger units (segments/blocks/sectors).

For NAND Flash, endurance is even more reduced compared to NOR Flash and the cells are less reliable (bits might flip occasionally or are defective), so you have to add error detection and correction. This is very likely a direction you should not go.

True EEPROM shares most issues, but they might be written byte/word-wise (internal erase).

Note that modern MCU-integrated "EEPROM" is most times also Flash. Some implementations just use slightly more reliable cells (about one decade more erase/write cycles than the program flash) and additional hardware allowing arbitrary byte/word write (automatic erase). But that is still not sufficient for frequent changes.

However, you first should verify if your application can tolerate the lengthly write/erase times. Can you accept a process blocking that long, or rewrite your program acordingly? If the answer is "no", you should even stop further investigation into that direction. Otherwise you should calculate the number of updates over the expected lifetime and compare to the information in the datasheet. There are also methods to reduce the number of erase cycles, but the leads too far.

If an external device (I2C/SPI) is an option, you could use a serial SRAM. Although the better (and likely cheaper) approach would be a larger MCU or think about a more efficient (i.e. less RAM, more code) way to store the data in SRAM.




回答2:


would it be bad for the nand flash because they have limited number of read/write cycle?

Yes it's not a good idea to use flash for frequent modification of data. Read only from flash does not reduce the life time of flash. Erasing and writing will reduce the flash lifetime.

Reading and writing from flash is substantially slower compared to conventional memory.

To write a byte whole block has to be erased and re written in flash.



来源:https://stackoverflow.com/questions/32712167/c-store-global-variables-in-flash

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!