Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Timer Interrupt handling in MC68332

76 views
Skip to first unread message

Ammulu

unread,
Jan 18, 2003, 1:19:13 AM1/18/03
to
hi friends
i am working on MC68332 based embeddeed system.
i am facing some problems while doing continuous RAM operation (Read
and compare with expected value)with timer interrupt.

here my requirement is like as follows

i have to do entire RAM area checks continuously with timer interrupt
configured for 5 msec interrupt.I fused my code in FLASH.

here i dont have any prob with PC(program Counter) but my test is
giving fail status.When checked the memory,the required memory
locations are having expected data.From this i could make out that
test is failing only due to read and compare operations.

So if any body have solution please let me know.
by
lakshmi

Tauno Voipio

unread,
Jan 18, 2003, 4:11:47 AM1/18/03
to

"Ammulu" <reddy...@yahoo.com> wrote in message
news:5b8e08f9.03011...@posting.google.com...

Some questions:

Which timer? (interval timer or TPU channel)

Internal or external RAM?

Are you sure that you're not checking the area used for interrupt handler
workspace?

Please note that the internal RAM can be given to TPU as code memory.

Tauno Voipio
tauno voipio @ iki fi


Mark Borgerson

unread,
Jan 18, 2003, 12:47:42 PM1/18/03
to
In article <5b8e08f9.03011...@posting.google.com>,
reddy...@yahoo.com says...

Have you taken into account that the processor is running in the
supervisor mode during the interrupt? You need to make sure that
the supervisor stack pointer is properly set up or you don't
know where pushes to that stack are going to occur in memory.

Are there any other interrupt running that could be of higher
priority than your memory check? A failure of another routine
to save all the proper registers could cause the mem check
to fail.

Mark Borgerson

Ammulu

unread,
Jan 21, 2003, 12:05:33 AM1/21/03
to
Hi,
we are not using any other interrupts and we have set the SP in
Supervisory mode only.
Previsouly we handled Timer ISR in C language using GNU C
compiler.
When we are handling Timer ISR in assembly language, we don't have any
problem.
Is ther any problem with Compiler or with C language ?
Please let me know the information.

Ammulu

Gene S. Berkowitz

unread,
Jan 21, 2003, 1:21:20 AM1/21/03
to
In article <5b8e08f9.03012...@posting.google.com>,
reddy...@yahoo.com says...

There may be a problem with the compiler _interrupt_ pragma
not preserving all registers used.

You might try inlining "push/pop Rx" for the entire register set
in the ISR. If it works, remove them one by one until you find the
offending register.

--Gene

Eric Doenges

unread,
Jan 21, 2003, 2:35:57 AM1/21/03
to

The GNU C compiler does not have an _interrupt_ pragma for the 68k
family, so this is likely the problem. For the original poster --
for the 68k family, gcc does not preserve register a0,a1,d0 and d1.
I would strongly discourage inlining register save/restore code
in a C function, because that would disrupt the assumptions gcc makes
about the elements on the stack. Instead, write small glue routines
in assembler:

asm(
" .text\n"
" .even\n"
" .global MyIsr\n"
"MyIsr_glue: movem.l %d0-%d1/%a0-%a1,-(%sp)\n"
" jsr MyIsr\n"
" movem.l (%sp)+,%d0-%d1/%a0-%a1\n"
" rte\n"
);


void MyIsr(void) {
/* Add your ISR code here */
}

The interrupt vector table has to be initialized to MyIsr_glue,
not MyIsr.
--
________________________________________________________________________
Dipl.-Ing. Eric Doenges http://www.rcs.ei.tum.de
Institute for Real-Time Computer Systems (RCS) fon +49-89-289-23590
Technische Universitaet Muenchen, D-80290 Muenchen fax +49-89-289-23555

Tauno Voipio

unread,
Jan 21, 2003, 4:37:36 AM1/21/03
to

"Eric Doenges" <doe...@lpr.e-technik.tu-muenchen.de> wrote in message
news:pan.2003.01.21.08....@lpr.e-technik.tu-muenchen.de...

The way I do it:

Embed the glue routine in a C function returning a pointer to the glue
function. The function result can be set to interrupt vector in C code.

