Searching \ for '[PIC] Chaining ISRs with the linker' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'Chaining ISRs with the linker'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] Chaining ISRs with the linker'
2005\06\29@095935 by Peter Onion

flavicon
face
I'm "refactoring some absolute mode code" which means I'm splitting the
reusable bits into separate files.

Several of these modules will need interrupt service routines (ISRs) in
them for handling their associated devices.  At the moment the isr code
is all together in an absolute segment at location 4.

It occurred to me that if I create a code segment called "isr" in each
module's source file, then the linker will put these together, one after
another, in the final image (.hex file).  If each module's isr code
sticks to a few rules (eg. no assumptions on bank settings, no messing
with pclath) and is just a block of code which always exits to a label
at it's end, then each one will be run in turn to test for and handle
interrups.

This method also requires suitable "top and tail" code in the isr
segment (to save and restore the context). Some simple tests I've done
show that putting the context save code in "intstart.asm" and context
restore and retfie code in "intend.asm", and making sure that the files
are linked in the order  "intstart.o" .... (any modules with isrs) ....
"intend.o" puts things in the right order in the final compound isr
segment.

You could even use a separate segment for code to be run periodically
by a "timer tick"

I expect someone will come up with some "prior art" as I'm sure this has
been done before ;-)

I realise there may be some potential problems with this, but what does
everyone think ?

Peter

2005\06\29@105542 by Jan-Erik Soderholm

face picon face
> Several of these modules will need interrupt
> service routines
(ISRs) in them for handling
> their associated devices.  At the moment
> the isr code is all together in an absolute
> segment at location 4.

I guess that you nedd to have some check in the
"main-ISR" to decide
which module-specific
ISR to call, right ? Then it doesn't matter much
where they are, let the linker spread them
as it likes. Why do you need
them stacked
together ?

> Some simple tests I've done show that
putting
> the context save code in "intstart.asm" and context
> restore
and retfie code in "intend.asm", and making
> sure that the files are
linked in the order  "intstart.o"
> .... (any modules with isrs) ....
"intend.o" puts things in
> the right order in the final compound isr
segment.

I'm not sure that that is by design, it could have
been a
coincidence. One little change someware
and the linker might decide to
swap the modules
around.

Why do you need to have your module-specific
ISR's stacked in that way ?

Regards,
Jan-Erik.



2005\06\29@113134 by Peter Onion

flavicon
face
On Wed, 2005-06-29 at 16:55 +0200, Jan-Erik Soderholm wrote:

> I guess that you nedd to have some check in the
> "main-ISR" to decide
> which module-specific
> ISR to call, right ?

No.  There is nothing in the "main ISR" routine other than the context
save.

Each module's isr checks the appropriate PIR bit and jumps to the next
handler in the chain if there is nothing to do.  If there is work to be
done, it does it and then jumps to the next one.

>  Then it doesn't matter much
> where they are, let the linker spread them
> as it likes. Why do you need
> them stacked
> together ?

So that I don't have to do anything other than link the module.o file to
make use of the peripheral.  Any "extern" definitions for the APIs can
go in an include file.  I'm also going to use the same technique to
chain together all the devices' initialisation code, so then it will be
really easy to use an device from my library of drivers.

Peter



2005\06\29@115254 by Jan-Erik Soderholm

face picon face
Peter Onion wrote :

> No.  There is nothing in the "main ISR"
>
routine other than the context save.
>
> Each module's isr checks the
appropriate PIR
> bit and jumps to the next handler in the chain
> if
there is nothing to do.

I guess that what it realy does, is to jump to
its own "end", and that the PIC then just
"falls through" to the next
ISR, becuse they
happens to be stuffed together physicaly in
memory,
right ?

And each handler doesn't realy knows about
the others, do they
?

I see what you are doing (with the init codes also),
but I'm not
sure that it's "safe"...

