On Tue, Apr 17, 2012 at 5:02 AM, David Brown <da...@westcontrol.com> wrote:
> 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.

Nothing wrong with brackets in macros.  Mismatched brackets that
require macro pairs, now---that's a Bad Thing(tm).

>
>> 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).

One clarification: you don't need a critical section around a data
access that the mcu *does* atomically.  That it could (even should)
have been atomic, and the compiler didn't make it so, should always be
taken into account.  Trust, but verify.

>> 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.

Interesting thought: I haven't tried to see whether the "critical"
attribute (which is expanded when the function prolog and epilog are
emitted) is preserved if a function is inlined.  Does that actually
work?

Peter

> 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

------------------------------------------------------------------------------
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