I am trying to write in STM32L476's flash memory using a JTAG ST-Link/V2 on Windows 7. No software has to be uploaded, I only need to write data in a non-volatile place where it can be read and deleted.
As a newbie regarding hardware and being efficient only when programming non-embedded regular C, I am afraid I might harm or modify irrevocably the flash memory. Also, I am not really sure regarding what I can or cannot do.
I have figured out reading the manual that writing in 0x08000000 memory place seemed to be a good idea. Using C code to make calls to ST-Link_Utility :
const char CMD_ACCESS_ST_UTILITY[] = "cd C:/Program Files (x86)/STMicroelectronics/STM32 ST-LINK Utility/ST-LINK Utility&&ST-LINK_CLI.exe ";
bool STLINKWriteSystemCalls(void)
{
char cmd[200] = "";
strcpy(cmd, CMD_ACCESS_ST_UTILITY); // cmd to access utility
strcat(cmd, "-c"); // Then connect with ST-Link
if (system(cmd) != 0)
return false; // If failed exit
strcpy(cmd, CMD_ACCESS_ST_UTILITY);
strcat(cmd, "-r8 0x08000000 0x100"); // Read to check if there is data already
// I haven't managed yet how I'll compare the result of read
// To FFFF but that's not the main issue
if (system(cmd) != 0)
return false; // If failed exit
strcpy(cmd, CMD_ACCESS_ST_UTILITY);
strcat(cmd, "-w8 0x08000000 0x00"); // Write data into 0x080000000
if (system(cmd) != 0)
return false; // If failed exit
return true;
}
Is there a better way to do this regarding where to write and how to write (errors checking, ressource used etc) ?
Main things to know about flash memories:
- Flash memories are page erasable, in your case page size if
2K
. What does it means? That you must be sure that your code does not resides in the 2k
range of page.
- After erase the state of all bytes in memory is 0xFF.
- Write to a flash byte means, at raw level, to modify bits set to
1
to bit set to 0
. If you want to modify a bit from 0
to 1
you must erase a whole page.
ST-Link_Utility
does it embedded way, so when you write to flash it erase a whole sector ans then write data. The same if your code is required to ease data after they are used.
By default your mCU, at startup, uses 0x0000 0000
aliased address of 0x0800 0000
.
First words should contain the reset vector and the default vector table. Reset vector is always the first instruction to be executed.The reset vector in this table will contain a branch to an address which will contain the reset code.
So, in other words,
At the time of power up, the processor jumps at fixed location 0x0, which means it jumps at 0x0800 0000
. Obviously the address you selected is not correct ;)
Good news! Since you're using ST Link utility you can't destroy the chip. It will simply refuse to write where there is no accessible memory.
The only way to permanently lock yourself out of the chip is to enable the read protection to the maximum level 2. To do this you have to write to the option bytes. And you do not accidentally write 0xCC33 to the lock bytes.
One thing to consider is that the chip only writes halfwords (16 bits) and only when the FLASH is still 0xFFFF (erased state). Otherwise it will return write error.
Update: manual snippet frome RDP. Code read protection.
Level 2: No debug
In this level, the protection level 1 is guaranteed.
In addition, the Cortex®-M4 debug port, the
boot from RAM (boot RAM mode) and the boot from System memory (boot loader mode)
are no more available.
In user execution mode (boot FLASH mode), all operations are
allowed on the Flash Main memory.
...
The level 2 cannot be removed at all:
it is an irreversible operation.
In short: do not write to 0x1FFF7800.