- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I would like to be able to permanently store data to flash of my PSoC5 processor and being able to retrieve it after rebooting the processor. I found sample project "Flash Example" that seems to be doing just that.
This is the code snippet how they store data to flash:
...
CySetTemp();
returnValue = CyWriteRowData(ARRAY_ID, ARRAY_ID_ROW_ADDR, rowPattern);
/* Check if operration is successful */
if (returnValue != CYRET_SUCCESS)
{
LED_Error_Write(LIGHT_ON);
CyHalt(0x00u);
...
It writes data to the flash and then immediately reads it and matches to what was stored. Everything works fine here. But if I modify this code such that when it runs first time it ONLY writes the data and the second it ONLY reads the data then the stored data is lost. So it looks like the stored data didn't survive the reboot OR reprogramming of the chip (I had to do it to comment out the code that writes data to flash).
Is there a way to burn something to flash so it stays there until explicitly erased?
Thanks!
Nikolay
Solved! Go to Solution.
- Labels:
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Question: Can I protect a flash region from being cleared during chip programming?
Answer: If you program the device use PSOC Programmer or Creator(include a mini programmer), you cannot protect a flash region from being cleared during chip programming because device flash is erased all first before program, this process is preset and fixed in software tool. Change the flash block protection level cannot prevent protected flash block be erased from external.
I think there are two ways to fix this issue:
(1) Store data in EEPROM of PSoC5LP, erase flash won't change EEPROM region.
(2) Design device program script use cli (command line), custom you own programming steps instead of use ready-made programming tools. Post 6. Re: Saving to flash also mentioned this method("unless you implement a custom program step). You can search "PSoC Programmer CLI User Guide.pdf" file on your PC to know how to do that.
If your design is a bootloader-bootlodable system, you can define a checksum-exclude region which won't be modified when bootlodable is upgrading by bootloader.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Have you tried using the EEPROM component? I think it just emulates EEPROM in flash, but it might make interfacing a little nicer than working with the flash directly.
Also have a look at these threads:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is another advantage of using the EmEEPROM component, wear leveling. Basically you can write to flash too many times and it will stick.
That said you are likely to lose your data when reprogramming the chip, unless you implement a custom program step. (There are other ways, but I don't have the documentation handy right now.)
If you just want to debug without programming, there is that option as well as attaching to a running target.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I just verified that writing to flash saves the data that survives a reboot. However, programming the chip clears the data.
So my original question comes to this one: can I protect a flash region from being cleared during chip programming?
Thank you, everybody, for help!
Nikolay
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I didn't think it would write over the EEPROM unless "Include EEPROM image in hex file" was checked in the EEPROM section of the design-wide resources. But it could be the case of it just writes 0xFF to all those EEPROM addresses unless you tick the box and give it something custom.
If you know exactly what addresses in flash you're saving into, you could perhaps mark it protected in the "Flash Security" tab in the design-wide resources. Mark the addresses 'R' and no external device should be able to clear it. I think the PSoC CPU should still be able to modify it. Check the PSoC Creator Help (search for "Flash Security") for more info on it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In the "Flash Security" tab I marked the row as "external write protect", but the result is the same.
The output of my program is below: when booted the first time the no data is saved in flash (expected). Then I hit Reset button a few times and the program can read the data from flash. Then I program the chip, it boots and the data is lost despite the flash row is marked as "external write protected"
What am I doing wrong?
Thanks!
Nikolay
P.S.
My test project is attached.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dang I thought the Flash Protection would have been it.
Are you running a Release or Debug build?
Does the same thing happen if you program via PSoC Programmer rather than through Creator? It seems unlikely but might be worth trying. Maybe Creator wipes it but Programmer wouldn't for some reason?
Just throwing stuff out there to try, since Flash Protection, as described in the help documentation, sounds like exactly what you want. it's really strange that didn't work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Programming with the Release build and/or PSoC Programmer didn't fix the problem.
Did I select the correct flash row to protect? I used the computations from the "Flash Example". Those macros, that they used, have a bit weird names and I keep confusing one with another. I think that the global row ID is 1022 which corresponds to array 3 with array's row ID 254. So I protected row 1022. Does it seem to be correct to you?
Thank you for your help!
Nikolay
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
If you don't mind using an EEPROM,
this seems to be working, too.
Note: Before the last line, I cycled the power of CY8CKIT-050.
schematic
main.c
===================
#include "project.h"
#include <CyFlash.h>
#include <stdio.h>
/* added on 28-Feb-2019 */
void print(char *str)
{
Debug_PutString(str) ;
}
int erase_EEPROM(void)
{
int sector_number = 0 ;
cystatus result ;
print("Erasing EEPROM ...") ;
EEPROM_UpdateTemperature();
result = EEPROM_StartErase(sector_number) ; /* use sectorNumber = 0 */
if (result != CYRET_SUCCESS) {
return( result ) ;
}
while((result = EEPROM_Query()) == CYRET_STARTED) {
; /* wait erase to finish */
}
if (result != CYRET_SUCCESS) {
print("Failed\n\r") ;
return( result ) ;
}
print("Done\n\r") ;
return( result ) ;
}
int blank_check_EEPROM(int address, int bytes)
{
int i ;
uint8_t data ;
int is_blank = 1 ;
EEPROM_UpdateTemperature();
for (i = 0 ; i < bytes ; i++ ) {
data = EEPROM_ReadByte(address + i) ;
if (data != 0) {
is_blank = 0 ;
break ;
}
}
return( is_blank ) ;
}
int
eeprom_store( uint8 *buf, uint16 sz )
{
cystatus result ;
uint16_t i ;
EEPROM_UpdateTemperature();
for (i = 0 ; i < sz ; i++ ) {
result = EEPROM_WriteByte(buf, i) ;
if (result != CYRET_SUCCESS) {
break;
}
}
return( result ) ;
}
void
eeprom_read( uint8 *buf, uint16 sz )
{
uint16_t i ;
EEPROM_UpdateTemperature();
for (i = 0 ; i < sz ; i++ ) {
buf = EEPROM_ReadByte(i) ;
}
}
/************************/
#define CY_TEST_FLASH_ROW (CY_FLASH_NUMBER_ROWS - 2u) // global ID of the row of interest
#define CY_TEST_FLASH_ADDR (CY_TEST_FLASH_ROW * CY_FLASH_SIZEOF_ROW) // address if the global row of interest
#define ARRAY_ID ((uint8)(CY_TEST_FLASH_ROW / CY_FLASH_SIZEOF_ROW)) // ID of the array that contains the row of interest
#define ARRAY_ID_ROW_ADDR ((uint16)(CY_FLASH_SIZEOF_ROW - 2u)) // address offset of the row of interest
//------------------------------------------------------------------------------
//
void
flash_store( uint8* buf, uint16 sz )
{
#ifndef CY_PSOC5
return;
#else
if( sz > CYDEV_FLS_ROW_SIZE ) return;
uint8 flash_row[ CYDEV_FLS_ROW_SIZE ];
memmove( flash_row, buf, sz );
cystatus ret = CYRET_SUCCESS;
CySetTemp();
ret = CyWriteRowData( ARRAY_ID, ARRAY_ID_ROW_ADDR, flash_row );
if( ret != CYRET_SUCCESS )
{
Debug_PutString( "CyWriteRowData(...) failed\n\r\b" );
//CyHalt( 0x00u );
return;
}
#endif // (CY_PSOC5)
}
//------------------------------------------------------------------------------
//
void
flash_read( uint8* buf, uint16 sz )
{
#ifndef CY_PSOC5
return;
#else
uint16 i = 0;
volatile uint8 flash_byte = 0;
if( sz > CYDEV_FLS_ROW_SIZE ) return;
for( i = 0u; i < sz; i++)
{
flash_byte = ( *( (uint8*) ( CYDEV_FLS_BASE + CY_TEST_FLASH_ADDR + i ) ) );
buf[ i ] = flash_byte;
}
#endif
}
//------------------------------------------------------------------------------
//
int
main( void )
{
CyGlobalIntEnable; /* Enable global interrupts. */
EEPROM_Start() ;
Debug_Start();
LED1_Write( 1 );
LED2_Write( 0 );
const static uint16 SZ = 8;
uint8 buf1[] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x01, 0x02, 0x03, 0x04 };
// uint8 buf1[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // for testing
uint8 buf2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Debug_ClearTxBuffer();
Debug_PutString( "booted: " );
if (blank_check_EEPROM(0, SZ)) {
erase_EEPROM() ;
}
eeprom_read(buf2, SZ) ;
// flash_read( buf2, SZ );
if( 0 == memcmp( buf2, buf1, SZ ) )
{
Debug_PutString( "data is stored\n\r\b" );
}
else
{
Debug_PutString( "data is not stored, storing ..." );
// flash_store( buf1, SZ );
erase_EEPROM() ;
eeprom_store(buf1, SZ) ;
// flash_read( buf2, SZ );
eeprom_read(buf2, SZ) ;
if( 0 == memcmp( buf2, buf1, SZ ) )
{
Debug_PutString( " stored\n\r\b" );
}
else
{
Debug_PutString( " not stored\n\r\b" );
}
}
for( ;; )
{
LED1_Write( ! LED1_Read() );
LED2_Write( ! LED2_Read() );
CyDelay( 250 );
}
}
===================
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Question: Can I protect a flash region from being cleared during chip programming?
Answer: If you program the device use PSOC Programmer or Creator(include a mini programmer), you cannot protect a flash region from being cleared during chip programming because device flash is erased all first before program, this process is preset and fixed in software tool. Change the flash block protection level cannot prevent protected flash block be erased from external.
I think there are two ways to fix this issue:
(1) Store data in EEPROM of PSoC5LP, erase flash won't change EEPROM region.
(2) Design device program script use cli (command line), custom you own programming steps instead of use ready-made programming tools. Post 6. Re: Saving to flash also mentioned this method("unless you implement a custom program step). You can search "PSoC Programmer CLI User Guide.pdf" file on your PC to know how to do that.
If your design is a bootloader-bootlodable system, you can define a checksum-exclude region which won't be modified when bootlodable is upgrading by bootloader.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Writing to EEPROM solves the problem!
Thank you everybody!