Another way (that also makes sure that all
ISR code
is held together, would be to #include the modules
from the
ISR-stub.

> ....really easy to use an device from my
> library of
drivers.

Are you takling about *pre-assembled* library ?
(Either as .O
files or as a .LIB) ?

It seems as pre-assembled code isn't used
very
much with the PICs, mainly becuse you
miss all assembly time
calculations and
conditional assembly that can make the
"library
routines" realy flexible. Most seems
to keep theirs "code libs" as
source code...

Jan-Erik.



2005\06\29@121443 by Peter Onion

flavicon
face
On Wed, 2005-06-29 at 17:52 +0200, Jan-Erik Soderholm wrote:

> I guess that what it realy does, is to jump to
> its own "end", and that the PIC then just
> "falls through" to the next
> ISR, becuse they
> happens to be stuffed together physicaly in
> memory,
> right ?

Yes 100% correct.

> And each handler doesn't realy knows about
> the others, do they

No, no connection between them.

> Are you takling about *pre-assembled* library ?
> (Either as .O
> files or as a .LIB) ?

Yes.  I guess my "big computer" mentality is showing here.  I'm used to
putting all my useful bits of C code into libraries for later reuse.

{Quote hidden}

There's no reason why a single source file with conditional assembly
can't still be used to produce libraries.  I'm planning to use
subdirectories to hold the .o and .a files for the various target PICs
and to use "make" to rebuild for only the required target when the
sources change.

I'll write it up when I've got it working.

Peter



2005\06\29@124229 by olin piclist

face picon face
Peter Onion wrote:
> It occurred to me that if I create a code segment called "isr" in each
> module's source file, then the linker will put these together, one after
> another, in the final image (.hex file).  If each module's isr code
> sticks to a few rules (eg. no assumptions on bank settings, no messing
> with pclath) and is just a block of code which always exits to a label
> at it's end, then each one will be run in turn to test for and handle
> interrups.

I'd be worried about guaranteed order of segments placed by the linker.
Yes, ti will place absolute segments first, but after that it depends on
segment size and the sizes of remaining space.  The segment at the interrupt
vector will be absolute, but I don't see how to guarantee that other
segments of a specific name will follow.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\06\29@124312 by Jan-Erik Soderholm

face picon face
Peter Onion wrote :

> > Are you takling about *pre-assembled* library
?
> > (Either as .O
> > files or as a .LIB) ?
>
> Yes.  I guess my
"big computer" mentality is
> showing here.  I'm used to putting all my
useful
> bits of C code into libraries for later reuse.

Beeing a long
time VMS (probably the best software
development platform available)
developer, I think
I fully understands the concepts of "object
libraries... :-)

> There's no reason why a single source file
> with
conditional assembly can't still be used
> to produce libraries.

Yes,
project/application specific libraries then.
That's just fine. Problem
is when trying to
sheare obj libs between multiple projects
(that needs
different conditional assembling)...

Jan-Erik.



2005\06\29@140318 by olin piclist

face picon face
Peter Onion wrote:
> There's no reason why a single source file with conditional assembly
> can't still be used to produce libraries.  I'm planning to use
> subdirectories to hold the .o and .a files for the various target PICs
> and to use "make" to rebuild for only the required target when the
> sources change.

But there is a lot more than target PIC type to customize the code to.
There is clock speed, size and location of the software stack, number and
location of scratchpad registers, etc, etc.  In the end you'll be creating a
different "library" for each project.  Given that, you might as well keep
the library in source form and use INCLUDE to grab what you need when you
need it.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\06\29@153242 by Peter Onion

flavicon
face
On Wed, 2005-06-29 at 12:42 -0400, Olin Lathrop wrote:

> I'd be worried about guaranteed order of segments placed by the linker.
> Yes, ti will place absolute segments first, but after that it depends on
> segment size and the sizes of remaining space.  The segment at the interrupt
> vector will be absolute, but I don't see how to guarantee that other
> segments of a specific name will follow.

The only thing about the order that matters that you can ensure the isr
tail code (with context restore and retfie) comes last.

I think it would be a pretty perverse linker that put code from the same
segment in any order other than the order it comes across it while
processing the command line arguments.

Maybe someone can try this with different mplink version to see how they
behave ? I've looked in the MPASM/MPLINK manual but I can't see anything
helpful.

You can slap me on the wrist Olin as I for got to add I'm using
gplink ;-)

Peter

2005\06\29@154306 by Peter Onion

flavicon
face
On Wed, 2005-06-29 at 18:43 +0200, Jan-Erik Soderholm wrote:

> Yes,
> project/application specific libraries then.
> That's just fine. Problem
> is when trying to
> sheare obj libs between multiple projects
> (that needs
> different conditional assembling)...
>

Hmmm... I see what you mean.....  

I've not thought this through, but for each project once the options
have been defined, run "make libs" to create any .o and .a files needed
and put them in a "libs" subdirectory.  Then link them from "make
project.hex"

Let me work on this a bit more to see if there are any "gotchas" in my plan.

Peter



2005\06\29@165412 by Peter Onion

flavicon
face
On Wed, 2005-06-29 at 14:03 -0400, Olin Lathrop wrote:

> But there is a lot more than target PIC type to customize the code to.
> There is clock speed, size and location of the software stack, number and
> location of scratchpad registers, etc, etc.  In the end you'll be creating a
> different "library" for each project.  Given that, you might as well keep
> the library in source form and use INCLUDE to grab what you need when you
> need it.

You are probably right, but that's no reason for me not to try :-)
After all objectives may be different to yours.

Peter.


2005\06\29@194935 by olin piclist

face picon face
Peter Onion wrote:
> The only thing about the order that matters that you can ensure the isr
> tail code (with context restore and retfie) comes last.

Yes, within that segment.  However, my point was how do you guarantee that
this segment even follows the ISR startup code at all?  The startup code
needs to be at an absolute address.  I could see the linker not allowing
absolute and relocatable segments with the same name.  On the other hand,
maybe it's fine with that, I've never tried.

> I think it would be a pretty perverse linker that put code from the same
> segment in any order other than the order it comes across it while
> processing the command line arguments.

Maybe, but it could also do it backwards or whatever.  I would stay away
from this unless it is specified in the linker manual.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\06\30@053708 by Peter Onion

