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
yggdrasil
PostPosted: Jun 24, 2011 - 02:37 PM
Newbie


Joined: Nov 12, 2010
Posts: 4


In my application I must join all the interrupt in a function, but I must know which interrupt
Use AVR is taken part Study 4 with language C AVR-GCC
Use ATMEGA88PA

Thanks for every answer

Quote:

table interupt vector:
0x000 jump --> main
0x001 jump --> ISR(INT0)
0x002 jump --> ISR(INT1)
0x003 jump --> interrupt3
0x004 jump --> interrupt4
0x005 jump --> interrupt5
0x006 jump --> interrupt6
0x007 jump --> interrupt7
0x008 jump --> interrupt8
0x009 jump --> interrupt9
0x00A jump --> interruptA
0x00B jump --> interruptB
0x00C jump --> interruptC
0x00D jump --> interruptD
0x00E jump --> interruptE
0x00F jump --> interruptF
0x010 jump --> interrupt10
0x011 jump --> interrupt11
0x012 jump --> interrupt12
0x013 jump --> interrupt13
0x014 jump --> interrupt14
0x015 jump --> interrupt15
0x016 jump --> interrupt16

//interrupt used
ISR(INT0){
.......
......
}

// interrupt fault CPU
ISR(INT1){
char x;
x=0x1;
goto int_main;
interrupt1:
x=0x2;
goto int_main;
interrupt2:
x=0x3;
goto int_main;
interrupt3:
x=0x4;
goto int_main;
interrupt4:
x=0x5;
goto int_main;
......
.......
......
.......
interrupt14:
x=0x14;
int_main:
while(1){
PORTB=x; //send number interrupt to Display
}
}
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Jun 24, 2011 - 02:57 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18545
Location: Lund, Sweden

Quote:

In my application I must join all the interrupt in a function

Us old farts here at 'freaks are always suspicious when we see those "I must..." statements. Before we start tsuggesting things that might end up not fitting your actual bill, and thus be a waste of time for all of us, please tell us why you "must" do this.

If you take a step back and tell us what the "original problem" is then we might have very good suggestions that do not include that "must". Very Happy

Apart from that, your code sketch is a step on the way, but still not quite good. I'd sketch something like this:

Code:
// No AVR has 255 interrupts so we use this value
// to denote "no interrupt"
volatile unsigned char interrupt = 255;

// Establish ISRs for every interrupt you want to see. Make each of them
// report a unique number in the global variable. One ISR looking roughly
// like this for each interrupt source:
ISR( <some_interrupt_vector> )
{
   interrupt = 7;    // A unique number denoting a specific interrupt source
}

int main(void)
{
   // Enable all your wanted interrupts here...
   .
   .
   .

   // now, sit in a loop and wait for them to be reported...
   while (1)
   {
      if (interrupt != 255)
      {
         PORTB = interrupt;
         interrupt = 255;
      }
   }

   return 0;
}
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Jun 24, 2011 - 03:08 PM
10k+ Postman


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

Is this about catching unhandled interrupts or something? I can think of no other reason to have them all vector to a single function. If it is about this do you know about BADISR_vect as detailed in the user manual?:

http://www.nongnu.org/avr-libc/user-man ... rupts.html

It's a shame it's an m88 with RJMP sized vectors. In a 168 where the vectors are wide enough for JMP you could actually use:
Code:
LDI R24, n
RJMP common_handler

where n increments for each vector and when you reach common_handler: you can use R24 to determine which vector it was.

_________________


Last edited by clawson on Jun 24, 2011 - 03:53 PM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Jun 24, 2011 - 03:43 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18545
Location: Lund, Sweden

Quote:

Is this about catching unhandled interrupts or something?

I'll give the OP 24 hrs, and if quiet then I'll assume it was a school assignment and that I just pushed him a substantial distance towards getting the grade..
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
yggdrasil
PostPosted: Jun 25, 2011 - 12:17 AM
Newbie


Joined: Nov 12, 2010
Posts: 4


JohanEkdahl, thanks but not what I wanted to have

clawson wrote:
Is this about catching unhandled interrupts or something? I can think of no other reason to have them all vector to a single function.

