| Author |
Message |
|
|
Posted: Jun 24, 2011 - 02:37 PM |
|

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
}
}
|
|
|
| |
|
|
|
|
|
Posted: Jun 24, 2011 - 02:57 PM |
|


Joined: Mar 27, 2002
Posts: 18757
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".
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;
}
|
|
|
| |
|
|
|
|
|
Posted: Jun 24, 2011 - 03:08 PM |
|


Joined: Jul 18, 2005
Posts: 62944
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
|
| |
|
|
|
|
|
Posted: Jun 24, 2011 - 03:43 PM |
|


Joined: Mar 27, 2002
Posts: 18757
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.. |
|
|
| |
|
|
|
|
|
Posted: Jun 25, 2011 - 12:17 AM |
|

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 |
|
|
| |
|
|
|
|
|
Posted: Jun 25, 2011 - 09:20 AM |
|


Joined: Mar 27, 2002
Posts: 18757
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. |
|
|
| |
|
|
|
|
|
Posted: Jun 25, 2011 - 03:03 PM |
|

Joined: Nov 12, 2010
Posts: 4
|
|
sorry if my translation is not good
JohanEkdahl wrote:
So, what you need is a lump of C code that translates to that assembler code? Exactly?
is something like
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.
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 ???  |
|
|
| |
|
|
|
|
|
Posted: Jun 25, 2011 - 03:21 PM |
|


Joined: Mar 27, 2002
Posts: 18757
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.] |
|
|
| |
|
|
|
|
|
Posted: Jun 25, 2011 - 04:15 PM |
|

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
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  |
|
|
| |
|
|
|
|
|
Posted: Jun 27, 2011 - 10:09 AM |
|


Joined: Jul 18, 2005
Posts: 62944
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. |
_________________
|
| |
|
|
|
|
|
Posted: Jun 27, 2011 - 10:32 AM |
|


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden
|
|
| Cliff! The calls to common_handler() will do pushes and stuff. As I understand 'yggdrasil' this is not what he wants.. |
|
|
| |
|
|
|
|
|
Posted: Jun 27, 2011 - 10:48 AM |
|


Joined: Jul 18, 2005
Posts: 62944
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!) |
_________________
|
| |
|
|
|
|
|
Posted: Jun 27, 2011 - 11:39 AM |
|


Joined: Mar 27, 2002
Posts: 18757
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. |
|
|
| |
|
|
|
|
|