Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
abcminiuser
PostPosted: Apr 21, 2006 - 01:36 PM
Moderator


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia

NOTE: This article is now obsolete, as the API has been incorporated into the newer versions of avr-libc.

Updated 19/11/06 for new ISR_ALIAS attribute and backwards compatibility
Updated 17/05/07 to fix ISR_ALIASOF definition

Freaks,

Most of you who use GCC are familiar with the method in which interrupt routines (ISRs) are defined and used. Before the latest AVRLibC major update, there existed two ways to declare an interrupt service routine:

Code:
SIGNAL(VectorName)
{
// Code goes here
}

And:
Code:
INTERRUPT(VectorName)
{
// Code goes here
}



While the two methods were easy to differentiate to the seasoned GCC user, these two macro names were a constant source of confusion to those new to the C language - or even just those new to GCC. The difference between the two was subtle, but important.

SIGNAL. This declares an ISR which keeps the global interrupt enable flag inside SREG disabled. It is by far the most commonly needed type of ISR, and sadly the least used by newbies.

INTERRUPT. Exactly the same as SIGNAL, except interrupts are re-enabled at the very start of the ISR code. Most newbies who did not study the AVRLibC manual properly chose this macro because of it's obvious name.


Knowing that this was a great source of confusion - mainly due to the large amount of problems posted in the GCC section of this site - the developers of AVRLibC deprecated both macros and replaced it with a single new one, functionally equivalent to the old SIGNAL macro:

Code:
ISR(VectorName)
{
// Code goes here
}


Note: If you are going to use ISR(VectName) macro it may be worth to update to avr-libc version 1.4.4 due to some bugfixes concerning ISR() incompatibility with gcc 3.4.5.


This new name is more descriptive, and helped significantly. But the problem is now the opposite; newbies don't make mistakes, but seasoned GCC users no longer have an easy way to declare an ISR with the "interrupt" attribute. It's possible to create your own:

Code:
#define INT_ISR(vector)  \
void vector (void) __attribute__((interrupt)); \
void vector (void)


But this solution seems rather hacked-together. It's harder to determine what the difference is between the INT_ISR and plain old ISR. I present my solution to the problem, a header file I made called "ISRMacro.h":

ISRMacro.h
Code:
/* Must be included after avr/interrupt.h. This file re-defines the new
   ISR macro to extend it to allow custom attributes. When the old ISR
   macros SIGNAL and INTERRUPT were depricated, no suitable replacement
   was specifed for interruptable ISR routine (and no macro at all exists
   for naked ISRs). This file avoids the clumsyness of declaring the ISR
   routines manually with custom attributes and thus gives code uniformity.

   As a bonus, the default vector (called when an interrupt fires which does
   not have an associated ISR routine) is aliased here to a more descriptive
   name - use the new name as you would a standard signal name.
   
   The new macro is backwards compatible with the original ISR macro.
   
   The avaliable attributes are:
      1) ISR_BLOCK         - ISR, interrupts disable until ISR completes.
      2) ISR_NOBLOCK       - ISR, interrupts enabled until ISR completes.
      3) ISR_NAKED         - ISR, no prologue or epilogue.
      4) ISR_ALIASOF(vect) - ISR, alias to another interrupt vector's ISR. GCC 4.2+ only.

   For GCC 3.x vector aliases, you can use the ISR_ALIAS_COMPAT macro (instead
   of ISR macro). Works with GCC 3.x as well as GCC 4.x, but compat aliased vector
   ISR will contain a JMP instruction that the non-compat aliased vector does not have.
*/

#ifndef ISRMACRO_H
#define ISRMACRO_H

   // If present, kill the current ISR macro:
   #if defined(ISR)
      #undef ISR
   #endif
   
   // The default vector is given a more descriptive alias here:
   #define BADISR_vect __vector_default
   
   // Return from interrupt command, defined for convenience in ISR_NAKED routines:
   #define reti() asm volatile ("RETI"::)
   
   // Internal macros:
   #define __replace_and_string(name) #name
   
   // Definition of the attributes here, GCC version specific:
   #if defined(__GNUC__) && (__GNUC__ > 3)
      #define ISR_NOBLOCK    __attribute__((interrupt, used, externally_visible))
      #define ISR_BLOCK      __attribute__((signal, used, externally_visible))
      #define ISR_NAKED      __attribute__((signal, naked, used, externally_visible))
      #define ISR_ALIASOF(v) __attribute__((alias(__replace_and_string(v)))) // GCC 4.2 and greater only!
   #else
      #define ISR_NOBLOCK   __attribute__((interrupt))
      #define ISR_BLOCK     __attribute__((signal))
      #define ISR_NAKED     __attribute__((signal, naked))
   #endif

   // GCC 3.x compatible alias macro. Works with GCC 4.1 also:
   #define ISR_ALIAS_COMPAT(vector, aliasof)      \
      void vector (void) ISR_NAKED;               \
      void vector (void) { asm volatile ("jmp " __replace_and_string(aliasof) ::); }

   // New ISR macro definition:
   #define ISR(vector, ...)                       \
      void vector (void) ISR_BLOCK __VA_ARGS__;   \
      void vector (void)
