Forums

Interrupts on a PowerPC

Started by Gilles January 17, 2008
Hello,

I'm developing some code for a PowerPC (mpc55x) with the gnu gcc. I'm using
the decrementer to generate a periodic interrupt that should execute a
C-routing.

How can I write the address of this function into the Interrupt-vector-Table
(IVOR10)?

Gilles
On Jan 17, 11:24=A0pm, Gilles <Id...@like.spam> wrote:
> Hello, > > I'm developing some code for a PowerPC (mpc55x) with the gnu gcc. I'm usin=
g
> the decrementer to generate a periodic interrupt that should execute a > C-routing. > > How can I write the address of this function into the Interrupt-vector-Tab=
le
> (IVOR10)? >
If you are asking about the method to invoke the function that you have written by using IVT, then you have to have a jump to that address in the IVT if the routine is big else, you can code it there itself. Karthik Balaguru
"Gilles" <Idont@like.spam> wrote in message news:1200594278_28@vo.lu...
> Hello, > > I'm developing some code for a PowerPC (mpc55x) with the gnu gcc. I'm > using > the decrementer to generate a periodic interrupt that should execute a > C-routing. > > How can I write the address of this function into the > Interrupt-vector-Table > (IVOR10)? > > Gilles
Here is a sample from a uCOS RTOS gcc port for the mpc555. This decrementer code may be slightly more complicated than you need because it adjusts for decrementer overflow to keep the tick in sync with real time. Scott /* **************************************************************************************************** * OS_Set_decrementer **************************************************************************************************** */ void OS_Set_decrementer (void) { __asm__ volatile (" lis r4, dec_init@ha "); __asm__ volatile (" lwz r4, dec_init@l(r4) "); __asm__ volatile (" mfdec r5 "); /* compensate for interrupt latency by */ __asm__ volatile (" add r5,r4,r5 "); /* adding decrementer underflow */ __asm__ volatile (" cmplw r4,r5 "); /* prevent that the compensated value is */ __asm__ volatile (" bge DEC_SetReg "); /* greater than the original */ __asm__ volatile (" mr r5,r4 "); __asm__ volatile ("DEC_SetReg: "); __asm__ volatile (" mtdec r5 "); /* load Decrementer */ } /* **************************************************************************************************** * DEC_Hdlr **************************************************************************************************** */ void DEC_Hdlr (void) { OS_CPU_SR cpu_sr; OS_ENTER_CRITICAL(); OS_Set_decrementer (); OS_EXIT_CRITICAL(); OSTimeTick (); /* process tick */ }
Hello,

how does the microcontroller know that the void DEC_Hdlr routine should be
executed? 
There must be a handler.s file like this:

#handler.s


.equ&nbsp;&nbsp;INTC_IACKR, 0xfff48010&nbsp;&nbsp;# Interrupt Acknoledge Register address
.equ&nbsp;&nbsp;INTC_EOIR,&nbsp;&nbsp;0xfff48018&nbsp;&nbsp;# End Of Interrupt Register address

.extern DEC_Hdlr

IVOR10Handler:
  bl   DEC_Hdlr
  rfi

#eof

is that correct? Correct me if something is missing.

Regards, Gilles

Not Really Me wrote:

> > "Gilles" <Idont@like.spam> wrote in message news:1200594278_28@vo.lu... >> Hello, >> >> I'm developing some code for a PowerPC (mpc55x) with the gnu gcc. I'm >> using >> the decrementer to generate a periodic interrupt that should execute a >> C-routing. >> >> How can I write the address of this function into the >> Interrupt-vector-Table >> (IVOR10)? >> >> Gilles > > Here is a sample from a uCOS RTOS gcc port for the mpc555. This > decrementer code may be slightly more complicated than you need because it > adjusts for decrementer overflow to keep the tick in sync with real time. > > Scott > > /* >
****************************************************************************************************
> * OS_Set_decrementer >
****************************************************************************************************
> */ > void OS_Set_decrementer (void) > { > __asm__ volatile (" lis r4, dec_init@ha "); > __asm__ volatile (" lwz r4, dec_init@l(r4) "); > __asm__ volatile (" mfdec r5 "); /* compensate for > interrupt latency by */ > __asm__ volatile (" add r5,r4,r5 "); /* adding > decrementer underflow */ > __asm__ volatile (" cmplw r4,r5 "); /* prevent that > the > compensated value is */ > __asm__ volatile (" bge DEC_SetReg "); /* greater than > the > original */ > __asm__ volatile (" mr r5,r4 "); > __asm__ volatile ("DEC_SetReg: "); > __asm__ volatile (" mtdec r5 "); /* load > Decrementer > */ > } > > /* >
****************************************************************************************************
> * DEC_Hdlr >
****************************************************************************************************
> */ > void DEC_Hdlr (void) > { > OS_CPU_SR cpu_sr; > > OS_ENTER_CRITICAL(); > OS_Set_decrementer (); > OS_EXIT_CRITICAL(); > > OSTimeTick (); /* process tick */ > }
Hello,
do you have an example how to write the address of a C-function into the
IVT?