flavicon
face
On Wed, 2005-06-29 at 19:49 -0400, Olin Lathrop wrote:
> Peter Onion wrote:
> > The only thing about the order that matters that you can ensure the isr
> > tail code (with context restore and retfie) comes last.
>
> Yes, within that segment.  However, my point was how do you guarantee that
> this segment even follows the ISR startup code at all?  The startup code
> needs to be at an absolute address.

Yes you are right, and I think I've said somewhere else that the isr
context save code is in an absolute segment at location 4.  It then
jumps to a label at the top of the isr handlers segment.

>  I could see the linker not allowing
> absolute and relocatable segments with the same name.  On the other hand,
> maybe it's fine with that, I've never tried.

You are right.  start up code is in a differently named (absolute)
segment.  Handlers go in a segment called "handlers" which is
relocatable.

> > I think it would be a pretty perverse linker that put code from the same
> > segment in any order other than the order it comes across it while
> > processing the command line arguments.
>
> Maybe, but it could also do it backwards or whatever.  I would stay away
> from this unless it is specified in the linker manual.

Who was talking about using "undocumented MPASM features" the other
week ?  ;-)

I've got a little example working which has interrupt handers for serial
receive and TMR0 and startup code for USART and TMR0 in "chained
segments" and it works fine.  

The main code has nothing in it but the context save for the isr, a call
to "startSetup"  and a calls to getChar, waitWms and putchar in an
endless loop.  

waitWms sets a counter and starts up TMR0 interrupts. The TMR0 interrupt
handler decrements a counter (at 1ms intervals) until it reaches zero
then it stops the interrupts.  waitWms just sits and waits until the
counter becomes zero then returns.

The USART rx interrupt puts chars in a circular buffer while the
"waitWms" is pausing so upto 16 chars can be buffered.

Peter


2005\06\30@075124 by olin piclist

face picon face
Peter Onion wrote:
> Yes you are right, and I think I've said somewhere else that the isr
> context save code is in an absolute segment at location 4.  It then
> jumps to a label at the top of the isr handlers segment.

I just assumed you didn't want the interrupt code hanging out on another
page somewhere.  That means an extra PCLATH load and GOTO.  I guess you
could eliminate the PCLATH load if you forced your relocatable ISR segment
to page 0 in the linker control file.

>> Maybe, but it could also do it backwards or whatever.  I would stay
>> away from this unless it is specified in the linker manual.
>
> Who was talking about using "undocumented MPASM features" the other
> week ?  ;-)

Oh?  And what undocumented feature was that?


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\06\30@083555 by Peter Onion

flavicon
face
On Thu, 2005-06-30 at 07:51 -0400, Olin Lathrop wrote:
> Peter Onion wrote:
> > Yes you are right, and I think I've said somewhere else that the isr
> > context save code is in an absolute segment at location 4.  It then
> > jumps to a label at the top of the isr handlers segment.
>
> I just assumed you didn't want the interrupt code hanging out on another
> page somewhere.

I've not worried about where the chained handlers segment ends up ...

>  That means an extra PCLATH load and GOTO.

Yes, I'm doing those.  I'm not worrying about that slight additional
overhead at the moment.

> > Who was talking about using "undocumented MPASM features" the other
> > week ?  ;-)
>
> Oh?  And what undocumented feature was that?

I'm not even sure which list it was on !  I think it started with talk
about using colons after label names and went on from there......

Peter


'[PIC] Chaining ISRs with the linker'
2005\07\11@092707 by Alan B. Pearce
face picon face
>I've got a little example working which has interrupt handers
>for serial receive and TMR0 and startup code for USART and
>TMR0 in "chained segments" and it works fine.

Just got back from 10 days (working unfortunately) in sunny Kourou, so
catching up on discussions.

I get the impression, Peter, that you are setting out to do exactly what I
did using Olins development environment. You can see extern labels declared
for interrupt handlers that were in other modules (the serial one is a
rework of Fr. MacGhees code).

below is the code from an interrupt handler I did: -

