This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Setting a semaphore in an ISR

Other Parts Discussed in Thread: SYSBIOS

Hello,

I am trying to use a hardware interrupt with SYS/BIOS using a c6678 EVM. I would like this to work as follows:

1) ISR sets a semaphore using Semaphore_post(mySem); i.e. ISR is :

Uint32 irqCount;

interrupt void My_Isr()

{

   Semaphore_post(mySem);

}

2) SYS/BIOS task waits (sleeps) pending the interrupt firing. So in the SYS/BIOS task use:

Semaphore_pend(mySem,BIOS_WAIT_FOREVER);

This works for a limited amount of time, and then exits with a SYS/BIOS stack error.

 

I notice in the example SRIO_LoopbackDioIsrexampleproject, supplied with with pdk_C6678_1_0_0_14, a polliing method is used instead of the semaphore suggested above, i.e. the ISR sets a global srioLsuIsrServiced and the thread polls to see if this has been set:

while((! srioLsuIsrServiced) && ((TSCL - startTime) < SRIO_DIO_LSU_ISR_TIMEOUT));

This is not useful for our application, because it means CPU cycles are used whilst waiting for the interrupt. 

Is it possible to use a Semaphore_post() in an ISR without getting stack errors from SYS/BIOS? If so please provide an example.

Thnaks in advance

Simon

  • Hi Simon,

    Are you getting a stack overflow error?  If so, have you considered increasing the size of your Task stack? 

    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var taskParams = new Task.Params();
    taskParams.stackSize = 4096;
    Task.create('&myTsk', taskParams);

    FYI, you can use the ROV tool in CCS (tools --> ROV) to monitor the peak Task stack usage.

    Regards,

    Shreyas

  • simon64 said:

    interrupt void My_Isr()

    {

       Semaphore_post(mySem);

    }

    Your stack overflow is most likely caused by the fact that you have an ISR declared with the interrupt keyword.  This is a no-no in SYS/BIOS.

    You need to eliminate the "interrupt" keyword, and configure your ISR to be handled by the SYS/BIOS Hwi dispatcher.

    Regards,

    - Rob

     

  • Rob,

    Thanks for the reply - please can you give a reference on using the ISR without the interrupt keyword and instead handling it by the SYS/BIOS Hwi dispatcher?

    Simon

  • Simon,

    I'll jump in here for Rob.

    See section 3.3 in the Bios_User_Guide.pdf for more detail information on the Hwi Module.  This can be found in your BIOS installation.

    You can also check out the cdoc documentation for SYSBIOS.  This might even give an example of this.

    In general, you create a Hwi object and you specify what the isr function is.  The 'isrFunction' could be any 'C' function declared with Void.

      Hwi_create(id, isrFunction, &hwiParams, &eb);

    Judah

  •  

     

     

     

  • Judah,

    Thanks for posting the link. Using CSL I register the interrupt, for the SRIO Doorbell, like this:

    vectId = CSL_INTC_VECTID_5;

    hIntcRIO0 = CSL_intcOpen(&intcObjRIO0, 20, &vectId, NULL);

    CSL_intcHookIsr(vectId, Srio_Isr);

    where Srio_isr() is the Interrupt Service Routine.

    For SYS/BIOS, the interface is different, i.e. it uses:

    Hwi_create(intNum, Hwi_FuncPtr, Hwi_Params, Error_block);

    How do I associate the IRQ with the SRIO doorbell interrupt on a c6678 device? A reference to a table of interrupt numbers for the device might be useful. Also, an example of using this mechanism with say a timer interrupt would also be useful

    Thanks,

    Simon

     

     

     

  • A quick addition to this : the number '20' passed to CSL_intcOpen(...) comes from table 7-38 in http://www.ti.com/lit/ds/sprs691b/sprs691b.pdf

    However if pass 20 as the intNum to Hwi_create(...) I get a message from SYS/BIOS telling me it can't create the interrupt.

     

    Any help on this is greatly appreciated!

     

    Simon

  • Simon,

    The '20' you specified is the 'eventId' of the Hwi params structure.  On other devices this is also known as the GEM event map.  On the C66xx they call it the "System event map" which I think is a bad name.

    The 'intNum' is the hardware interrect vector.  There are only 12 mappable interrupt vectors (4-15) on the C66xx. 

    Bottom line is specify one of the 12 available vectors for 'intNum' and specify 20 as the params.eventId to the Hwi_create() API.

    Judah