Code Gen problem calling functions through pointers.

David Querbach querbach@realtime.bc.ca
Fri Jun 11 21:07:00 GMT 1999


> Is it *ENTIRELY* in C++?  Is it pre-emptive?  If so, how do you do
> context save and restore operations in C++ in a machine transparent
> manner? 

Perhaps I should have said "C/C++".  We use setjmp/longjmp for context
switching, and have added a function we call "initjmp" to prime a jmpbuf
when first creating a task.  We of course use a few classic C functions such
as strcpy, strlen, and the transcendental math functions.

Yes, it is fully pre-emptive, with a sub-100 usec interrupt latency on
reasonable (16 and 32-bit) micros.

Only the system startup, first-level interrupt handler, and global interrupt
masking are in assembler.  The system startup consists of a few hundred
lines to initialize the .bss and .data sections, call the static
constructors, and call main().

The first-level interrupt handler varies in its implementation according to
the way interrupts are handled on a given processor, but it always looks in
a static table of interrupt handler objects:

// isr.h

  // base class of all interrupt handlers

  class Isr
  {
  public:
    enum Name			// interrupt sources
    {
      inSci,			   // serial port
      inTimer,			   // system timer
      ...			   // lots more...
      inNumNames		   // number of sources
    };

    Isr				// register handler
    (
      Name name			   // interrupt to handle
    );

    ~Isr();			// de-register handler

  private:
    virtual void handler() = 0;	// handle interrupt

    Isr* prev;			// previous handler
  };


// isr.cpp

  static Isr* isrs[Isr::inNumNames];      // table of Isr objects


The first level interrupt handler's job is to look up the Isr-derived object
for the current interrupt, call its virtual handler() function, then return
from interrupt.

Global interrupt masking support consists of a few preprocessor macros which
expand into inline interrupt enable/disable assembler instructions.

Other than the above, the only time we need assembler is when we need to
handle wierd address maps or when we need the ultimate in speed.  We can
usually port our entire system to a new processor as fast as we can get
control of the hardware and write a boot loader.

Regards,

David Querbach
Real-Time Systems Inc.

_______________________________________________
New CrossGCC FAQ: http://www.objsw.com/CrossGCC
_______________________________________________
To remove yourself from the crossgcc list, send
mail to crossgcc-request@cygnus.com with the
text 'unsubscribe' (without the quotes) in the
body of the message.


More information about the crossgcc mailing list