void *isrptr(void)
{
void *ptr;

asm (
" lea Glue,%0\n"
" bra skip\n"

/* embedded interrupt glue veneer */

"Glue:\n"
......... /* copy code from above */
" rte\n"

/* end of veneer */

"skip:\n"

"=&r" (ptr)
);

return ptr;
}

The interrupt function (MyIsr) does not need to be global if it is in the
same module as the glue and setup function.

Disclaimer: The code is translated from equivalent ARM GCC code, M68k
blunders may be present.

Gene S. Berkowitz

unread,
Jan 25, 2003, 10:38:35 PM1/25/03
to
In article <pan.2003.01.21.08....@lpr.e-technik.tu-
muenchen.de>, doe...@lpr.e-technik.tu-muenchen.de says...

> >>
> >>
> > There may be a problem with the compiler _interrupt_ pragma not
> > preserving all registers used.
> >
> > You might try inlining "push/pop Rx" for the entire register set in the
> > ISR. If it works, remove them one by one until you find the offending
> > register.
>
> The GNU C compiler does not have an _interrupt_ pragma for the 68k
> family, so this is likely the problem.

That's interesting. How are you supposed to notify the compiler that
you're writing an ISR?

--Gene

Anton Erasmus

unread,
Jan 26, 2003, 8:14:25 AM1/26/03
to

Hi,

There is a version of the gcc 68K port available that supports the
interrupt attribute. It is version 2.95.3. Someone at Motorola added
the support, and apprently will hopefully have it in the main stream
source branch by version 3.3
Unfortunately I do not have the URL handy of where I downloaded
this version.

Regards
Anton Erasmus


Eric Doenges

unread,
Jan 27, 2003, 2:45:33 AM1/27/03
to
On Sun, 26 Jan 2003 04:38:35 +0100, Gene S. Berkowitz wrote:

> That's interesting. How are you supposed to notify the compiler that
> you're writing an ISR?

You can't. Many moons ago there was a patch that added this capability
to gcc, but it never found it's way into the main source tree. You
have to write your own glue code that saves the registers not usually
saved by the compiler, and has the 'rte' at the end (see my previous
post). Does this suck ? Yes it does, but then gcc was originally
designed to compile Unix software, not serve as a cross-compiler for
embedded systems. AFAIK, only three (or was it two ?) gcc targets have
direct support for writing ISRs.

Mark Borgerson

unread,
Jan 27, 2003, 5:37:30 PM1/27/03
to
In article <pan.2003.01.27.08...@lpr.e-technik.tu-
muenchen.de>, doe...@lpr.e-technik.tu-muenchen.de says...

> On Sun, 26 Jan 2003 04:38:35 +0100, Gene S. Berkowitz wrote:
>
> > That's interesting. How are you supposed to notify the compiler that
> > you're writing an ISR?
>
> You can't. Many moons ago there was a patch that added this capability
> to gcc, but it never found it's way into the main source tree. You
> have to write your own glue code that saves the registers not usually
> saved by the compiler, and has the 'rte' at the end (see my previous
> post). Does this suck ? Yes it does, but then gcc was originally
> designed to compile Unix software, not serve as a cross-compiler for
> embedded systems. AFAIK, only three (or was it two ?) gcc targets have
> direct support for writing ISRs.

Knowing little about Unix, but a bit about 68K systems, I wonder
how anyone could hope to write Unix for the 68K without writing
interrupt handlers. Isn't one of the features of Unix or Linux
for a particular processor the ability to compile the OS with
the C compiler?

Mark Borgerson

Eric Smith

unread,
Jan 27, 2003, 9:26:51 PM1/27/03
to
Mark Borgerson <ma...@oes.to> writes:
> Knowing little about Unix, but a bit about 68K systems, I wonder
> how anyone could hope to write Unix for the 68K without writing
> interrupt handlers. Isn't one of the features of Unix or Linux
> for a particular processor the ability to compile the OS with
> the C compiler?

Yes, but traditionally this was done by writing some assembly language
glue, which is also sometimes how the vectors were initialized.

It would be very nice if the interrupt pragma made it into GCC for the 68K,
but I'm not certain that it would have eliminated all of the assembly
glue I've had to use on past projects.

Tauno Voipio

unread,
Jan 28, 2003, 6:40:18 AM1/28/03
to