Regards, Gilles

karthikbalaguru wrote:

> On Jan 17, 11:24&nbsp;pm, Gilles <Id...@like.spam> wrote: >> Hello, >> >> I'm developing some code for a PowerPC (mpc55x) with the gnu gcc. I'm >> using the decrementer to generate a periodic interrupt that should >> execute a C-routing. >> >> How can I write the address of this function into the >> Interrupt-vector-Table (IVOR10)? >> > > If you are asking about the method to invoke the function that you > have written by using IVT, then you have to have a jump to that > address in the IVT if the routine is big else, you can code it there > itself. > > Karthik Balaguru
"Gilles" <Idont@like.spam> wrote in message news:1200703258_34@vo.lu...
> Hello, > > how does the microcontroller know that the void DEC_Hdlr routine should be > executed? > There must be a handler.s file like this: > > #handler.s > > > .equ INTC_IACKR, 0xfff48010 # Interrupt Acknoledge Register address > .equ INTC_EOIR, 0xfff48018 # End Of Interrupt Register address > > .extern DEC_Hdlr > > IVOR10Handler: > bl DEC_Hdlr > rfi > > #eof > > is that correct? Correct me if something is missing. > > Regards, Gilles > > Not Really Me wrote: > >> >> "Gilles" <Idont@like.spam> wrote in message news:1200594278_28@vo.lu... >>> Hello, >>> >>> I'm developing some code for a PowerPC (mpc55x) with the gnu gcc. I'm >>> using >>> the decrementer to generate a periodic interrupt that should execute a >>> C-routing. >>> >>> How can I write the address of this function into the >>> Interrupt-vector-Table >>> (IVOR10)? >>> >>> Gilles >> >> Here is a sample from a uCOS RTOS gcc port for the mpc555. This >> decrementer code may be slightly more complicated than you need because >> it >> adjusts for decrementer overflow to keep the tick in sync with real time. >> >> Scott >> >> /* >> > **************************************************************************************************** >> * OS_Set_decrementer >> > **************************************************************************************************** >> */ >> void OS_Set_decrementer (void) >> { >> __asm__ volatile (" lis r4, dec_init@ha "); >> __asm__ volatile (" lwz r4, dec_init@l(r4) "); >> __asm__ volatile (" mfdec r5 "); /* compensate >> for >> interrupt latency by */ >> __asm__ volatile (" add r5,r4,r5 "); /* adding >> decrementer underflow */ >> __asm__ volatile (" cmplw r4,r5 "); /* prevent that >> the >> compensated value is */ >> __asm__ volatile (" bge DEC_SetReg "); /* greater than >> the >> original */ >> __asm__ volatile (" mr r5,r4 "); >> __asm__ volatile ("DEC_SetReg: "); >> __asm__ volatile (" mtdec r5 "); /* load >> Decrementer >> */ >> } >> >> /* >> > **************************************************************************************************** >> * DEC_Hdlr >> > **************************************************************************************************** >> */ >> void DEC_Hdlr (void) >> { >> OS_CPU_SR cpu_sr; >> >> OS_ENTER_CRITICAL(); >> OS_Set_decrementer (); >> OS_EXIT_CRITICAL(); >> >> OSTimeTick (); /* process tick */ >> } >
Sorry, was in a rush. Of course you are right. Here is the .s code. BTW, prologue and epilogue are macros that save and restore the stack frame. Remember that this example is uC/OS-II specific. You may have to adjust. Send me a direct email and I will send you the files. Scott decIsr: prologue bl OSIntEnter lis r11,OSIntNesting@ha lbz r0,OSIntNesting@l(r11) cmpwi r0,1 bne DEC_Intr_NotSaveSP # Get pointer to current TCB lis r11,OSTCBCur@ha lwz r11,OSTCBCur@l(r11) # Save stack pointer in current TCB stw r1,0(r11) DEC_Intr_NotSaveSP: bl DEC_Hdlr bl OSIntExit epilogue
Not Really Me wrote:

