This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Flash protection

I'm using silabs parts. The 040 has a vmon protection that resets the process when the supply voltage drops to a point where flash could be corrupted.
That is enabled in my code.
We are seeing devices come back with apparently corrupted flash (these are locked so we actually
cannot see the flash contents, but they appear to be locked in reset loops or partially run and then get crazy.

In order to ensure that rouge code doesn't execute the flash write routines, I'd like to be able
to alter the flash by using code to overwrite the flash enable lines with nops so it will
physically be impossible for the code to alter flags required to initiate a flash write.

Generating code that can overwrite a function is proving to be difficult. How can I force
Keil 7.5 C51 compiler to do this?

To enable the flash writes on the silab part, you have to set a bit that enables
flash write/erase, then you set a bit that changes the target of the MOVX instruction so that it targets flash. you need code that looks like this:
CBYTE can also be used, but it is throwing some strange error messages.

unsigned char code* ptr;

ptr=&lcation; // point to a byte in flash boo();
....
boo()
{ FLSCL=1; PCTL=1; // *ptr=0xAA; // generates a MOVX which, due to the bits above, will target flash PCTL=0; FLSCL=0; // now movx instructions access xram, and writes are disabled.
}


What I want to do is to add in a line of code after the bits are set, that will reference foo + some offset.
For example, foo+3 happens the be the FLSCL instruction. The CBYTE macro throws an error.
When I do a manual replace like this:


      *((unsigned char volatile code * &(foo))=0x00;


The compiler swallows it nicely, and completely eliminates the above line.
I thought about using a label and generating a point to it, but C doesn't allow that. Then
the thought occurred : "Well you can take the address of a function:..."

Currently I have code running that does something similar to this as part of a personalization/configuration procedure:

but I can't make the compiler generate a pointer to foo (see above) CBYTE[foo] throws an
error. CBYTE[&foo()] throws an error.....


This is from working code:

void configure_me()
    {
    unsigned char volatile xdata * write_ptr;

    unsigned int t;

    saved_ie = IE;
    EA = 0;                            // disable interrupts (precautionary)
    write_ptr=&(security[0]);    // it is critical that this comes before flash
                                // enable.  The damn compiler uses movx
                                // otherwise and screws things up

    FLSCL=0x01;               // enable flash write/erase
    PSCTL=0x01;               // NOT 2, which would erase flash, but 1 write to flash
    *write_ptr=CBYTE[0xFA00];
    PSCTL = 0x00;              // MOVX writes target XRAM
    FLSCL=0;                   // disable flash write

    write_flash(&(security[1]),0xFA00,20);   // copy serial number
    FLSCL=0x01;               // enable flash write/erase
        PSCTL = 0x03;         // MOVX writes target FLASH memory, and erase is ENabled
    XBYTE[0xFA00]=0;          // erase the flash page
    PSCTL=0x00;
    FLSCL=0x00;                // disable flash write

    IE=saved_ie;
}

idata unsigned char byt2wrt;


void write_flash( unsigned char  * dest,  unsigned char  code*  srce,   int len)
    {
    char EA_save;                      // saves the current state of the interrupts
    register volatile unsigned char code * source;
    register volatile unsigned char xdata * destination;

    EA_save = EA;
    EA = 0;                            // disable interrupts (precautionary)
    source=srce;
    destination=dest;
    FLSCL=0x01;               // enable flash write/erase

    do
        {                          // copy until len is 0
        byt2wrt=*srce;             // ensure that no MOVX is used. Variable is in idata.
        PSCTL = 0x01;              // MOVX writes target FLASH memory, and erase is disabled
        *destination=byt2wrt;
        PSCTL=0;                   // MOVX writes to xdata
        srce++;                    // advance pointers
        destination++;
        len--;
        }
    while (len != 0);
    PSCTL = 0x00;              // MOVX writes target XRAM
    FLSCL=0x00;                // disable flash write
    EA = EA_save;                      // re-enable interrupts

    }