#endif



Instead of creating extra macros, this header file alters the existing one. The new format is:

Code:
ISR(VectorName, Attribute)
{
// Code goes here
}



This leads to nicer-looking and more uniform ISR macros. If you want to create an ISR which blocks other ISRs from running until it has completed (signal attribute), you can use:

Code:
ISR(VectorName, ISR_BLOCK)
{
// Code goes here
}


Or, conversely, an ISR which itself be interrupted can be specified by:

Code:
ISR(VectorName, ISR_NOBLOCK)
{
// Code goes here
}



A third attribute (admittedly not commonly used) is ISR_NAKED, which creates an ISR which has no prologue or epilogue code. I've added it for completeness. Because the ISR_NAKED attribute also specifies that the routine is a signal (despite not having any prologue or epilogue code) the GCC extension to spell-check ISR vector names is still functional.


The final attribute (added 19/11/06) is in preparation for GCC4.2. It allows for the aliasing of one vector to another. An example of aliasing the PCINT0_vect vector to the PCINT1_vect vector:

Code:
ISR(PCINT0_vect, ISR_ALIASOF(PCINT1_vect));


If you are not using GCC 4.2 or greater, you can instead use the compatibility alias macro, which will work in all GCC versions, at the cost of a JMP instruction for the aliased vector:

Code:
ISR_ALIAS_COMPAT(PCINT0_vect, PCINT1_vect);


Finally, when debugging it can be desirable to create an ISR which runs if any vector without an accompanying ISR fires. This is usually done using the "__vector_default" signal name:

Code:
ISR(__vector_default)
{
// Bad interrupt code goes here
}


However the name is clumsy and undescriptive at best. The ISRMacro.h gives an alternate and more descriptive name to this vector, that of BADISR_vect (conforms with the latest ISR naming scheme). With the new name, you can specify a bad-ISR catching ISR which blocks other ISRs from running until it completes via:

Code:
ISR(BADISR_vect, ISR_BLOCK)
{
// Bad interrupt code goes here
}


The new macro is backwards compatible with the old - if no attributes are specified, the ISR will default to ISR_BLOCK, as is the norm without the new macros.


Just another suggestion and tool from a fellow lowly GCC C programmer Smile. Discuss and poke fun at at will.

- Dean Twisted Evil

_________________



Last edited by abcminiuser on Apr 07, 2008 - 12:19 PM; edited 13 times in total
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
smileymicros
PostPosted: Apr 21, 2006 - 02:18 PM
Raving lunatic


Joined: Nov 17, 2004
Posts: 4528
Location: Great Smokey Mountains.

Dean,

Very good work and sure to be helpful.

Thanks,
Smokey

_________________
FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
abcminiuser
PostPosted: Apr 22, 2006 - 02:16 PM
Moderator


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia

Thanks Smokey! I appreciate that this will be viewed as either unnessesary, voodoo or silly by many, but I actually prefer this construct and if it helps someone, then my work isn't wasted. I like sharing and thinking up new ideas!

Speaking of which, wern't you trying to design some new header to help newbies with C? Has anything come from that?

- Dean Twisted Evil

_________________

 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
smileymicros
PostPosted: Apr 22, 2006 - 03:04 PM
Raving lunatic


Joined: Nov 17, 2004
Posts: 4528
Location: Great Smokey Mountains.

Well, yeah, but between the day job and juggling chainsaws, it is going kind of slow.

And this is the way tutorials get OT real quick so I'll just say that I intend to keep you informed and will email you with details as I progress.

Smiley

_________________
FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
skleroz
PostPosted: Apr 23, 2006 - 03:51 PM
Wannabe


Joined: Dec 05, 2004
Posts: 67


Well, may it be worth to mention possible need of avr-libc-1.4.4 to avoid probable pitfalls?
Quote:
*** Changes in avr-libc-1.4.4:
* Bugs fixed:
...
[#15732] interrupt.h: ISR() incompatibility with gcc 3.4.5

http://www.nongnu.org/avr-libc/NEWS.txt
 
 View user's profile Send private message  
Reply with quote Back to top
abcminiuser
PostPosted: Apr 23, 2006 - 10:38 PM
Moderator


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia

skleroz,

How so? My code redefines the ISR macro, and so should work regardless of what ISR is already set to. It shouldn't be affected by any existing ISR macro definition.

- Dean Twisted Evil

_________________

 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
skleroz
PostPosted: Apr 24, 2006 - 04:12 AM
Wannabe


Joined: Dec 05, 2004
Posts: 67


Yes, I see. But if You are explaining (as it seems to me - not for "seasoned GCC users ") how an ISR(VectorName) was born
Quote:
Knowing that this was a great source of confusion - mainly due to the large amount of problems posted in the GCC section of this site - the developers of AVRLibC deprecated both macros and replaced it with a single new one:
Code:
ISR(VectorName)
{
// Code goes here
}

why not to provide some (usefull?) info, helping
Quote:
newbies don't make mistakes

At least before the new WinAVR release is out...
 
 View user's profile Send private message  
Reply with quote Back to top
abcminiuser
PostPosted: Apr 24, 2006 - 06:24 AM
Moderator


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia

I'm still unclear. You want me to explain what the original ISR macro does? Or you think that my solution is a bad one?

I'll be happy to provide an explanation on any of this, just give me a clear rundown on what you're confused about.

- Dean Twisted Evil

_________________

 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
skleroz
PostPosted: Apr 24, 2006 - 02:27 PM
Wannabe


Joined: Dec 05, 2004
Posts: 67


Quote:
You want me to explain what the original ISR macro does? Or you think that my solution is a bad one?

1) No. Your introduction is thorough enough.
2) No. (BTW - which line of my post made You think so?)

