EmbeddedRelated.com
Forums

CrossWorks inline and interrutps...

Started by Tim Wade March 17, 2004
Hi

I have read the manual and I cannot see how to do two things with
CrossWorks for the MSP430.

1. inline assembler; I have tried the usual asm("nop") but to no avail

2. interrupt functions; again I cannot seem to be able to get this to
work ~ the documentation actually has an example for the ARM! (the
syntax is different, it dosen't work)

I am sure there must be some way of doing this... if there is anybody
out there who has got these things to work and could let me know it
would be much appreciated!

Thanks
Tim
--
This email is confidential and intended solely for the use of the individual to
whom it is addressed.  
Any views or opinions presented are solely those of the author and do not
necessarily represent those of NAUTRONIX LTD.

If you are not the intended recipient, you have received this email in error and
use, dissemination, forwarding, printing, or copying of 
this email is strictly prohibited.  If you have received this email in error
please contact the sender.   

Although our computer systems use active virus protection software, and we take
various measures to reduce the risk of viruses 
being transmitted in e-mail messages and attachments sent from this company, we
cannot guarantee that such e-mail messages 
and attachments are free from viruses on receipt.  It is a condition of our
using e-mail to correspond with you, that any and all liability 
on our part arising directly or indirectly out of any virus is excluded.  Please
ensure that you run virus checking software on all e-mail 
messages and attachments before reading them.


Beginning Microcontrollers with the MSP430

Hi Tim,

> 1. inline assembler; I have tried the usual
asm("nop") but to no avail

I don't know about inline ASM, normally I use separate ASM modules.
 
> 2. interrupt functions; again I cannot seem to be
able to get this to
> work ~ the documentation actually has an example for the ARM! (the
> syntax is different, it dosen't work)

Syntax is as follows :

(static) void int_name (void) __interrupt [XYZ_VECTOR]
{
/ * Interrupt code  */
}

You can leave static in if you want the scope to be only within the module,
which of course
you do, unless some funky code mimics an interrupt and then wants to call your
INT code from
somewhere else.

XYZ_VECTOR is the proper vector eg.
TIMERA0_VECTOR, TIMERB0_VECTOR etc etc.

B regards,
Kris





BTW, 

if you go to : Tutorial -> MSP430 Samples -> .... in that pretty HTML
help,
there are stacks and stacks of example projects where you can see the syntax for
Interrupt handlers.
I think you might have hit ARM examples because the context sensitive help took
you to the
CTL (CrossWorks Tasking Library), actually a ___fast__ and really nice RTOS !!!

Actually, people have asked about small RTOSs many times here.
If anyone is interested, I can post some typical timing test results I got with
RAL CTL
wrt event response from INTs, rescheduling etc etc.

-- Kris





Thanks for your help! I got it all going. I was porting a slab of code
from GCC to CrossWorks. 

> if you go to : Tutorial -> MSP430 Samples ->
.... in that 
> pretty HTML help, there are stacks and stacks of example 
> projects where you can see the syntax for Interrupt handlers. 
> I think you might have hit ARM examples because the context 
> sensitive help took you to the CTL (CrossWorks Tasking 
> Library), actually a ___fast__ and really nice RTOS !!!

Yes; it is a little confusing as I still haven't found any explanation
about interrupts in the IDE help files... Or in-line assembler! I ended
up reorganizing the code to remove the two small inline bits of code...

One last question wrt to the __interrupt. On GCC we use the 'wakeup'
flag on the interrupt service routine. Do Rowley have anything similar?
 
> Actually, people have asked about small RTOSs many
times 
> here. If anyone is interested, I can post some typical timing 
> test results I got with RAL CTL wrt event response from INTs, 
> rescheduling etc etc.

If looks really interesting. When I find a spare 10 minutes I will have
a try.

Cheers
Tim
--
This email is confidential and intended solely for the use of the individual to
whom it is addressed.  
Any views or opinions presented are solely those of the author and do not
necessarily represent those of NAUTRONIX LTD.

If you are not the intended recipient, you have received this email in error and
use, dissemination, forwarding, printing, or copying of 
this email is strictly prohibited.  If you have received this email in error
please contact the sender.   

Although our computer systems use active virus protection software, and we take
various measures to reduce the risk of viruses 
being transmitted in e-mail messages and attachments sent from this company, we
cannot guarantee that such e-mail messages 
and attachments are free from viruses on receipt.  It is a condition of our
using e-mail to correspond with you, that any and all liability 
on our part arising directly or indirectly out of any virus is excluded.  Please
ensure that you run virus checking software on all e-mail 
messages and attachments before reading them.


Hi Tim,

> One last question wrt to the __interrupt. On GCC
we use the 'wakeup'
> flag on the interrupt service routine. Do Rowley have anything similar?

I'm not familiar with GCC. I think Paul wil have to answer that.

-- Kris


Hi Tim, Kris,

> > One last question wrt to the __interrupt. On
GCC we use the 
> 'wakeup' 
> > flag on the interrupt service routine. Do Rowley have anything 
> > similar?
> 
> I'm not familiar with GCC. I think Paul wil have to answer that.

I think you'll find the wakeup takes the CPU out of LPM on the RETI and
makes it go into active mode.  Thus, one of the LPMx_EXIT macros is
probably what you're wanting in the ISR.  Take a look at the contents of
<msp430x14x.h> and in the online help for _BIS_SR_IRQ and _BIC_SR_IRQ.

There are plenty of examples in the "samples" directory or, as Kris
points out, use the HTML-based help system and open up the samples
directly from inside the help system.

Regards,

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for MSP430, ARM, and (soon) Atmel AVR processors 

Tim,

> Thanks for your help! I got it all going. I was
porting a 
> slab of code from GCC to CrossWorks. 
> 
> > if you go to : Tutorial -> MSP430 Samples -> .... in that
> > pretty HTML help, there are stacks and stacks of example 
> > projects where you can see the syntax for Interrupt handlers. 
> > I think you might have hit ARM examples because the context 
> > sensitive help took you to the CTL (CrossWorks Tasking 
> > Library), actually a ___fast__ and really nice RTOS !!!
> 
> Yes; it is a little confusing as I still haven't found any 
> explanation about interrupts in the IDE help files... Or 
> in-line assembler! I ended up reorganizing the code to remove 
> the two small inline bits of code...

We don't support inline assembler other than by using _OPC.  I'm not
sure why people love inline assembler when we have a bunch of intrinsic
functions that do away with the need for it.  (I hope--but if you know
different, just drop me a line...)

> One last question wrt to the __interrupt. On GCC
we use the 
> 'wakeup' flag on the interrupt service routine. Do Rowley 
> have anything similar?

I think you'll find the wakeup takes the CPU out of LPM on the RETI and
makes it go into active mode.  Thus, one of the LPMx_EXIT macros is
probably what you're wanting in the ISR.  Take a look at the contents of
<msp430x14x.h> and in the online help for _BIS_SR_IRQ and _BIC_SR_IRQ.

There are plenty of examples in the "samples" directory or, as Kris
points out, use the HTML-based help system and open up the samples
directly from inside the help system and start exploring.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for MSP430, ARM, and (soon) Atmel AVR processors 

On Thu, 18 Mar 2004 09:42:12 -0000, Paul Curtis wrote:

<snip>

>We don't support inline assembler other than
by using _OPC.  I'm not
>sure why people love inline assembler when we have a bunch of intrinsic
>functions that do away with the need for it.  (I hope--but if you know
>different, just drop me a line...)


<snip>

Paul
  I'll jump in on that one.  A recent MSP project was to create a
replacement California FasTrac (auto toll) tag.  The ASIC originally
used had gone end-of-life and our customer was still selling almost
1/4 million tags per year.  Part of the requirements was the reception
of a 300Kbps Manchester encoded message from the toll-booth.  And we
found later in the project, the data rate could vary from booth to
booth by a little over 1%.  The code to synchronize to and decode the
data stream was written in assembly, however the code that called it
and the code that used the results was written in C.  The abiltiy to
have in-line assembly code which has access to C level data by name is
a great benefit.  The assembly code in our case stored code in an
array of uint8_t that was part of a union which allowed the C code to
later parse the download packet.  It also updated the count field in
the struct which held the union.

  In another part of that same project had the need to very quickly
swap the two bytes of a 16-bit word.  Yes, it would have been possible
to either create an in-line C function or an assembly level routine to
do it.  However, the C level function was bigger and slower, and the
assembly language suffered from the overhead of the call/return.
An in-line function containing only in-line assembly was ideal.

Regards
-Bill Knight
R O SoftWare



Bill,

> <snip>
> 
> >We don't support inline assembler other than by using _OPC. 
I'm not 
> >sure why people love inline assembler when we have a bunch 
> of intrinsic 
> >functions that do away with the need for it.  (I hope--but 
> if you know 
> >different, just drop me a line...)
> 
> 
> <snip>
> 
> Paul
>   I'll jump in on that one.  A recent MSP project was to 
> create a replacement California FasTrac (auto toll) tag.  The 
> ASIC originally used had gone end-of-life and our customer 
> was still selling almost 1/4 million tags per year.  Part of 
> the requirements was the reception of a 300Kbps Manchester 
> encoded message from the toll-booth.  And we found later in 
> the project, the data rate could vary from booth to booth by 
> a little over 1%.  The code to synchronize to and decode the 
> data stream was written in assembly, however the code that 
> called it and the code that used the results was written in 
> C.  The abiltiy to have in-line assembly code which has 
> access to C level data by name is a great benefit.  The 
> assembly code in our case stored code in an array of uint8_t 
> that was part of a union which allowed the C code to later 
> parse the download packet.  It also updated the count field 
> in the struct which held the union.

I don't see why it can't just be an assembly module that C has access
to.  It's simple to do, to publicise an address in code that's right
in
the middle of an assembly insert, or to move code form flash to RAM for
execution.

So, how did you manage the registers in use when you coded inline?  Did
you need to save them and restore them in the assembly code sequence?

Again, I fail to see why you need a huge amount of in-line assembly
code.  You can easily modify C variables from assembly, just as you can
modify assembly variables from C.

>   In another part of that same project had the
need to very 
> quickly swap the two bytes of a 16-bit word.  Yes, it would 
> have been possible to either create an in-line C function or 
> an assembly level routine to do it.  However, the C level 
> function was bigger and slower, and the assembly language 
> suffered from the overhead of the call/return. An in-line 
> function containing only in-line assembly was ideal.

What's wrong with _SWPB in every MSP430 compiler?  It's inline, comes
in
the package, and is documented in our compiler, and it's efficient.
Same for every other byte/word swapping function in our compiler.  No
need for inline code or assembler, so again, I fail to see why inline
assembly code is the answer?

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for MSP430, ARM, and (soon) Atmel AVR processors 

On Thu, 18 Mar 2004 13:33:53 -0000, Paul Curtis wrote:

>Bill,

>> <snip>
>> 
>> >We don't support inline assembler other than by using _OPC. 
I'm not 
>> >sure why people love inline assembler when we have a bunch 
>> of intrinsic 
>> >functions that do away with the need for it.  (I hope--but 
>> if you know 
>> >different, just drop me a line...)
>> 
>> 
>> <snip>
>> 
>> Paul
>>   I'll jump in on that one.  A recent MSP project was to 
>> create a replacement California FasTrac (auto toll) tag.  The 
>> ASIC originally used had gone end-of-life and our customer 
>> was still selling almost 1/4 million tags per year.  Part of 
>> the requirements was the reception of a 300Kbps Manchester 
>> encoded message from the toll-booth.  And we found later in 
>> the project, the data rate could vary from booth to booth by 
>> a little over 1%.  The code to synchronize to and decode the 
>> data stream was written in assembly, however the code that 
>> called it and the code that used the results was written in 
>> C.  The abiltiy to have in-line assembly code which has 
>> access to C level data by name is a great benefit.  The 
>> assembly code in our case stored code in an array of uint8_t 
>> that was part of a union which allowed the C code to later 
>> parse the download packet.  It also updated the count field 
>> in the struct which held the union.

>I don't see why it can't just be an
assembly module that C has access
>to.  It's simple to do, to publicise an address in code that's
right in
>the middle of an assembly insert, or to move code form flash to RAM for
>execution.

>So, how did you manage the registers in use when
you coded inline?  Did
>you need to save them and restore them in the assembly code sequence?

>Again, I fail to see why you need a huge amount of
in-line assembly
>code.  You can easily modify C variables from assembly, just as you can
>modify assembly variables from C.

>>   In another part of that same project had the
need to very 
>> quickly swap the two bytes of a 16-bit word.  Yes, it would 
>> have been possible to either create an in-line C function or 
>> an assembly level routine to do it.  However, the C level 
>> function was bigger and slower, and the assembly language 
>> suffered from the overhead of the call/return. An in-line 
>> function containing only in-line assembly was ideal.

>What's wrong with _SWPB in every MSP430
compiler?  It's inline, comes in
>the package, and is documented in our compiler, and it's efficient.
>Same for every other byte/word swapping function in our compiler.  No
>need for inline code or assembler, so again, I fail to see why inline
>assembly code is the answer?


Last things first.  At the time the project was underway, IAR 1.2x was
the only comercial compiler available.  It did not have _SWPB.

The code that synchronized to, decoded, and saved the downlink data
stream did so in 12 cycles per Manchester bit cell.  Even in assembly
it is a very tightly interwoven piece of code.  And yes, it saved all
used registers upon entry and restored them at exit.  And yes, it is
possible to pass addresses and data into assembly routines.  It is
also nice to be able to reference them by name, without additional
declarations, while having to code in assembly.

-Bill