Electronic – What are the caveats of placing PSoC 4 variables in flash

cflashpsoc

PSoC4 chips have only between 2 and 4KB of RAM. That's not much, especially if I want to do some data processing. Between 16 and 32KB of Flash seems much more promising, even if I need to share it with the code. Thanks to the "Flash Accelerator" it seems one can use Flash the same way as one would use SRAM, only at cost of a minor performance drop. There's a document that describes how to do it, and it seems quite trivial:

in Project > Build Settings > Linker > Command Line > Custom Flags add:

     -Wl,--section-start=.MY_SECTION=0x00001000

then declare your variable as:

     uint8 variable1 __attribute__ ((section(“.MY_SECTION”)));

(that is using GCC, as PSoC Creator does "out of the box").

Now if I understand correctly, the first thing to consider is the standard 100k write cycles that standard PSoC4 chips have. Performing 100k writes to a variable can take a very short time; does the "accelerator" protect the cell or do I risk damage to the chip with a simple for(uint32 flash_var __attribute__ ((section(“.FLASH”)))=0 ;flash_var<100000;flash_var++){...}?

Next – can I expect the variable to persist its value across power loss, or do I need some extra wizardry to obtain this functionality?

Does that play nice with bootloader in bootloadable applications, or do I risk overwriting the bootloader or something like that?

What other considerations concerning that kind of variables should I have in mind, that I haven't thought of – and which I'd likely learn only "the hard way" if I don't ask?

Best Answer

I had very good results using the PSoC3's Emulated EEPROM, and I believe the E_EEPROM component is the same for both PSoC3 and PSoC4. Here are your easy answers first:

  1. Yes, the values will stay persistent across power loss, as long as the power loss doesn't occur during the write cycle.

  2. You shouldn't have any issues with your E_EEPROM variables overwriting anything. If you're using the Cypress macros correctly, the compiler should be locating empty flash locations for you. However, I have no idea what happens if you allocate more flash variables than you have room for. I would hope the compiler would throw an error for you, but I haven't tried it.

  3. I would check your documentation again for how to actually use the E_EEPROM. The PSoC3 used the Keil compiler because the core is actually an Intel 8051, unlike PSoC4's ARM core, so it's possible that you're correct. But it seems more complicated than it needs to be. I didn't have to use any compiler flags, and the Emulated EEPROM component provided a much easier to use API. Also, take a look at the example projects that come with PSoC Creator.

Here's the downside: As far as I know, you do need to worry about flash wear levelling. I was unable to find any references to an automated wear-levelling scheme in the PSoC3 docs, so I assume there is none. You can definitely wear out your Flash cells with repeated writes, though the compiler may be smart enough to optimize out the Flash writes in your loop example.

Keep in mind that you also don't need to write to the same variable to wear things out. In the PSoC3, flash rows are 256 bytes wide. If you have an array of 32 uint8's and that array happens to align perfectly with a Flash row, writing to any element of the array is going to put the entire array through a Read-Erase-Write cycle. The PSoC4 row size might be different, but you're going to face the same situation.

The E_EEPROM was a perfect solution for me when I needed data to stay persistent across resets, and didn't have nearly enough real EEPROM. It's a good option as long as you have the space and take care to avoid wearing out your Flash cells.