;   This module is based on a concept developed by Olin Lathrop as outlined
;   in the following copyright notice. All additional code developed for the
;   end use product is copyright 2002, Rutherford Appleton Laboratory.
;
;   ***************************************************************
;   * Copyright (c) 2001, Embed Inc (http://www.embedinc.com)     *
;   *                                                             *
;   * Permission to copy this file is granted as long as this     *
;   * copyright notice is included in its entirety at the         *
;   * beginning of the file, whether the file is copied in whole  *
;   * or in part and regardless of whether other information is   *
;   * added to the copy.                                          *
;   *                                                             *
;   * The contents of this file may be used in any way,           *
;   * commercial or otherwise.  This file is provided "as is",    *
;   * and Embed Inc makes no claims of suitability for a          *
;   * particular purpose nor assumes any liability resulting from *
;   * its use.                                                    *
;   ***************************************************************
;
;   Interrupt service and related routines.
;
        include "hkp.inc"

;       noexpand        ; no macro expansion

        extern i2c_intr
        extern uart_intr_rx
        extern uart_intr_tx

        extern_flags        ; declare global flag bits EXTERN
;
;***********************************************************************
;
;   Configuration constants.
;
save_fsr equ     true        ; indicate whether ISR must save/restore FSR
;
;**********
;
;   Derived constants.
;

;
;***********************************************************************
;
;   Global state.
;
;   The following global state is in the normal register bank for global
;   state.  The bank is GBANK, and GBANKADR is an address guaranteed to
;   be within this bank.
;
.bank#v(gbank) udata

temp1    res     1           ; temp scratch that may be trashed by any
routine

        global  temp1
;
;***********************************************************************
;
;   Local state.  This is always in the same register bank as the global
;   state.
;

;
;   The following state is private to the interrupt service routine, and
;   must always be in bank 0.
;
 if gbank != 0
.bank0   udata
   endif
status_save res  1           ; saved copy of STATUS, nibbles swapped
 if save_fsr
fsr_save res     1           ; saved copy of FSR (if FSR save enabled)
   endif
 if ncodepages > 1
pclath_save res  1           ; saved copy of PCLATH (if multiple code pages)
   endif

itmp1   res     1            ; temp storage for use within interrupt routine
itmp2   res     1
;
;   This state is private to the interrupt service routine and must always
;   be accessible regardless of the current direct register bank setting.
;
        udata_shr
w_save   res     1           ; saved W during interrupt, mapped to all banks

.intr    code
;
;***********************************************************************
;
;   Subroutine INTR_INIT
;
;   Initialize the interrupt system and other state managed by this module.
;
        glbsub  intr_init, noregs
;
;   Initialize local state.
;
;   setup the INTR function
       dbankif OPTION_REG
       clrf    OPTION_REG          ; set defaults for most things
;       bcf     OPTION_REG,INTEDG   ; set to falling edge interrupts
;       bsf     INTCON,INTF         ; allow it to interrupt - turned on
after download

;   set up timer interrupts
;   TMR0    - Not used here
;       dbankif TMR0
;       movlw   timer0_val
;       movwf   TMR0
;       bcf     OPTION_REG,T0CS     ; set to internal clock source
;       bcf     OPTION_REG,T0SE     ; set external clock edge
;       bsf     OPTION_REG,PSA      ; set prescaler to watchdog timer
;       bsf     INTCON,T0IE

;   TMR1    - used for timeout timimg
       dbankif T1CON
       clrf    T1CON               ; default to timer off, Internal Clock,
Prescale 1
       bsf     T1CON,T1CKPS1       ; set to prescale 4
       movlw   low Timer1_Value
       movwf   TMR1L
       movlw   high Timer1_Value
       movwf   TMR1H

       dbankif PIE1
       bsf PIE1,TMR1IE             ; enable interrupts for timer
       dbankif OPTION_REG
       bsf     OPTION_REG, PEIE    ; allow timer interrupts

;   TMR2    - not used here


;
;   Initialize global state.
;
;       dbankif INTCON          ; INTCON occurs in all banks
       bsf INTCON,GIE          ; enable global interrupt bit
                               ; to finally awaken the whole system up
        leaverest
;
;***********************************************************************
;
;   Interrupt service routine.
;
;   The processor effectively executes a call to location 4 on an interrupt,
;   except that global interrupts are also disabled.  These are re-enabled
;   at the end of the ISR by the RETFIE instruction.
;
;   Note that subroutine calls must be minimized or avoided in the ISR.
;   Since an interrupt can come at any time in the main code, any additional
;   call stack locations used here are not available anywhere else.
;
.intr_svc code   4              ; start at interrupt vector location
       movwf   w_save          ; save W
intr_trap
       swapf   status,w        ; make copy of status without effecting
status bits
       clrf    status          ; select direct and indirect register banks
0

       dbankis 0
       ibankis 0
       movwf   status_save     ; save old STATUS value with nibbles swapped

       dbank   intr_led_reg
       bcf     intr_led_pin    ; show serial activity LED

 if save_fsr                   ; FSR needs to be saved ?
       movf    fsr, w          ; save FSR
       movwf   fsr_save
   endif

 if ncodepages > 1             ; multiple code pages may be in use ?
       movf    pclath, w       ; save PCLATH
       movwf   pclath_save
       clrf    pclath
   endif
;
;   W, STATUS, FSR (if SAVE_FSR set), and PCLATH (if multiple code pages)
;   have been saved.  Direct and indirect register banks 0 are selected, and
;   the bank assumptions have been set accordingly.  Program memory page 0
;   is selected.
;
       dbank   pir1            ; check for UART receive interrupt
       btfss   pir1, rcif
       goto    no_uart_recv
;********************
intr_uart_rx
       nop                     ; nop for ICD to stop on
       gjump   uart_intr_rx    ; will jump to INTR_RET when done

;********************

no_uart_recv
       dbankif pie1
       btfss   pie1, txie      ; check for UART transmit interrupt allowed
       goto    no_uart_trans   ; no so skip check

       dbankif pir1
       btfss   pir1, txif      ; check if UART tx interrupt occurred
       goto    no_uart_trans
;********************
intr_uart_tx
       nop                     ; nop for ICD to halt on
       gjump   uart_intr_tx    ; will jump to INTR_RET when done

;********************

no_uart_trans

       dbankif pir1            ; check for I2C interrupt
       btfss   pir1, sspif
           goto    no_i2c
           gjump   i2c_intr    ; will jump to INTR_RET when done

;********************

no_i2c

       dbankif pir1
       btfsc   pir1,tmr1if
       goto    tmr1_intr

;********************

intr_chk_inte
       btfsc   INTCON,INTE     ; check if interrupt enabled
       goto    intr_ret        ; no, so dont look for interrupt
       bcf INTCON,INTF         ; clear the interrupt flag


;;      goto    intr_ret        ; To prevent ALERTS


intr_alert
       dbankif OPTION_REG
       btfsc   OPTION_REG,INTEDG
       goto    Clear_Big_Red_Intr

       bsf OPTION_REG,INTEDG   ; change edge to turn off next time
       dbankif big_red_reg
       bcf     big_red_pin     ; show Panic Interrupt LED

       dbankif gbankadr
       bsf flag_Alert          ; show an alert occurred

       goto    intr_ret

;********************

Clear_Big_Red_Intr
       dbankis OPTION_REG
       bcf OPTION_REG,INTEDG

       dbankif INTCON
       bcf INTCON,INTF         ; clear the interrupt flag
       bsf INTCON,INTE         ; Enable Interrupt

       dbankif big_red_reg
       bsf     big_red_pin     ; clear Panic Interrupt LED

       goto    intr_ret

;
;********************
;
intr_nonint
                   ; we should never end up here but this
                   ; is a trap point for ICD to check.
       nop
;
;********************
;
;   Restore state to when the interrupt occurred and return from interrupt.
;
   glbent  intr_ret        ; common code to return from the interrupt
        clrf    status     ; register bank settings are now 0
        dbankis 0
        ibankis 0
 if ncodepages > 1             ; multiple code pages may be in use ?
        movf    pclath_save, w ; restore PCLATH
        movwf   pclath
   endif

 if save_fsr                   ; FSR needs to be restored ?
        movf    fsr_save, w    ; restore FSR
        movwf   fsr
   endif
   dbankif intr_led_reg
   bsf     intr_led_pin    ; clear interrupt activity LED

   dbankif 0
   swapf   status_save,w   ; get old STATUS with nibble order restored
   movwf   status          ; restore STATUS, register banks now unknown
   swapf   w_save,f        ; swap nibbles in saved copy of W
   swapf   w_save,w        ; restore original W

   retfie                  ; return from interrupt, re-enable global
interrupts

;********************************************************************
;*                                                                  *
;*  Routine "Tmr1_Intr"                                             *
;*  Handle the timer 1 timeout by setting the timeout flag, turning *
;*  off the timer, and setting up for next time.                    *
;*                                                                  *
;********************************************************************

   locent  Tmr1_Intr

   dbankif pir1
   bcf PIR1,TMR1IF     ; clear the interrupt flag
   dbankif gbankadr
   bsf flag_timeout    ; show that timeout occurred

   dbankif T1CON
   bcf T1CON,TMR1ON    ; turn timer off
   nop                 ; to allow switch off to take effect

   dbankif TMR1L       ; reload timer to 100mS default
   movlw   low Timer1_Value
   movwf   TMR1L
   dbankif TMR1H       ; ready for the next timeout
   movlw   high Timer1_Value
   movwf   TMR1H

   goto    intr_ret    ; and return from interrupt

end

2005\07\11@095806 by olin piclist
face picon face
Alan B. Pearce wrote:
> I get the impression, Peter, that you are setting out to do exactly
> what I did using Olins development environment.

I noticed some things you might want to look into:

> .bank#v(gbank) udata

I've got a nicer way of handling this since you grabbed the snapshot this
code was based on.  See the new DEFRAM macro.

>  if gbank != 0
> .bank0   udata
>    endif

DEFRAM gets around this messiness.

>        clrf    status          ; select direct and indirect bank 0
>        dbankis 0
>        ibankis 0
>        ...
>        dbank   intr_led_reg
>        bcf     intr_led_pin    ; show serial activity LED

I assume you are using DBANK only since this is intended to be temporary
debug code.  Otherwise DBANKIF would be better since it probably wouldn't
emit any instructions.  The bank is already known to be 0, and the port
register is probably in bank 0.

>  if save_fsr                   ; FSR needs to be saved ?
>        movf    fsr, w          ; save FSR
>        movwf   fsr_save
>    endif

This is a problem since the LED code stomped on the bank.  This code assumes
the bank is 0 since it was meant to be right after the CLRF STATUS.  In
general it is best to put app code after the standard interrupt entry is
complete.

>  if ncodepages > 1             ; multiple code pages may be in use ?
>        movf    pclath, w       ; save PCLATH
>        movwf   pclath_save
>        clrf    pclath
>    endif

Same bank dependency on PCLATH_SAVE here.

>        dbank   pir1            ; check for UART receive interrupt

Why DBANK and not DBANKIF?  I don't see any reason the assembler lost track
of the bank.  Anyway, I think it's better to state that separately with an
UNBANK, then have code that requires a particular bank use DBANKIF.  That
allows code snippets to be moved around without problems and redundant bank
setting cycles.

>        nop                     ; nop for ICD to stop on

Yeah, I wish the ICD didn't have that problem either.  However, I've been
surrounding these NOPs with IF DEBUG.  I can set one symbol in the main
include file to include or remove the ICD2 debug NOPs.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\07\11@101340 by Peter Onion

flavicon
face
On Mon, 2005-07-11 at 14:27 +0100, Alan B. Pearce wrote:
> >I've got a little example working which has interrupt handers
> >for serial receive and TMR0 and startup code for USART and
> >TMR0 in "chained segments" and it works fine.
>
> Just got back from 10 days (working unfortunately) in sunny Kourou, so
> catching up on discussions.
>
> I get the impression, Peter, that you are setting out to do exactly what I
> did using Olins development environment. You can see extern labels declared
> for interrupt handlers that were in other modules (the serial one is a
> rework of Fr. MacGhees code).

Not quite the same....

You have a ISR that checks the status bits and jumps out to the handler
code for each device.  To add a new device you have to add new code into
the ISR to check the appropriate status bits for the new device. My
technique has no similar code.  The handlers for devices are just linked
into one segment and just run one after another.  The main ISR is a stub
that saves the context and then jumps to the start of the chained
handlers.

Peter


2005\07\11@111345 by Alan B. Pearce

face picon face
>Alan B. Pearce wrote:
>>...
>I noticed some things you might want to look into:
...
>I've got a nicer way of handling this since you grabbed the
>snapshot this code was based on.  See the new DEFRAM macro.

Yeah, this is pretty old code now, from your original release, that I
managed to persuade you to send me.

>>        dbank   intr_led_reg
>>        bcf     intr_led_pin    ; show serial activity LED
>
>I assume you are using DBANK only since this is intended ...

>This is a problem since the LED code stomped on the bank. ...

You picked up a couple of errors I did not spot because they never gave me
trouble. Problem with posting ones old code as examples to others. (red face
VBG)

>Why DBANK and not DBANKIF?

Cannot remember. (more red face)

>>        nop                     ; nop for ICD to stop on
>
>Yeah, I wish the ICD didn't have that problem either.
>However, I've been surrounding these NOPs with IF DEBUG.
>I can set one symbol in the main include file to include
>or remove the ICD2 debug NOPs.

I know I did that elsewhere in the project. I also provided labels at
strategic points that I could use to set breakpoints. I do get the feeling
that they could have made the debug interface somewhat nicer without taking
up too much more real estate on the silicon.

2005\07\11@112017 by Alan B. Pearce

face picon face
>You have a ISR that checks the status bits and jumps out to
>the handler code for each device.  To add a new device you
>have to add new code into the ISR to check the appropriate
>status bits for the new device. My technique has no similar
>code.  The handlers for devices are just linked into one
>segment and just run one after another.  The main ISR is a
>stub that saves the context and then jumps to the start of
>the chained handlers.

How do you get the linker to chain the handlers? The only way I can see is
to hard code it into the modules.

How do you set the interrupt priority? Essentially it is done by deciding
the order in which the flags get tested, in your case this means setting the
order of chained code. I suspect that the example I gave would actually
reach the lowest priority in a shorter time, as it could potentially stop
bank switching code being required at the bit testing stage, for the jump to
the next test, which may become an advantage on a chip with some timing
critical apps.

2005\07\11@113650 by Peter Onion

flavicon
face
On Mon, 2005-07-11 at 16:20 +0100, Alan B. Pearce wrote:

> How do you get the linker to chain the handlers? The only way I can see is
> to hard code it into the modules.

The handlers are all placed in a code segment called "handlers".

> How do you set the interrupt priority? Essentially it is done by deciding
> the order in which the flags get tested, in your case this means setting the
> order of chained code.

To be honest I've not got anything were interrupt response times are
critical.  You can control the order by reordering the ".o" files in the
linker command.  I know this may break if MPLINK's behaviour changes
(but since I don't use MPLINK I'm not too worried about this).

Peter


2005\07\11@132347 by Jan-Erik Soderholm

face picon face
Alan B. Pearce wrote :

> I get the impression, Peter, that you are
setting out to do
> exactly what I did using Olins development
environment...

You might have to study this thread a bit more closely.

What Peter are doing is to (and this could have been
any code, not
just some ISRs) let the linker "link"
(or rather "chain") code in such
a way that when one
code just runs "out into the blue", another code
snipped
(from another source code file) just happens to have been
put
*physicaly* right after the first, so the PIC
can just flow from one to
the other without any
call/return code.

Peter thought this was clever,
I (and I think some
others) thought it was a bad idea for various
reasons.

Peter is using the fact that the linker (he is not
using
MPLINK) puts code in the same segment
from different .o files, in the
same order that the .o
files are specified on the linker command line.
And by this, "chaining" code hard together, head
to tail.

I don't know
anything about that other linker,
but it would surpice me a lot if this
fact actualy
is documented in that linkers documentation.

A supported
way of doing this, would be to
have the ISR's as source files and then
use the
INCLUDE directive to chain them together. One
could then be
sure that the code would be an
continous segment. Something like :

INCLUDE   ISR_TOP ;context save
INCLUDE   ISR_A
INCLUDE   ISR_B
INCLUDE   ISR_C
INCLUDE   ISR_D
INCLUDE   ISR_END ; context restore and
return

Any of the ISR_X could be commented out
without breaking the
(ISR) code.


Regards,
Jan-Erik.



2005\07\11@142754 by Peter Onion

flavicon
face
On Mon, 2005-07-11 at 19:23 +0200, Jan-Erik Soderholm wrote:

> Peter thought this was clever,

Peter still thinks it is clever.

> I (and I think some
> others) thought it was a bad idea for various
> reasons.

>From what I remember (and I've not been back and reread the whole thread
again) the main objection was that using only the documentation you
can't predict what MPLINK is going to do when it links code for the same
segment from different object files.  On the other hand I'm happy to
continue to use this technique because I looked at the gplink source
code to find out exactly what it's going to do.

"Use the source, Luke"

Peter


2005\07\12@051340 by Michael Rigby-Jones

picon face


{Quote hidden}

But of course no guarantees that this behaviour won't change in the future.  I have to agree with Jan-Erik on this, using an obscure/undocumented tooleset feature is nearly always a bad idea in the long run.

Regards

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2005\07\12@055712 by Peter Onion

flavicon
face
On Tue, 2005-07-12 at 10:13 +0100, Michael Rigby-Jones wrote:

> But of course no guarantees that this behaviour won't change in the future.  

It's not changing behaviour you guys have a problem with, it's unknown
behaviour in the case of MPLINK.  That's your problem, not mine.

Peter

2005\07\12@063308 by Michael Rigby-Jones

picon face


>-----Original Message-----
>From: piclist-bouncesspamKILLspammit.edu [.....piclist-bouncesKILLspamspam.....mit.edu]
>Sent: 12 July 2005 10:57
>To: Microcontroller discussion list - Public.
>Subject: RE: [PIC] Chaining ISRs with the linker
>
>
>On Tue, 2005-07-12 at 10:13 +0100, Michael Rigby-Jones wrote:
>
>> But of course no guarantees that this behaviour won't change in the
>> future.
>
>It's not changing behaviour you guys have a problem with, it's
>unknown behaviour in the case of MPLINK.  That's your problem,
>not mine.
>

I rarely use MPLINK so I don't have any problem with it whatsoever.  I am simply saying that relying on undocumented features/side effects of *any* toolset is dangerous.  i.e. unless the GPLINK docs say that object files will be guaranteed to be linked in the order specified on the command line (do they?), then the authors are under no obligation to keep this functionality in future revisions.

It also seems a little pointless when there are alternative methods of achieving the same objectives that are always guaranteed to work.

Regards

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2005\07\12@063910 by Chris Emerson

flavicon
face
On Tue, Jul 12, 2005 at 10:57:08AM +0100, Peter Onion wrote:
> On Tue, 2005-07-12 at 10:13 +0100, Michael Rigby-Jones wrote:
>
> > But of course no guarantees that this behaviour won't change in the
> > future.  
>
> It's not changing behaviour you guys have a problem with, it's unknown
> behaviour in the case of MPLINK.  That's your problem, not mine.

It's both.  Will you verify that the behaviour of gplink hasn't changed
every time you upgrade it?

If it's your project, and you're happy to check, or never upgrade
gplink, then there's no problem of course.

FWIW I think it's a good idea, but would feel uncomfortable relying on
this kind of undocumented behaviour.  (I use gplink.)

Chris

2005\07\12@070636 by Peter Onion

flavicon
face
On Tue, 2005-07-12 at 11:39 +0100, Chris Emerson wrote:

> It's both.  Will you verify that the behaviour of gplink hasn't changed
> every time you upgrade it?

Yes...  It's easy to do....

> If it's your project, and you're happy to check, or never upgrade
> gplink, then there's no problem of course.
>
> FWIW I think it's a good idea, but would feel uncomfortable relying on
> this kind of undocumented behaviour.  (I use gplink.)

I don't consider it to be undocumented... The behaviour is clear from
the source and there can be no more authoritative documentation than the
source code.  How often have you come across errors in manuals ?  

Peter

2005\07\12@072224 by Peter Onion

flavicon
face
On Tue, 2005-07-12 at 11:33 +0100, Michael Rigby-Jones wrote:

>
> I rarely use MPLINK so I don't have any problem with it whatsoever.  
> I am simply saying that relying on undocumented features/side effects
> of *any* toolset is dangerous.  i.e. unless the GPLINK docs say that
> object files will be guaranteed to be linked in the order specified
> on the command line (do they?), then the authors are under no
> obligation to keep this functionality in future revisions.

I take your point.  BUT looking at the way the code works, it's hard to
imagine why this would ever happen.

> It also seems a little pointless when there are alternative methods
> of achieving the same objectives that are always guaranteed to work.

Can we drop this thread now... Nothing anyone says is going to stop me
using my scheme.  If you don't like it I'm not forcing you to use it.  I
know the thinks that could go wrong but as far as I'm concerned it has
definite advantages over any other scheme I've seen proposed.  

YMMV.

Peter

2005\07\12@074927 by Jan-Erik Soderholm

face picon face
Peter Onion wrote :

> Can we drop this thread now...

Sure, but just
let me finish off... :-)

