cancel
Showing results for 
Search instead for 
Did you mean: 

Interrupts and loss of Data

mejrissi
Associate II
Posted on May 15, 2014 at 19:35

I am currently building a big project on STM32F4 Discovery board for my graduation project. I have configured 4 Timers' interrupts (10Hz, 50Hz, 100Hz and 1kHz), USART communication with interrupt, and CAN communication. I am working with a lot of variables too.

My question is: If I am reading a variable, and lets say for example CAN_RX_Interrupt occurs and tries to set a variable while I am reading it in my main, will that cause a loss of Data? 

#interrupt-can-usart-data
9 REPLIES 9
Posted on May 15, 2014 at 20:18

My question is: If I am reading a variable, and lets say for example CAN_RX_Interrupt occurs and tries to set a variable while I am reading it in my main, will that cause a loss of Data?

Well it depends, the variable would need to marked as volatile, if the variable is changed in two places, or relates to other changed data, you have a potential for a race condition.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mejrissi
Associate II
Posted on May 15, 2014 at 20:25

Yes, I already marked it as volatile. And yes, the variable is changed in more than one place. Will that be a problem? If yes, how can I solve it? And thank you for your quick reply 🙂

Posted on May 15, 2014 at 20:36

Will that be a problem? If yes, how can I solve it?

Well it could interact in complex ways, but I don't know enough about your code. Figure out why you need to change it in multiple places, if its the correct method to use, if you need to lock/arbitrate access or for data structures whether you can queue them. The load-store nature of ARM designs is not friendly to schemes requiring an atomic read-modify-write operations.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 15, 2014 at 22:26

For variables which fit into a register (i.e. up to 32-bit integer and if the floating-point unit is used, 32-bit floats) are loaded/stored in one (thus uninterruptible) instruction, single accesses are naturally atomic; read-modify-write accesses are not (as in ARM they are not single instruction). It means, that for example if ISR reads a value from ADC and stores it into a variable, ''main'' can read it and it will always see a complete information. Contrary, if in ISR a 64-bit value is calculated and stored into a variable, as main needs at least two instructions to read this value, if an interrupt occurs after the first half of it was read (i.e. half of the old value), the second half will be read from the already updated variable (so the other half will be of the new value calculated in ISR).

The non-atomicity of read-modify-write operations means, that e.g. if main wants to perform var++ (even if var is up to 32-bit), it reads var into a register, increments it, but before writing back the ISR may kick in, modify var, then when returning, main will overwrite that new value by the incremented old value.

JW

mejrissi
Associate II
Posted on May 16, 2014 at 13:16

Hey guys, I found the answer to my question and I am sharing it with you. The read-write-instruction is not an atomic operation in ARM Cortex M4. However, you can make it an atomic operation by using bit-banding (my reference here is the ARM infocenter and The definitive guide to arm Cortex M3 and Cortex M4 book by Yiu). But in general it is recommended that you use exclusive access instructions to implement

semaphores.

John F.
Senior
Posted on May 16, 2014 at 13:34

Yes - but ... your question was about ''variables'' (which normally hold values).

Bit-banding is only atomic for a single bit operation.

Bit-banding maps a complete word of memory onto a single bit in the bit-band region. For example, writing to one of the alias words will set or clear the corresponding bit in the bitband region.

This allows every individual bit in the bit-banding region to be directly accessible from a word-aligned address using a single LDR instruction. It also allows individual bits to be toggled from C without performing a read-modify-write sequence of instructions.

mejrissi
Associate II
Posted on May 16, 2014 at 13:42

Okay, I guess that I understood what I read in the wrong way. Then, if the load/store operation for 32bit variables is atomic, can you provide with a document as a reference for this information? I can't find it anywhere and I will have to justify it. 

Posted on May 16, 2014 at 13:55

8, 16 and 32-bit variables are read/written in a single instruction, and single instructions are uninterruptible.

But, if you push it that hard, then yes, the compiler is free to make idiotic things, and it MAY read/write for example a 32-bit variable bytewise in 4 instructions. So to seek definitive assurance, you must ask your compiler vendor - but IMO it's rude to accuse any compiler maker of doing anything such stupid.

JW

chen
Associate II
Posted on May 16, 2014 at 13:59

Hi

I think you are getting lost in details and forgetting what you are trying to do :

''I am currently building a big project on STM32F4 Discovery board for my graduation project. I have configured 4 Timers' interrupts (10Hz, 50Hz, 100Hz and 1kHz), USART communication with interrupt, and CAN communication. I am working with a lot of variables too.

My question is: If I am reading a variable, and lets say for example CAN_RX_Interrupt occurs and tries to set a variable while I am reading it in my main, will that cause a loss of Data? ''

Trying to exchange data between main and ISRs

Clive1's point :

''Well it could interact in complex ways, but I don't know enough about your code. Figure out why you need to change it in multiple places, if its the correct method to use, if you need to lock/arbitrate access or for data structures whether you can queue them.''

Rather than relying on a single variable that every ISR and main all access the same variable (you asking for trouble!), find another way to transfer the information to/from the ISRs

eg post to main/ISR OR

guard (with semaphore/mutex)