+91 9945200008     support@uttaracomputers.com
LOGIN     REGISTER    

Embedded control VIII - Audio 30, page 97 - static function to be invoked by dispatcher of interrupt

Answered
0
0

Hello Sir,

In the Host class you have mentioned about a static function to be invoked by “dispatcher of interrupt”.

As per the audio the purpose is to read the incoming byte on the COM port and put it in the buffer.

Is it called by the interrupt service routine host_intr()?

If yes, given that the buffer “buf” is a non-static member of the Host class, how can host_intr() access it?

Also can I send the exercise code across to you on email for getting it examined by you? I am able to compile the same.

Thanks and regards,

Shreesha

  • You must to post comments
Best Answer
1
0

A dispatcher of interrupt is the interrupt service function written in assembly language. The intr constructor establishes the address of the interrupt service function in the CPU interrupt table at the specified vector location.  The despatcher function gets invoked automatically by the CPU on receipt of a byte in the host port. The service function needs to read a byte from the COM port and invoke a C++ function.  That function cannot be non-static since the assembly language interrupt service function will not know how to push the (default) this pointer of the object. Hence the dispatcher can only call a static function ( that does not have the default this pointer as 1st parameter ).  If we were to declare a single Host object in our system (  like :    Host host ( &com1, 4, … ) ),  then the static function will pick up the correct member function with a code something like :  host.collect ( char x ).  If we were to declare multiple Host objects, then they must be linked to the corresponding vector numbers using an initialized global array  AND the static function should be invoked with the vector number as 1st parameter.  The function then can pickup the correct host object by searching for the vector number in the initialized global array and then invoke the collect function for the correct Host object.  Note that collect function ( like any other member function of Host ) is a non-static function and can access the data areas of the object.

  • svit19@gmail.com
    Thank you for the clarification Sir. Below is the Host class that I have written. I have another doubt. We have declared interrupt service routine is an extern “C” function. Does it call an assembly routine internally or do we write the assembly code inside the definition itself? class Host { ComPort* port; intr host_intr; buffer buf; interface iface; Host():host_intr(0,0) {} //illegalize public: Host(ComPort* p, int vec, void (*intr_service)(), cable_type ct, flow_control fc): host_intr(vec, intr_service), iface(ct, fc) { port = p; } uchar pick_char() { return buf.buf_read(); } static void collect(); //to be invoked by dispatcher of interrupt }; const int HOST_INTR_VEC = 4; const int COM1_PORT = 0x0200; extern “C” void host_service(); ComPort com1(COM1_PORT); Host host(&com1, HOST_INTR_VEC, host_service, cable_type::data_leads, flow_control::sw); void Host::collect() { if(!host.buf.full()) host.buf.buf_write(host.port->receive_byte()); }
  • svit19@gmail.com
    Please ignore the below answer. Instead of putting in comment section I put as answer by mistake.
  • You must to post comments
0
0

Thank you for the clarification Sir. Below is the Host class that I have written.

I have another doubt. We have declared interrupt service routine is an extern “C” function. Does it call an assembly routine internally or do we write the assembly code inside the definition itself?

class Host {
    ComPort* port;
    intr host_intr;
    buffer<BUF_SIZE> buf;
    interface iface;

    Host():host_intr(0,0) {} //illegalize

public:
    Host(ComPort* p, int vec, void (*intr_service)(), cable_type ct, flow_control fc):
        host_intr(vec, intr_service), iface(ct, fc) {
            port = p;
        }

    uchar pick_char() {
        return buf.buf_read();
    }

    static void collect(); //to be invoked by dispatcher of interrupt
};

const int HOST_INTR_VEC = 4;
const int COM1_PORT = 0x0200;
extern "C" void host_service(); 

ComPort com1(COM1_PORT);
Host host(&com1, HOST_INTR_VEC, host_service, cable_type::data_leads, flow_control::sw);

void Host::collect() {
    if(!host.buf.full()) 
        host.buf.buf_write(host.port->receive_byte());
}


  • You must to post comments
Showing 2 results
Your Answer

Please first to submit.