EmbDev.net

Forum: µC & Digital Electronics Atomic write - STM32


von Lasse S. (cowz)


Rate this post
useful
not useful
Hi,

I'm currently working with a STM32F4 and try to implement atomic access 
to variables (e.g. mutexes).

Currently, I disable all interrupts before accessing a mutex, and enable 
them afterwards.

Now there exist the LDREX and STREX commands on the STM32, which seem to 
be perfect for my application. But how do I use them correctly? In the 
manual it says that an STREX must have the same address as the 
previous LDREX. So I still need to disable interrupts (or atleast the 
scheduling), as in another task I might have another LDREX/STREX 
combination.

Is there any other way for read/check/write operations? Mutexes are only 
one of my concerns, another is:
- i have a list of integers, which are all set to zero
- i want to set one of those entries to 1 (==this entry is busy, don't 
use it)
- do some calculations and in the end set that same entry to another 
value (>1)
This should be working with scheduling and interrupts (both tasks and 
interrupts access this list, therefore waiting for mutexes is not 
possible).

Also disabling the interrupts is bad, as I actually don't want my 
processes to have the rights to do that.

I hope you can help me, or point out that I'm just not seeing the easy 
possibility.

Yours
Lasse

von Fritz (Guest)


Rate this post
useful
not useful
You should read the The Cortex-M4 Instruction Set Manual carefully. You 
get a resultvalue aftera LDREX/STREX pair. The STREX only executes if 
there was no other LDREX/STREX beetween by an other interrupt. You have 
to repeat the LDREX/STREX pair. There is also an example in the manual.

Not to allow a process or task to enable or disable the interrupts is a 
good idea, but you should also not allow LDREX/STREX in a process or 
task, this are typically system interna. Usually a RTOS handles this in 
special system calls!

You can change a list of integer in the following way:

Examples
MOV  R1, #0x1 ; Initialize the ‘lock taken’ value

...
try
LDREX  R0, [LockAddr] ; Load the lock value
CMP  R0, #0 ; Is the lock free?
ITT     EQ  ; IT instruction for STREXEQ and CMPEQ
STREXEQ R0, R1, [LockAddr] ; Try and claim the lock
CMPEQ  R0, #0 ; Did this succeed?
BNE  try ; No – try again
.... ; Yes – we have the lock.
now change the list save because no other task can acess it.
...
MOV  R1, #0x1
STR  R1, [LockAddr]; now the list is free for other taks to use.

Every task that want to use the list must use the above locking 
mechanism, then there you have exclusive access to the list.

Hope this helps.

von Lasse S. (cowz)


Rate this post
useful
not useful
Thank you for your answer. I did not find the part about the behaviour 
if interrupted.

Why should I limit (and how?) the processes allowance to use 
LDREX/STREX? They don't seem to be able to mess with the system.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.