It is always nice to get confirmation, especially from the person that
on the assumption that the compiler does not have bugs there. The later
than the gcc 3 msp430 port. We use them on a couple of projects (we
with the tools.
mostly). But when working with high temperature electronics, the msp430
partial qualification (excluding some peripherals) at 175C. There are
size and power consumption that work at high temperatures. One day, I
specialised projects.
Post by Peter BigotYour colleague is mistaken regarding re-ordering of access to
volatile-qualified objects. David's description is correct and nicely
detailed. In the example a will always be written before b unless the
compiler is broken.
(I should point out that mspgcc in the 3.2.3 era in fact probably *was*
broken with respect to correct ordering of some volatile operations,
because of a hack intended to improve peripheral register access
performance. There were errors in volatile behavior when I started
maintenance that didn't get cleaned up until sometime around August
2011. There's probably traffic in the list archive around that time
that explains the problem.)
MSP430 writes of 16-bit values in any version of mspgcc I released would
be atomic except if they occurred to an object declared with the
"packed" attribute, in which case the byte values would be written
separately to prevent alignment problems. (There were bugs in this
usage too.)
I also use ARM Cortex devices these days, and am very pleased to see
that TI is moving the MSP432 to using CMSIS-Core--compatible peripheral
structure definitions as of March 2016
(http://processors.wiki.ti.com/index.php/MSP432_CMSIS_Update?DCMP=epd-mcu-msp-gen&HQS=MSP432CMSIS).
If the Tiva and CC3K folks were that adaptable I might still use TI chips.
Peter
Thanks very much David.
I already disable interrupts when I need an atomic operation, such
as a write to 32 bit variable or a read-modify-write on a 16bit
variable.
Am I right to assume that simple writes to 16 bit variables are
always atomic on MSP430? Eg done = 0xabcd, the CPU doesn't do two
byte writes or anything dumb like that, the memory will be X (don't
care) before the write and will be 0xabcd after, or should I disable
interrupts for all writes to shared memory (shared with an ISR)?
My colleague asserts that the compiler is even free to reorder
volatile accesses, like
volatile int a;
volatile int b;
int c;
int main()
{
a = 5;
b = 0;
c = 1;
return 0;
}
You are saying that the compiler will always write a before b, even
without a memory barrier. Is that right?
But in the above, the write to c can happen anywhere, as far as I understand.
Lastly, this compiler (3.2.3) is only used on our legacy projects.
More recently we are using the last LTS of mspgcc before Ti/RH
started their port.
I've not seriously tried to use the new RH compiler, and my company
is largely moving away from MSP430 towards ARM Cortex now.
Thanks
- Wayne
Post by David BrownPost by Wayne UrodaHello,
I have a question about instruction reordering in the compiler.
In this blog
http://preshing.com/20120625/memory-ordering-at-compile-time/ It
says
Post by David BrownPost by Wayne Urodathat a compiler barrier should be used where writes to memory must
not be reordered.
Looks like good information.
Post by Wayne UrodaMy MSP430 code is all bare metal, foreground-background code and
I am
Post by David BrownPost by Wayne Urodanot using any type of RTOS, so it could be considered lock-free.
Anyway, a new employee at my work pointed out that the compiler is
free to reorder my memory writes, even those marked volatile. I said
will mspgcc reorder memory writes, eg to global variables? Is this
dependent on the msp430 side of gcc (the backend), or more on the
AST/RTL side?
The compiler can re-order any reads or writes it likes, except
volatile
Post by David Brownaccesses. The order of volatile accesses will always match the
source
Post by David Browncode. But the compiler can move non-volatile reads and writes
back and
Post by David Brownforth between volatile accesses.
So if you have non-volatile variables a, b, c, and volatile
variables u,
Post by David Browna = 1;
u = 100;
b = 2;
v = 200;
c = 3;
a = 1;
c = 3;
u = 100;
v = 200;
b = 2;
a = 1;
v = 200;
b = 2;
u = 100;
c = 3;
(The same applies to reads.)
The volatile accesses must be exact, in the same number and the same
order with respect to other volatile accesses. But the non-volatile
accesses can be moved around as much as the compiler wants.
Note that variable accesses can also be moved around with respect to
function calls, /if/ the compiler knows the function does not make
volatile accesses.
The compiler can also eliminate "dead" stores, or unused reads.
a = 1;
u = 100;
a = 2;
v = 200;
a = 3;
u = 100;
v = 200;
a = 3;
or
a = 3;
u = 100;
v = 100;
Post by Wayne UrodaOr to put it another way, should I be reviewing my shared (between
background and ISR) variables and placing compiler barriers where
variables must be stored in an exact order?
Yes, these must be handled carefully. In particular, volatile
accesses
Post by David Browngive no indication about how non-volatile accesses are handled.
int data[4];
volatile bool newData;
void update(int x) {
data[0] = data[1];
data[1] = data[2];
data[2] = data[3];
data[3] = x;
newData = true;
}
And they think that making the newData flag a volatile is sufficient.
It is /not/ sufficient - the compiler can set newData before doing
anything with the data[] array. And then your interrupt code
will work
Post by David Brownfine in all your testing, and hit a race condition when the
customer is
Post by David Brownwatching.
You have to make each access to "data" here volatile, or you need a
memory barrier between "data[3] = x;" and "newData = true;". A
memory
Post by David Brownbarrier tells the compiler that all memory writes before the barrier
need to be completed, no writes after the barrier may be started, and
any data read before the barrier is now invalid.
And note that even then, nothing in memory barriers or volatile
access
Post by David Brownwill ensure that the reads or writes are atomic.
#define volatileAccess(v) *((volatile typeof((v)) *) &(v))
static inline void compilerBarrier(void) {
asm volatile("" ::: "memory");
}
Post by Wayne UrodaI am using a very old version of mspgcc, 3.2.3, I think it was the
last stable Windows binary release before the CPUX instructions
started making their way in, sorry I don't know the version, from
2008/2009 maybe?
That was probably the final release before the mspgcc 4 project was
started. And now there is a new port msp430-elf from Red Hat and TI,
which is where you should go for moving on for the future.
gcc 3.2.3 did not optimise as aggressively as newer gcc, so it
will do a
Post by David Brownlot less re-arrangement of code. In general, the compiler will
re-arrange the order of writes if it has good reason to do so -
if the
Post by David Brownresult is smaller and/or faster. If it makes no difference, then it
will not re-order the writes.
------------------------------------------------------------------------------
Post by David Brown_______________________________________________
Mspgcc-users mailing list
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
------------------------------------------------------------------------------
_______________________________________________
Mspgcc-users mailing list
https://lists.sourceforge.net/lists/listinfo/mspgcc-users