On Tue, Apr 17, 2012 at 9:03 AM, David Brown <da...@westcontrol.com> wrote:
> On 17/04/2012 13:44, Peter Bigot wrote:
>>
>> 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).
>
>
> That's what I meant, though it's not what I wrote - it is /mismatched/
> brackets that are the problem.  Sometimes they sound like a good idea, such
> as in this case, but they are always a bit risky.
>
>
>>
>>>
>>>> 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.
>
>
> Good point.
>
> You have to be particularly careful about read-modify-write codings. The
> msp430 can do some of these actions atomically, but it is possible that the
> compiler will split the actions up.  For example, if you write "a += 1; b =
> a" then then compiler might read "a" into a register, do the addition, then
> save the value to "a" as three separate actions, so that it can re-use the
> saved value for "b".
>
>
>>
>>>> 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?
>>
>
> As far as I remember, it works fine.  However, I haven't actually used
> mspgcc much for the last few years, and the projects using it are all on an
> older gcc 3.x version - I can't comment about current versions.  And most of
> my uses of "critical" functions were not declared inline - but as single-use
> static functions, I expect that some of them were inlined.
>
> Would it ever be possible to get the "critical" attribute pushed into
> mainline gcc?  I'm sure other ports would benefit from the same idea (with
> the avr port being the obvious example).  It always struck me as silly that
> all the different ports for gcc define their own attributes for things like
> interrupt functions or critical functions, rather than combining them.

I doubt it would ever get taken up officially; the implementation and
interface is always in the target-specific code.  The good back ends
try to see how the other ones did it and stay as consistent as
possible.

Peter

> mvh.,
>
> David
>
>
>
>
>> 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

Reply via email to