> > "Gilles" <Idont@like.spam> wrote in message news:1200703258_34@vo.lu... >> Hello, >> >> how does the microcontroller know that the void DEC_Hdlr routine should >> be executed? >> There must be a handler.s file like this: >> >> #handler.s >> >> >> .equ INTC_IACKR, 0xfff48010 # Interrupt Acknoledge Register address >> .equ INTC_EOIR, 0xfff48018 # End Of Interrupt Register address >> >> .extern DEC_Hdlr >> >> IVOR10Handler: >> bl DEC_Hdlr >> rfi >> >> #eof >> >> is that correct? Correct me if something is missing. >> >> Regards, Gilles >> >> Not Really Me wrote: >> >>> >>> "Gilles" <Idont@like.spam> wrote in message news:1200594278_28@vo.lu... >>>> Hello, >>>> >>>> I'm developing some code for a PowerPC (mpc55x) with the gnu gcc. I'm >>>> using >>>> the decrementer to generate a periodic interrupt that should execute a >>>> C-routing. >>>> >>>> How can I write the address of this function into the >>>> Interrupt-vector-Table >>>> (IVOR10)? >>>> >>>> Gilles >>> >>> Here is a sample from a uCOS RTOS gcc port for the mpc555. This >>> decrementer code may be slightly more complicated than you need because >>> it >>> adjusts for decrementer overflow to keep the tick in sync with real >>> time. >>> >>> Scott >>> >>> /* >>> >>
****************************************************************************************************
>>> * OS_Set_decrementer >>> >>
****************************************************************************************************
>>> */ >>> void OS_Set_decrementer (void) >>> { >>> __asm__ volatile (" lis r4, dec_init@ha "); >>> __asm__ volatile (" lwz r4, dec_init@l(r4) "); >>> __asm__ volatile (" mfdec r5 "); /* compensate >>> for >>> interrupt latency by */ >>> __asm__ volatile (" add r5,r4,r5 "); /* adding >>> decrementer underflow */ >>> __asm__ volatile (" cmplw r4,r5 "); /* prevent that >>> the >>> compensated value is */ >>> __asm__ volatile (" bge DEC_SetReg "); /* greater than >>> the >>> original */ >>> __asm__ volatile (" mr r5,r4 "); >>> __asm__ volatile ("DEC_SetReg: "); >>> __asm__ volatile (" mtdec r5 "); /* load >>> Decrementer >>> */ >>> } >>> >>> /* >>> >>
****************************************************************************************************
>>> * DEC_Hdlr >>> >>
****************************************************************************************************
>>> */ >>> void DEC_Hdlr (void) >>> { >>> OS_CPU_SR cpu_sr; >>> >>> OS_ENTER_CRITICAL(); >>> OS_Set_decrementer (); >>> OS_EXIT_CRITICAL(); >>> >>> OSTimeTick (); /* process tick */ >>> } >> > > Sorry, was in a rush. Of course you are right. Here is the .s code. > BTW, prologue and epilogue are macros that save and restore the stack > frame. > Remember that this example is uC/OS-II specific. You may have to adjust. > Send me a direct email and I will send you the files. > > Scott > > decIsr: > > prologue > > bl OSIntEnter > > lis r11,OSIntNesting@ha > lbz r0,OSIntNesting@l(r11) > cmpwi r0,1 > bne DEC_Intr_NotSaveSP > > # Get pointer to current TCB > lis r11,OSTCBCur@ha > lwz r11,OSTCBCur@l(r11) > > # Save stack pointer in current TCB > stw r1,0(r11) > > DEC_Intr_NotSaveSP: > bl DEC_Hdlr > > bl OSIntExit > > epilogue
Hello, I've found the missing part to get my code working: First one has to define a line like this (ass shown in AN3524SW): /* Interrupt Handler Parameters */ __IV_ADDR = ADDR(.xcptn); in the linker file. Then this must be added in handler.s: .equ IV_ADDR, __IV_ADDR .org IV_ADDR because the ISR must be close together. Somewhere in the code (during the initialization) the addresses of the ISR must be written into the corresponding special function registers: asm ("lis r5, __IV_ADDR@h"); asm ("mtivrp r5 "); asm ("lis r5, IVOR10Handler@h"); asm ("ori r5, r5, IVOR10Handler@l"); asm ("mtivor10 r5"); Regards, Gilles