You see, this forum even by it's name ("AVR Tutorials") is especially attractive for newbies...
One can even find out about ISR(VectorName) first time from Your post, but not from avr-libc manual (sigh) Sad
So what would go wrong if this part of Your post would be appended with some comment like this (brown)
Quote:
Knowing that this was a great source of confusion - mainly due to the large amount of problems posted in the GCC section of this site - the developers of AVRLibC deprecated both macros and replaced it with a single new one:
Code:
ISR(VectorName)
{
// Code goes here
}
(* If You are going to use ISR(VectName) macro it may be worth to update to avr-libc version 1.4.4 due to some bugfix concerning ISR() incompatibility with gcc 3.4.5)


Seems I need to continue "read-only" mode - my "not native English" does not allow me to communicate in clear way Sad
 
 View user's profile Send private message  
Reply with quote Back to top
abcminiuser
PostPosted: Apr 24, 2006 - 02:31 PM
Moderator


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia

Ahhh! I got you. I've appended the nessesary text to my original post. Sorry for the confusion!

- Dean Twisted Evil

_________________

 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
abcminiuser
PostPosted: May 19, 2006 - 09:24 AM
Moderator


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia

I've just updated the code so that it now supports GCC4.x with the global code compression turned on, a feature which normally ends up in deleted ISRs without the extra attributes.

Thanks to Bernd Trog, who suggested the extra attributes to me in a private email.

- Dean Twisted Evil

_________________

 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: May 19, 2006 - 09:29 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 33138
Location: (using avr-gcc in) Finchingfield, Essex, England

skleroz wrote:
One can even find out about ISR(VectorName) first time from Your post, but not from avr-libc manual (sigh) Sad

Methinks you have an outdated copy of the avr-libc manual then. I just looked at the 1.4.3 PDF and section 5.25 that documents <avr/interrupt.h> tells you all about ISR()

Cliff
 
 View user's profile Send private message  
Reply with quote Back to top
skleroz
PostPosted: May 19, 2006 - 03:33 PM
Wannabe


Joined: Dec 05, 2004
Posts: 67


Cliff, I must quote myself again:
Quote:
Seems I need to continue "read-only" mode - my "not native English" does not allow me to communicate in clear way Sad

In no way I was blaming avrl-libc manual missing ISR() explanation.
All I was thinking about was that at least I know a couple of guys, who are mainly reading AVRFreaks, but (alas Sad ) not the avr-libc manual...
They are completely new to avr'ing, and due to their boyhood are also ignoring forum search (as I can predict Your next question).
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: May 19, 2006 - 05:19 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 33138
Location: (using avr-gcc in) Finchingfield, Essex, England

I know what you mean - about 99.9% of all questions raised on 'Freaks are actually answered by the documentation (either the Datasheets, the Studio help, a copy of Kerningham&Ritchie, sundry other PDFs or a thread search/Google). It's a shame that some folks seem to think it's possible to learn to program without doing a bit of reading.

Cliff
 
 View user's profile Send private message  
Reply with quote Back to top
skleroz
PostPosted: May 20, 2006 - 04:07 AM
Wannabe


Joined: Dec 05, 2004
Posts: 67


It's what they are doing now - a bit of reading...
All I hope is that some day they would realize that they must do a lot of reading, searching and thinking!
 
 View user's profile Send private message  
Reply with quote Back to top
RyanNZ
PostPosted: May 24, 2006 - 03:55 AM
Newbie


Joined: May 10, 2006
Posts: 4


clawson wrote:
I know what you mean - about 99.9% of all questions raised on 'Freaks are actually answered by the documentation (either the Datasheets, the Studio help, a copy of Kerningham&Ritchie, sundry other PDFs or a thread search/Google). It's a shame that some folks seem to think it's possible to learn to program without doing a bit of reading.

Cliff


hahahah classic who here ever thought reading would come in handy though really......
 
 View user's profile Send private message  
Reply with quote Back to top
abcminiuser
PostPosted: Nov 18, 2006 - 02:36 PM
Moderator


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia

Just updated this. I've added in the ISR_ALIAS attribute which will be available in GCC4.2. That will make it easier to alias the ISR code for one or more vectors to another vector's code.

Also added in some voodoo to allow for backwards compatibility. You can now use your existing code without changes without compile errors. This relies on the fact that the INTERRUPT attribute augments the SIGNAL attribute without being clobbered.

- Dean Twisted Evil

_________________

 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits