On 17/04/2012 09:53, Wayne Uroda wrote:
> Hi,
>
> I feel quite foolish asking the following question... Please don't judge me 
> too harshly...
>
> In my MSPGCC based system I have got the following #defines which I use for 
> critical (interrupts disabled) access around volatile memory which is 
> modified by interrupt routines:
>
> #define criticalStart() __asm__ __volatile__("push r2"::); __asm__ 
> __volatile__("dint"::)
> #define criticalEnd() __asm__ __volatile__("pop r2"::)
>

/Never/ mess with the stack inside a C function.  You are asking for 
trouble.  Simply save the old SR in a local variable (as you do in the 
new versions below).

> Usually I use this code to write to a counter which is decremented by my 
> timer ISR, eg
>
> void setTimeout(UInt16 timeout)
> {
>      // Other work before setting the volatile, ISR driven value
>      criticalStart();
>      busyTimeout = timeout;
>      criticalEnd();
> }

Of course, it is pointless disabling interrupts here.  The msp430 does 
the 16-bit write as an atomic operation anyway.  If there is only one 
instruction, it cannot be interrupted.  You only need the critical 
section if you are trying to do a 32-bit write.

>
> Today I am using Code composer for a new project and I tried a similar trick. 
> After several hours of debugging, it turns out that my little "push r2" trick 
> causes code composer to access local variables incorrectly, since these are 
> accessed relative to the stack pointer.
>
> For example, the following code does not function correctly because the 
> "localTimer" variable is not written correctly (the memory access is one word 
> off owing to the extra stack push).
>
> while(true)
> {
>      UInt32 localTimer;
>      criticalStart();
>      localTimer = globalTimer;
>      criticalEnd();
>      if (localTimer == 0)
>      {
>          break;
>      }
> }
>
>
> My question is, does GCC analyse the inline assembly code and notice that I 
> have altered the stack, or have I just been *extremely* lucky for many years? 
> Certainly code composer does not see that I have modified the stack.

You've just been lucky.

>
> I am going to change my critical macros like so (this is how I am now doing 
> critical access in code composer, which, unless I am missing something, has 
> no builtin way to do critical functions):
>
> #define criticalStart() { UInt16 __oldInterruptStatus__ = READ_SR(); __asm__ 
> __volatile__("dint"::)
> #define criticalEnd() WRITE_SR(__oldInterruptStatus__); }
>

That should work.  Like many people (and all serious coding standards), 
I don't like putting brackets in macros - but that's your choice.

> Any major issues with doing this? Should I instead wrap all reads and writes 
> to volatile memory/variables with critical functions? I usually only wrap one 
> line of code with the critical macros.
>

You would be better off learning what critical sections actually /are/, 
and when you need them, rather than wasting time, effort, code space and 
run time when they are not necessary.  As a very general indication, you 
need interrupt disabling like this if you have code that needs atomic 
access to several parts of a complex memory structure, and the code 
could be interrupted by other code that also then accesses the same 
structure.

In particular, you don't need them within interrupt functions (or other 
places with interrupts disabled), and you don't need them to access data 
that the cpu can access atomically (like 8-bit and 16-bit data).

> Also if anybody knows code composer v3.1 and knows a better way, please let 
> me know.
> Thanks,
>

With gcc for the msp430, there is also a "critical" function attribute - 
you can put your critical accesses within a small static inline 
"critical" function.

With Code Composter 3.1, the best option is to throw away the tools and 
use something else.  The toolchain has major problems, and you need to 
work hard to get around them.  At the very least, use CCS 5, as it has a 
much better IDE.  But the toolchain still has the critical failing that 
it doesn't zero out uninitialised statically allocated data, and it has 
the most appalling choices you could imagine of which issues are 
warnings, errors, or ignored.  It will give errors or warnings on 
perfectly good code, while accepting total crap without question.



------------------------------------------------------------------------------
Better than sec? Nothing is better than sec when it comes to
monitoring Big Data applications. Try Boundary one-second 
resolution app monitoring today. Free.
http://p.sf.net/sfu/Boundary-dev2dev
_______________________________________________
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users

Reply via email to