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 }
"Chuckle. I hate it when people say LED lights...."
But isn't that a good expression, when you make a complete lamp from one or more LED, some armature etc?
Chuckle. I hate it when people say LED lights....
Nearly as bad as LCD display, PIN number or (my real hated but oh so common one) baud rate.
ROTFLMAO!
Erik was jabbing me just for the LCD bit :>
mine is functionable I've heard that on a major automobile manufactures' ad. shakes head...
and Erik, I may try that...
Silabs guys say:
" The info page is data only, so the interrupt will vector correctly. However if the interrupt access any data in that page of flash it will get results from the info page. "
So it looks like the code will execute under the scratch pad page, but any movx a,#dptr where dptr is pointing to 0-x7f will get set A to what ever is in the scratch pad page, not the underlying main flash page.
That also implies that code cannot execute from the scratch pad page.
So your idea of writing the stuff to the scratch pad page in the 040 instead of flash bullet proofs the code, so that if rouge code gets loose, it can only muck with the scratch pad because the bit for accessing the main flash won't even be in the code. Of course that will cause my checksum to fail... It solves the issue (unless rouge code happens to start executing in the middle of an instruction like the old Microsoft basic interpreters used to do).
Billy boy was fond of doing a branch into the second byte of a 3 byte instruction to execute the remaining two bytes as code, even if they were data, in order to save a byte or two.
I've been working with micros since 1976 and one of my hobbies was disassembling Microsoft Basics. I did the 6809 coco basic, the commodore PET basic, and the trs-80 basic. Completely disassembled and completely commented them.
Later I got a peek at the old microsoft CPM basic, and was amused at some of the comments. "Bill Gates wrote some fast stuff, and Paul Allen wrote some faster stuff" or something very close to that...Been a long time. In 1985 I learned C and rarely did assembly after that, but I did sell a set of cross assemblers under the name CrossSoft out of the old computer shopper.
Light Emitting Diode light.... Liquid Crystal Display display... Personal Identification Number number.... 's why Erik asked me if I stuttered.... :}
any movx a,#dptr where dptr is pointing to 0-x7f will get set A to what ever is in the scratch pad page, not the underlying main flash page. I doubt that very much, however a MOVC, will do so
Erik
right. sigh. Silabs says "to read from the scratch page, you have to access it with a code pointer, and to write to it you have to write it with a xdata pointer." So I take it that means after you have set the re-direct bit to send xdata writes to the flash..
I'm having some issues getting this to work. I can write from code space to cratch pad space. Got that working, I can copy a fixed string to the scratch pad flash page.
Right now, what is confusing me, is trying to copy data from one area of the scratch page to another area of the scratch page... it seems like I should set the flag to access the scratch page, read the byte into an data variable (not a xdata variable) then set the write enable, and redirect flag and write to xdata. It just is not working quite that way. What is happening is that I am reading data at the correct address, but instead of it being the scratch pad, it is the main code flash page, cause in trying to read 20 bytes from location 0 and program them into location 0x60, I'm copying a portion of the vector table into the scratch pad area.
I'll ultimately get it, but it doesn't seem like I can use the Keil CBYTE macro XBYTE macro to do this.