cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F1 atomic operation (ISR and main variable sharing) and assembly question

FF1
Associate III

Dear all,

I'm checking if a variable assignement is atomic or not. I know that are many stuff on this subject but I need to approach from a low level perspective to better know what happen under the scene and then have better control of my code.

To do that I'm looking the dissassembler window during the debugging stage, I'm using the IAR IDE v8.32.1 but my question is not related to this specific IDE/Compiler.

A variable with name Nstep_total is update under ISR and is also declared to be volatile, here below my declaration:

volatile int32_t Nstep_total = 0;  // Updated under ISR

Under the ISR code I've to write the Nstep_total variable and into the main code I have only to perform a read. This operation is made by means of a temporary variable called Nstep_total_tmp definited into my main code as.

int32_t Nstep_total_tmp = 0; // Temporary variable used to store the Nstep_total

in other words, instead to use directly the Nstep_total variable in my calculations, I simply do an assignement to another variable and then I'll use this temporary variable value for my purpose.

What I need to discover is if this assigment is performed as atomic or not in order to avoid any strange code behaviour.

Here below I written the piece of code that perform the assignement of the Nstep_total to the temporary Nstep_total_tmp variable.

   Nstep_total_tmp = Nstep_total;

   0x80011b8: 0x4843        LDR.N    R0, [PC, #0x10c]       ; Nstep_total

   0x80011ba: 0x6800        LDR      R0, [R0]

   0x80011bc: 0x0005        MOVS     R5, R0

   Into the assembly window I can see a LDR.N instruction, from the IAR Asembler guide I can read:

   "By specifying a 16-bit version explicitly with the LDR.N instruction, a 16-bit instruction is always generated. This may lead to the constant being placed in the literal pool, even though a 32-bit instruction could have loaded the value directly using MOV or MVN."

so the meaning of this instruction would be load a 16 bit address into the register R0, address is contained into the location ad address PC+0x10c, performing this sum with PC=0x80011b8 give 0x‭80012c4‬, checking at this address I can see:

...

0x80012b8: 0x2000008c    DC32     cSPIN_rx_data

0x80012bc: 0x2000000c    DC32     cSPIN_RegsStruct

0x80012c0: 0x004fffff    DC32     0x4fffff (5242879)

0x80012c4: 0x2000009a    DC32     button3

0x80012c8: 0x2000007c    DC32     Nstep_total

0x80012cc: 0x20000084    DC32     Delta_step

0x80012d0: 0x20000080    DC32     Nstep_current

0x80012d4: 0x20000088    DC32     Delta_step_tmp

0x80012d8: 0x2000000a    DC32     Dir_old

...

the correct variable should be Nstep_total which is at the next place, may be I've to consider the PC +4 byte instead the value where the breakpoint is? Someone can please let me know some about this point?

After that the Nstep_total value is loaded into the R0 general purpose register, the LDR instruction is able to load in a single cycle a 32 bit of data so from this it appear to me that this operation should be atomic, I'm thinking correctly?

The next instruction (MOVS) take the content of the R0 general purpose register and move it into the Nstep_total_tmp temporary variable then, If I correctly understand the code, the assignement performed by the LDR instruction is atomic and then I should be fully protected from any side effect in my code from the copresence of ISR variable writing and the main access to the Nstep_total variable.

I'm doing right or I've missed something?

Thank for your time!

Best regards

Fabio

1 ACCEPTED SOLUTION

Accepted Solutions

PC points to the instruction going to be executed next.

View solution in original post

3 REPLIES 3
Uwe Bonnes
Principal III

Yes, reading an aligned variable of up to 4 byte length is atomic on a 32 bit CPU.

Thank you @Uwe Bonnes​ ,

could you please let me know also about the apparent discrepance between the PC + 0x10c and the real address of my variable? There are 4 bytes in difference..

Thank!

BR

Fabio

PC points to the instruction going to be executed next.