[En-Nut-Discussion] NutEnterCritical vs NutEnterCriticalAccess()
Nathan Moore
nategoose at gmail.com
Thu Nov 19 16:39:48 CET 2015
On Thu, Nov 19, 2015 at 6:00 AM, Uwe Bonnes <
bon at elektron.ikp.physik.tu-darmstadt.de> wrote:
>
> can you explain why you use do not use:
>
> #define NutCriticalUpdate( VARIABLE, VALUE) \
> do { \
> size_t sz_ = sizeof(typeof(VARIABLE)); \
> size_t sza_ = sizeof(sig_atomic_t); \
> typeof(VARIABLE) * VP_ = &(VARIABLE); \
> typeof(VALUE) VAL_ = (VALUE); \
> if (sz_ <= sza_ && is_alligned(VP_) { \
> *VP_ = VAL_; \
> } else { \
> NutEnterCritical(); \
> *VP_ = VAL_; \
> NutExitCritical(); \
> } \
> } while (0)
>
> Thanks
>
>
The difference there being that you used <= for the size comparison rather
than ==.
I did not write this particular macro to be the 100% accurate everywhere
but rather
to demonstrate an idea, but I did use == on purpose. The reason for this
is that on
32 bit RISC systems if had the following code:
struct thingy {
uint8_t a;
uint8_t b;
uint16_t c;
};
struct thingy x;
...
x.c = 4;
then, you would likely end up with code like:
load r1 from address of x
and r1, 0x00ff
load r2, 0x0400
or r1,r2
store r1 into address of x
while if you were to do
struct thingy y;
y.a = 0;
y.b = 0;
y.c = 4;
x = y;
you'd end up with something like:
load r1 with constant value 0x0400;
store r1 to address of x
With the assignment of the value that is smaller than the native word size
you end up with several instructions for the operation so an interrupt might
happen that changes the a and/or b members.
Thanks,
Nathan
More information about the En-Nut-Discussion
mailing list