cancel
Showing results for 
Search instead for 
Did you mean: 

Trying to learn how to program a double word

Anonymous
Associate II

Can anyone help me in understanding each part of the below function?

static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)

{

 /* Check the parameters */

 assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); /* What's this? */

 /* Set PG bit */

 SET_BIT(FLASH->CR, FLASH_CR_PG);

 /* Program first word */

 *(__IO uint32_t*)Address = (uint32_t)Data; /* What's this? */

 /* Barrier to ensure programming is performed in 2 steps, in right order

  (independently of compiler optimization behavior) */

 __ISB(); /* What's this? */ /* What's this? */

 /* Program second word */

 *(__IO uint32_t*)(Address+4U) = (uint32_t)(Data >> 32);

}

9 REPLIES 9

The assert() is typically used in debug builds to range check parameters passed in.

ISB is an ARM Instruction Barrier command, effects how the command fetches/completes

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/CIHGHHIE.html

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Anonymous
Associate II

Okay, what's this:  *(uint32_t*)Address

It casts an integer to an address of a uint32_t and fetches the uint32 from that address.

Basically a shorter form of:

uint32_t *tmp;

tmp = (uint32_t *)Address;

*tmp;

Thank you!

Piranha
Chief II

These questions are not STM32 specific, but a general C programming. Learn the C language first!

 /* Barrier to ensure programming is performed in 2 steps, in right order (independently of compiler optimization behavior) */
 __ISB();

And this one is a proof that ST's code monkeys do not understand what they are doing. ISB is not a memory barrier and does not ensure the order of memory accesses. Memory barrier instructions are DMB and DSB, of which DSB is more restrictive, but in this case DMB is enough.

I thought that a while, and yes, it's not memory barrier, but it is instruction barrier. And the idea is probably what it says in the comment: making the writing to happen in two steps - which it does. After the first write is done, the instruction pipeline is flushed (ISB). Then the instruction queue is refilled and then the second write is done. That introduces a small delay between writes, and makes sure the compiler can't decide to use multiple-write instruction, but the bus needs to be released in-between.

You are right about compiler barrier part, but for CPU instruction barrier does not enforce memory barrier. CPU can hold store operation in write buffer forever and ISB doesn't have impact on it. After ISB newly loaded instructions can still do and complete memory operations while that previous store operation is still waiting in write buffer. Whether that actually can happen on specific CPU implementations is another question. But what's the point in doing some dirty "seems to work" hacking with ISB, when DMB by definition has exactly the required behavior? 🙂

I think ISB doesn't allow the compiler to spit out LDM-instructions. But I have to agree that DSB would be safer in that the the latter store couldn't be even executed before the former gets acknowledged by the AMBA-bus slave.

Maybe ISB is there to flush I-cache, in case the program jumps to the flash area where it just wrote.

-- pa