you're right, I want to group all interrupts not used in my program in a single function, but I want to know what interrupt has occurred
I am interested in minimizing the program
The interrupt function should not return to the main function

clawson wrote:

If it is about this do you know about BADISR_vect as detailed in the user manual?

I do not think is the right way

example of assembly code
PROBLEM --> how can I convert it to C

Code:

.include "m88def.inc" 
.device ATMEGA88

  .org 0
  rjmp  main
  rjmp  Int_vect0
  rjmp  Int_vect1
  rjmp  Int_vect2
  rjmp  Int_vect3
  rjmp  Int_vect4
  rjmp  Int_vect5
  rjmp  Int_vect6
  rjmp  Int_vect7
  rjmp  Int_vect8
  rjmp  Int_vect9
  rjmp  Int_vect10
  rjmp  Int_vect11
  rjmp  Int_vect12
  rjmp  Int_vect13
  rjmp  Int_vect14
  rjmp  Int_vect15
  rjmp  Int_vect16
  rjmp  Int_vect17
  rjmp  Int_vect18
  rjmp  Int_vect19
  rjmp  Int_vect20
  rjmp  Int_vect21
  rjmp  Int_vect22
  rjmp  Int_vect23
  rjmp  Int_vect24

Int_vect0:
   ldi r24,0x01
   rjmp  GlobalInt
Int_vect1:
   ldi r24,0x02
   rjmp  GlobalInt
Int_vect2:
   ldi r24,0x03
   rjmp  GlobalInt
Int_vect3:
   ldi r24,0x04
   rjmp  GlobalInt
Int_vect4:
   ldi r24,0x05
   rjmp  GlobalInt
Int_vect5:
   ldi r24,0x06
   rjmp  GlobalInt
Int_vect6:
   ldi r24,0x07
   rjmp  GlobalInt
Int_vect7:
   ldi r24,0x08
   rjmp  GlobalInt
Int_vect8:
   ldi r24,0x09
   rjmp  GlobalInt
Int_vect9:
   ldi r24,0x0A
   rjmp  GlobalInt
Int_vect10:
   ldi r24,0x0B
   rjmp  GlobalInt
Int_vect11:
   ldi r24,0x0C
   rjmp  GlobalInt
Int_vect12:
   ldi r24,0x0D
   rjmp  GlobalInt
Int_vect13:
   ldi r24,0x0E
   rjmp  GlobalInt
Int_vect14:
   ldi r24,0x0F
   rjmp  GlobalInt
Int_vect15:
   ldi r24,0x10
   rjmp  GlobalInt
Int_vect16:
   ldi r24,0x11
   rjmp  GlobalInt
Int_vect17:
   ldi r24,0x12
   rjmp  GlobalInt
Int_vect18:
   ldi r24,0x13
   rjmp  GlobalInt
Int_vect19:
   ldi r24,0x14
   rjmp  GlobalInt
Int_vect20:
   ldi r24,0x15
   rjmp  GlobalInt
Int_vect21:
   ldi r24,0x16
   rjmp  GlobalInt
Int_vect22:
   ldi r24,0x17
   rjmp  GlobalInt
Int_vect23:
   ldi r24,0x18
   rjmp  GlobalInt
Int_vect24:
   ldi r24,0x19
GlobalInt:
   ldi   r17,0xFF
   out   DDRB,r17
   out   PORTB,r24
Loop:
   rjmp   Loop


main:
   rjmp   main


Thanks to all
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Jun 25, 2011 - 09:20 AM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18545
Location: Lund, Sweden

So, what you need is a lump of C code that translates to that assembler code? Exactly? That will be hard, or even impossible..

What is forcing you to want this exact solution?
Why does it need to be exactly this?

As I see it, implementing something in C that generating roughly that machine code will involve some elaborate "goto-programming". While goto's aren't taboo in C, my opinion is that they should be the last resort when no other "elegant C solution" is possible.

And as I hinted at, the compiler can generate any machine code it wants from the C code as long as the semantics are preserved. Thus, looking for a lump of C code that will generate a specific sequence of assembler is in general a futile.