> Nothing anyone says is going to stop me
>
using my scheme...

Fine, but then I don't understand why you (in your
first post in this thread) asked :

> I realise there may be some
potential
> problems with this, but what does
> everyone think ?

Now,
when noone thinks that your method is
a good idea, you still decide to
use it.
So why ask in the first place ?

Anyway, good luck !

Best
Regards,
Jan-Erik.



2005\07\12@082745 by Peter Onion

flavicon
face
On Tue, 2005-07-12 at 13:49 +0200, Jan-Erik Soderholm wrote:

> Now,
> when noone thinks that your method is
> a good idea, you still decide to
> use it.

I'm using it because no one has actually come up with anything that I
consider to be reason enough not to use it.  It works, it does exactly
what I want it to do.

> So why ask in the first place ?

I won't ask next time.  I'll just keep my ideas to my self.

Peter


>

2005\07\12@092243 by olin piclist

face picon face
Peter Onion wrote:
> I don't consider it to be undocumented... The behaviour is clear from
> the source and there can be no more authoritative documentation than the
> source code.

The source code only tells you how it is, but not that there is an intent of
keeping it that way.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\07\12@092500 by Hazelwood Lyle

flavicon
face

>> Now,
>> when noone thinks that your method is
>> a good idea, you still decide to
>> use it.
>
>I'm using it because no one has actually come up with anything that I
>consider to be reason enough not to use it.  It works, it does exactly
>what I want it to do.
>
>> So why ask in the first place ?
>
>I won't ask next time.  I'll just keep my ideas to my self.
>

