Skip to main content
Associate III
March 7, 2026
Solved

Unions and flash access

  • March 7, 2026
  • 5 replies
  • 387 views

I am wishing to write two floating point values to flash memory at time.  I understand it is best to write 64 bits at a time, hence my writing two floats at once.

 

This question is about using a union to structure the data. This code won't compile for the STM32L412KB.  Could someone please show me where I am going wrong? error on line 17.  Thanks.

struct dual {
 float v1;
 float v2;
};

struct dual two_readings = {1.23, 4.56};

union gemini
{
 struct dual left;
 uint64_t right;
};

union gemini value;


value.right=0;

 

Best answer by TDK

@gbm I felt this was getting a bit too off-topic for the OP which is concerned about flash endurance so I posted a new questions and answer here:

How atomic are the STRD/LDRD instructions on Corte... - STMicroelectronics Community

Let me know if I've misinterpreted the result.

5 replies

TDK
Super User
March 7, 2026

Are you doing "value.right = 0" at the global scope? That won't work. It needs to be within a function. Otherwise the code is fine. Global variables get initialized to 0 by default so the statement is not needed.

If you want to assign it explicitly at the global scope, do so in the definition:

union gemini value = { .right = 0 };

 

"If you feel a post has answered your question, please click ""Accept as Solution""."
Clyde_SAuthor
Associate III
March 7, 2026

Thank you.  I have read conflicting statements on the internet about writing to a union.  I shall give this a try.

 

Am I correct that I should write 64 bits at a time to flash?  That is, won't writes of two single 32 bit sized floats count as two writes from an endurance standpoint?

TDK
Super User
March 7, 2026

> Am I correct that I should write 64 bits at a time to flash?

Kind of. The flash page size is 64 bits and it has ECC. Writing the entire flash page "at once" is the only option. However, the actual write operation is done as 2x 32bit writes. Splitting it into a union is not necessary here.

stm32l4xx-hal-driver/Src/stm32l4xx_hal_flash.c at f8e66b7f8db10809f91a4360c154b6304fab06ba · STMicroelectronics/stm32l4xx-hal-driver

 

This isn't an endurance thing. What you can't do is write 32 bits, then go off and do something else, then write 32 bits later on.

"If you feel a post has answered your question, please click ""Accept as Solution""."
gbm
Principal
March 7, 2026

use:

*ptr = value.right; // write to flash

 

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
Clyde_SAuthor
Associate III
March 7, 2026

I recall reading in documentation, perhaps rm0432,  that the flash is 64 bits wide.  I would prefer to do a single write of a float value 32 bits.  The only reason I went to 64 bits at a crack was (possibly in error) because of endurance.  

 

I shall work some more at this.  Thanks.

Clyde_SAuthor
Associate III
March 7, 2026

from google...flash.PNG

Pavel A.
Super User
March 9, 2026

Situation with STM32L4 seems more complicated as it supports "fast programming mode".

Simple 64-bit programming is demonstrated in the HAL library (function FLASH_Program_DoubleWord):

https://github.com/STMicroelectronics/stm32l4xx-hal-driver/blob/f8e66b7f8db10809f91a4360c154b6304fab06ba/Src/stm32l4xx_hal_flash.c#L705

It splits the uint64 data to two uint32 and writes them successfully (of course no STRD's there). Looks like the flash controller has internal buffer which accumulates the 64-bit value before programming.

But then there's function FLASH_Program_Fast, it writes 32 or 64 64-bit words, depending on the STM32L4 model, at once, with interrupts disabled. Also without STRD's.

Not sure how useful this can be to the OP.

/* BTW in github you can mark a source line or few lines, click on the copilot icon - and it will explain the code. It does this **** *****ing well. Impressive. Requires logging in */