It does not get easier taking into account that you want see only one interrupt (apart from the reset interrupt).

If you want control over the code on this level - stick with assembler.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
yggdrasil
PostPosted: Jun 25, 2011 - 03:03 PM
Newbie


Joined: Nov 12, 2010
Posts: 4


sorry if my translation is not good Laughing
JohanEkdahl wrote:
So, what you need is a lump of C code that translates to that assembler code? Exactly?

is something like Wink

The application is too complex to explain all, it's much more logic gates in a circuit that makes a big mill industry.
The malfunctioning of the microcontroller may cause damage to property or persons.
Unfortunately, I don't succeed in making to understand me from the compiler, the compiler continues to put a lot of assembler code to do simple things. Confused

JohanEkdahl wrote:

What is forcing you to want this exact solution?
Why does it need to be exactly this?

The CPU enters the interrupt when is on tilt or fault .... I do not want to use the Stack could be compromised because, in the interrupt do not want to use the command pop/push/call/rcall/iCall/ret/reti and I was looking for a solution in c language

JohanEkdahl wrote:

As I see it, implementing something in C that generating roughly that machine code will involve some elaborate "goto-programming". While goto's aren't taboo in C, my opinion is that they should be the last resort when no other "elegant C solution" is possible.

I also think that the "goto" is bad to use, but I do not like what the compiler creates leaving him do what he wants

JohanEkdahl wrote:

If you want control over the code on this level - stick with assembler.

If I have to rebuild the entire program in assembly language. Would be many weeks of work

I can put the interrupts in code assembler in the program C ??? Question
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Jun 25, 2011 - 03:21 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18545
Location: Lund, Sweden

Quote:

I can put the interrupts in code assembler in the program C ???

Yes.

(You are programming on something that can potentially kill a human being if it fails? And this is your level of knowledge? Please tell me that this thing is something I will never have to come close to...)

Since avr-gcc is open-source you can fiddle with anything. Some things are easier. Other things are harder. Here, it might be that you will have to rewrite/replace a piece of the source code in avrlibc. Or you might get away with writing some assembler with .org directives. And it has to be assembler that is accepted by the GNU Assembler (AVR Assembler will not do) since you want to link it to your avr-gcc application.

Anyhow, I still don't get it. Your code implies that you do not want anything else than halting the program by going into a tight loop as soon as an interrupt occurs. Why, then enable those interrupts at all?

And, if this is actually a way to guard against interrupts that are enabled but that lacks an established ISR, then there are "standard" ways to handle that.

The argument that you do not want to use the stack because it might be compromised is doubly moot since

1. At the generation of the interrupt condition, hardware in the AVR will use the AVR to push the return address. Since it is hardware, you can not alter this.
2. Since you just want to report the interrupt source and then hang the program in an eternal loop you will never use anything on that potentially compromised stack.

[I'm more or less rhetorical now. It seems we have to pull out facts from you with pliers, and we're also potentially going into "moving-target-mode". Both are tell-tale indicators that people will walk away from helping you.]
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
yggdrasil
PostPosted: Jun 25, 2011 - 04:15 PM
Newbie


Joined: Nov 12, 2010
Posts: 4


JohanEkdahl wrote:

(You are programming on something that can potentially kill a human being if it fails? And this is your level of knowledge? Please tell me that this thing is something I will never have to come close to...)

I always work to the best to get safety Very Happy

JohanEkdahl wrote:

Anyhow, I still don't get it. Your code implies that you do not want anything else than halting the program by going into a tight loop as soon as an interrupt occurs. Why, then enable those interrupts at all?

that interrupts don't serve me, I didn't want to leave I hung them

JohanEkdahl wrote:

1. At the generation of the interrupt condition, hardware in the AVR will use the AVR to push the return address. Since it is hardware, you can not alter this.

you are right but I would be able not to read the stack
JohanEkdahl wrote:

2. Since you just want to report the interrupt source and then hang the program in an eternal loop you will never use anything on that potentially compromised stack.

even if in an endless cycle it is guaranteed the signal of stop machine "out PORTB,r24"
in the industrial machineries it owes the stop to be guaranteed
JohanEkdahl wrote:

[I'm more or less rhetorical now. It seems we have to pull out facts from you with pliers, and we're also potentially going into "moving-target-mode". Both are tell-tale indicators that people will walk away from helping you.]

thanks you have been of great help
I will look for some example among the projects in your forum Very Happy
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jun 27, 2011 - 10:09 AM
10k+ Postman


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

Quote:

PROBLEM --> how can I convert it to C

Something like this maybe:
Code:
/* External Interrupt Request 0 */
ISR( INT0_vect         ) { common_handler(1); }
/* External Interrupt Request 1 */
ISR( INT1_vect         ) { common_handler(2); }
/* Pin Change Interrupt Request 0 */
ISR( PCINT0_vect         ) { common_handler(3); }
/* Pin Change Interrupt Request 0 */
ISR( PCINT1_vect         ) { common_handler(4); }
/* Pin Change Interrupt Request 1 */
ISR( PCINT2_vect         ) { common_handler(5); }
/* Watchdog Time-out Interrupt */
ISR( WDT_vect         ) { common_handler(6); }
/* Timer/Counter2 Compare Match A */
ISR( TIMER2_COMPA_vect      ) { common_handler(7); }
/* Timer/Counter2 Compare Match A */
ISR( TIMER2_COMPB_vect      ) { common_handler(8); }
/* Timer/Counter2 Overflow */
ISR( TIMER2_OVF_vect         ) { common_handler(9); }
/* Timer/Counter1 Capture Event */
ISR( TIMER1_CAPT_vect      ) { common_handler(10); }
/* Timer/Counter1 Compare Match A */
ISR( TIMER1_COMPA_vect      ) { common_handler(11); }
/* Timer/Counter1 Compare Match B */
ISR( TIMER1_COMPB_vect      ) { common_handler(12); }
/* Timer/Counter1 Overflow */
ISR( TIMER1_OVF_vect         ) { common_handler(13); }
/* TimerCounter0 Compare Match A */
ISR( TIMER0_COMPA_vect      ) { common_handler(14); }
/* TimerCounter0 Compare Match B */
ISR( TIMER0_COMPB_vect      ) { common_handler(15); }
/* Timer/Couner0 Overflow */
ISR( TIMER0_OVF_vect         ) { common_handler(16); }
/* SPI Serial Transfer Complete */
ISR( SPI_STC_vect         ) { common_handler(17); }
/* USART Rx Complete */
ISR( USART_RX_vect         ) { common_handler(18); }
/* USART, Data Register Empty */
ISR( USART_UDRE_vect         ) { common_handler(19); }
/* USART Tx Complete */
ISR( USART_TX_vect         ) { common_handler(20); }
/* ADC Conversion Complete */
ISR( ADC_vect         ) { common_handler(21); }
/* EEPROM Ready */
ISR( EE_READY_vect         ) { common_handler(22); }
/* Analog Comparator */
ISR( ANALOG_COMP_vect      ) { common_handler(23); }
/* Two-wire Serial Interface */
ISR( TWI_vect         ) { common_handler(24); }
/* Store Program Memory Read */
ISR( SPM_READY_vect         ) { common_handler(25); }

I'll leave you to fill in the blanks.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Jun 27, 2011 - 10:32 AM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18545
Location: Lund, Sweden

Cliff! The calls to common_handler() will do pushes and stuff. As I understand 'yggdrasil' this is not what he wants..
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Jun 27, 2011 - 10:48 AM
10k+ Postman


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

What does it matter? He's only trying to determine why a none planned interrupt has occurred. If that really happens then surely it's game over anyway? Also, if common_handler() is small and included in the same file as these ISR() definitions there should be very little push/pop overhead. In the limit use an attribute to force it always inline (all 25 copies!)

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Jun 27, 2011 - 11:39 AM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18545
Location: Lund, Sweden

Quote:

What does it matter? He's only trying to determine why a none planned interrupt has occurred. If that really happens then surely it's game over anyway?

Yes, agree. But then he could have been content with my initial suggestion (with a small change). He wasn't, arguing stack stuff etc.
 
 View user's profile Send private message 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