Well, you're going to do as you wish, but I learn a lot from discussions like this.
See, I don't know all the details of the linker, and I thought your question a good one.

Now that it's been discussed among people smarter than I, I've learned a bit about how the linker works, what we can be reasonably sure of, and what happens but maybe not reliably.

Whether or not you share your ideas is your choice, but don't be so quick to assume that nothing was gained from it. If we all agree on everything, there would be little to learn from sharing ideas, would there?

Thanks,
Lyle

2005\07\12@094142 by Alan B. Pearce

face picon face
>> It also seems a little pointless when there are alternative methods
>> of achieving the same objectives that are always guaranteed to work.
>
>Can we drop this thread now... Nothing anyone says is going to stop me
>using my scheme.

fair enough.

>If you don't like it I'm not forcing you to use it.  I know the thinks
>that could go wrong but as far as I'm concerned it has
>definite advantages over any other scheme I've seen proposed.

Unfortunately it has one possible disadvantage, and that is if you propose
to share your code with someone else. As others have pointed out at various
times (I don't think it happened directly in this thread) the "lowest common
denominator" is MPLAB, and if your method of doing things doesn't work in
MPLAB, then you may be hindering, rather than helping someone if you share
code with them, even in an "I did it this way" demonstration.

Following that you said in another email
>I'm using it because no one has actually come up with anything that I
>consider to be reason enough not to use it.  It works, it does exactly
>what I want it to do.

Not quite sure why you feel that your method has any real advantage over the
example I posted using Olin's environment. It seems to me that there is
still a "test flag and jump if not this interrupt" methodology, the
difference being my example had all the tests in one place, and jumped out
to a module if the interrupt occurred. The problem I see with yours is how
to link the return code stub at the end, without having some oddball
"interrupt return" module that you link at the end of interrupt blocks.

Fair enough, you feel that your method works, does the job how you want, and
you asked for comment on it. It does have bits in it that I (and possibly
others) consider less than desirable practice, but that is your lookout. I
get the feeling that you feel a bit hurt because the comments weren't
necessarily totally positive about your method. When I posted my code, I
thought you wanted an example of "how to" do it in a modularised manner.

2005\07\12@182800 by Jinx

face picon face
> If we all agree on everything, there would be little to learn from sharing
> ideas, would there?

Or as Patton said

"If everybody is thinking alike, then somebody isn't thinking"

=================================

Even if you think they're throwaway lines, quotations are wonderfully
condensed common sense. Remembering just a couple can change
the way you approach a problem

"Go out looking for one thing, and that's all you'll ever find"

"Every act of creation is first an act of destruction"

"Creativity is allowing oneself to make mistakes. Art is knowing
which ones to keep"

"Most people are more comfortable with old problems than with
new solutions"

"The test of a first-rate intelligence is the ability to hold two opposed
ideas in the mind at the same time, and still retain the ability to
function"

More... (looser matching)
- Last day of these posts
- In 2005 , 2006 only
- Today
- New search...