RAK4630 Flash random bytes

Hello,

As our product developement goes I have a question regarding RAK4030 internal flash.

We need to save on internal flash multiple data (schedulers and config bits) In order to help our development I’ve done a quick and dirty custom AT command in order to check via terminal specific flash offset with both save and read operations.

I’ve noticed that after subsequent firmware flashes the area gets written with random characters, at least on offsets 0X00000 and 0x00016.

Why is this happening? Is it safe to erase them?

Maybe we can move to a superior offset (0x1000) in order to check if this offset gets erased or written with random bytes.

We know RAK4630 offsets go from 0x00000 to 0x20000. What about RAK11720?

Many thanks in advance!

For example purposes, this is my write to flash dirty code. Beware, it doesn’t do size checks and so on…

bool set_flash(uint32_t offset, uint32_t value)
{
	uint8_t flash_value[16] = {0};

	flash_value[0] = (uint8_t)(value >> 0);
	flash_value[1] = (uint8_t)(value >> 8);
	flash_value[2] = (uint8_t)(value >> 16);
	flash_value[3] = (uint8_t)(value >> 24);
	flash_value[4] = (uint8_t)(value >> 32);
	flash_value[5] = (uint8_t)(value >> 40);
	flash_value[6] = (uint8_t)(value >> 48);
	flash_value[7] = (uint8_t)(value >> 56);
	flash_value[8] = (uint8_t)(value >> 64);
	flash_value[9] = (uint8_t)(value >> 72);
	flash_value[10] = (uint8_t)(value >> 80);
	flash_value[11] = (uint8_t)(value >> 88);
	flash_value[12] = (uint8_t)(value >> 96);
	flash_value[13] = (uint8_t)(value >> 104);
	flash_value[14] = (uint8_t)(value >> 112);
	flash_value[15] = (uint8_t)(value >> 120);

	if (!api.system.flash.set(offset, flash_value, sizeof(value)))
	{
		MYLOG("AT_CMD", "Failed to write Flash");
		return false;
	}
	MYLOG("AT_CMD", "Write flash result: 0X%02X 0X%02X 0X%02X 0X%02X 0X%02X 0X%02X 0X%02X 0X%02X 0X%02X 0X%02X 0X%02X 0X%02X 0X%02X 0X%02X 0X%02X 0X%02X",
			  flash_value[0], flash_value[1],flash_value[2], flash_value[3], flash_value[4], flash_value[5], flash_value[6], flash_value[7], flash_value[8],
			  				 flash_value[9], flash_value[10], flash_value[11], flash_value[12], flash_value[13], flash_value[14], flash_value[15]);
	return true;
}

Data in the flash area used by the API api.system.flash should not be touched by a firmware update, I will ask our R&D team to check why this happens.
If you don’t care, you can overwrite anything there, this is reserved area for your custom code usage.

But this is critical, because others might write data there that should survive a firmware update without being changed.

RAK11720 has the same amount of flash memory, the size should be the same, but I will check.

1 Like

Thanks as always Bernd,

Currently we moved the data to addresses > 0x11100 and implemented a “magic” byte to check if flash went wrong. At our current firmware size, this address doesn’t get rewritten.

We’re saving about 16bytes of data for each module output (11), so we need this data consistent…
Does the flash api have some kind of wear leveling techniques?

Regards!

Have to ask about wear leveling, but I am guessing the answer is NO.

One question about flash content changing on firmware update, how do you update the firmware?
From Arduino via USB or with Jlink via the SWD pins?

I’m using USB at the moment. The IDE I’m using is Vscode + Arduino on windows.

Same here, VScode with Arduino extension.

I can confirm something strange is going on already.
I cannot change the values in the user flash on address 2 to 6.
But flashing a new firmware doesn’t change any values in the user flash.

I will open an internal issue with our R&D team.

My test:
(1) write 1kB into the user flash
(2) check written values against expected
(3) if different, write again 1kB
(4) check written values against expected
(5) reflash same firmware, only small change
(6) check flash content against expected
(7) if different, write again 1kB
(8) check written values against expected
(9) write complete different firmware and let it run (double the size of the flash test firmware)
(10) write back flash test firmware
(11) check written values against expected
(12 if different, write again 1kB
(13) check written values against expected

2023-09-21 17:47:08 --> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2023-09-21 17:47:08 --> Read after reset starting 0
2023-09-21 17:47:08 --> Adr 2 read 00 expected 02
2023-09-21 17:47:08 --> Adr 3 read 00 expected 03
2023-09-21 17:47:08 --> Adr 4 read 00 expected 04
2023-09-21 17:47:08 --> Adr 5 read 00 expected 05
2023-09-21 17:47:08 --> Adr 6 read AA expected 06
2023-09-21 17:47:08 --> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2023-09-21 17:47:08 --> Check if changed
2023-09-21 17:47:08 --> Write because changed
2023-09-21 17:47:08 --> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2023-09-21 17:47:08 --> Read second time
2023-09-21 17:47:08 --> Adr 2 read 00 expected 02
2023-09-21 17:47:08 --> Adr 3 read 00 expected 03
2023-09-21 17:47:08 --> Adr 4 read 00 expected 04
2023-09-21 17:47:08 --> Adr 5 read 00 expected 05
2023-09-21 17:47:08 --> Adr 6 read AA expected 06
2023-09-21 17:47:08 --> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2023-09-21 17:47:08 --> Read after reset starting 32
2023-09-21 17:47:08 --> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2023-09-21 17:47:08 --> Check if changed
2023-09-21 17:47:08 --> No changes in flash!
2023-09-21 17:47:08 --> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2023-09-21 17:47:08 --> Read second time
2023-09-21 17:47:08 --> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Going on with this issue, on my current firmware I’m reading / writing 11 groups of 16 bytes to addresses 0x11000, 0x12000, 0x13000 and so on till 0x12100.

I’ve implemented a check with the first and last byte of each address group, if at the time to read them, the byte 0 and byte 15 is not equal to a “magic” byte (fixed known value), then I generate a boilerplate config to these bytes and save them to flash again. This check is done at setup() stage.

Successive firmware flashes demonstrate that my “security” function gets triggered about 80% of the time, no matter if code size changes or not.

I suspect, the flash utility sends the firmware to these addresses, but there is some randomness here:

As a side note I have the feeling that probably next days of consecutive firmware flashes maybe the flash utility will use another flash offset to write the firmware (to add some wear leveling at firmware flash time)

Hi Javier,

Sorry for the delayed answer, I was travelling.

I found that in my test, there was actually something running in the background of my app that was changing the first 6 bytes.
After removing this writing and reading works without problems. Our R&D team could not reproduce the problem either.

Just to double check, you are using RUI3 V4.0.6?

Hello Bernd

Yes, I’m using RUI3 v4.0.6. I’ve double checked my code and I think it’s okay. Will send my code snippet to you.

Thanks

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.