"Mark Borgerson" <ma...@oes.to> wrote in message
news:MPG.189f54817...@netnews.attbi.com...

That's not too difficult - just write a piece of assembler glue, either as a
separate module or embedded in C code if the compiler allows it.

I already posted a draft version for M68k GCC.

The idea is:

-C function returning pointer to interrupt handler,
-function body consists of an asm statement, which:
-loads the address of the glue code in pointer return register
-jumps over the glue code
-glue code:
-saves registers
-calls the real interrupt handler
-restores registers
-dismisses interrupt with rte
-function code returns with the glue code address

The main program calls the encapsulated interrupt handler function to get a
pointer to the glues code and iinstalls the pointer into the interrupt
vector table.

Here is a slightly more complicated version for ARM/Thumb GCC:

/* Set up IRQ handler */

static void set_irq_handler(void)
{
FWORD ih_ptr;

asm (
"adr %0,irq1\n\t" /* -> interrupt handler */
"b irq6\n\t" /* skip handler proper */

/* IRQ interrupt veneer - embedded in setup code */
/* --------------------------------------------- */

".code 32\n"

"irq1:\t"

/* dismiss the interrupt if interrupts are indeed */
/* inhibited (Atmel application note 1156A) */
#if 0
"mrs r13,spsr\n\t" /* get saved PSR */
"tst r13,%5\n\t" /* interrupts disabled? (PS_I) */
"subnes pc,lr,#4\n\t" /* yes - dismiss */
#endif
/* save critical state into *ctdb
the IRQ veneer uses r4 */

"ldr r13,ctdbp\n\t" /* -> ctdb */
"ldr r13,[r13]\n\t" /* -> current TDB */

"stmia r13,{r0-r4,r12-r14}^\n\t" /* save user registers */

/* switch to system mode (user register set)
r13 and lr are preserved in IRQ bank
interrupts are kept disabled */

"mrs r4,cpsr\n\t" /* get current PSR, keep for later */
"orr r0,r4,%6\n\t" /* change to system mode (PS_SYS) */
"msr cpsr,r0\n\t" /* switch mode */

/* call irq_handler() in 16 bit mode
the code trusts that irq_handler()
preserves r4 (as specified in the APCS) */

"adr lr,irq2+1\n\t" /* -> 16 bit return */
"adr r0,irq_handler+1\n\t" /* -> interrupt handler */
"bx r0\n\t" /* handle the interrupt */

/* dismiss the interrupt */

".code 16\n"

"irq2:\t"
"adr r1,irq3\n\t" /* -> 32 bit code */
"bx r1\n\t" /* enter it */

".code 32\n"

"irq3:\t"
"msr cpsr,r4\n\t" /* restore IRQ mode (no interrupts) */

"ldmia r13,{r0-r4,r12-r14}^\n\t" /* restore user registers */
"nop\n\t" /* banked ldmia recovery delay */
"subs pc,lr,#4\n\t" /* dismiss the interrupt */

"ctdbp:\t.word ctdb\n" /* -> current TDB pointer */

/* End of interrupt veneer - continue setup code */
/* --------------------------------------------- */

".code 16\n"
"irq6:"

: "=r" (ih_ptr)
: "i" (offsetof(struct systdb, tr5)),
"i" (offsetof(struct systdb, tr12)), /***/
"i" (offsetof(struct systdb, tpc)),
"i" (offsetof(struct systdb, tpsr)),
"i" (PS_I),
"i" (PS_SYS),
"i" (irq_handler) /* not used, to keep the compiler happy */
);

arm7exc.vectr[EXC_IRQ] = ih_ptr; /* set up vector in low memory */
arm7exc.instr[EXC_IRQ] = EXC_JMP; /* set up instruction in low memory */
}


HTH

Mark Borgerson

unread,
Jan 29, 2003, 12:08:36 AM1/29/03
to
In article <C_tZ9.171$tz2...@read3.inet.fi>,
tauno....@iki.fi.SPAMBAIT_REMOVE.invalid says...


WOW! All that to---

// possible 68K RTC timer interrupt handler
ClockISR:
Inc.l ClockSeconds

RTE


// Note that no registers need be saved or restored
// on a 68K
I guess there's still a place for assembly language after all!

Mark Borgerson

0 new messages