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.

Difference in performance between Timer object and hardware interrupt manager (Hwi object) ?

Other Parts Discussed in Thread: SYSBIOS

Hello,

I need to know the difference in performance (and also in overall if there is important restriction) between an Timer thread and a simple ISR handles by the hwi_dispatcher.

It seems to me both call a run to completion function.

My goal is only to achieve the best performance in this case.

 

Setup is:

TMS570

CCS 4.2

SYS/BIOS 6.31

 

Simon

  • Simon,

    For the TMS570, you can create a timer that has your function called directly (just like using Hwi_create()) or through a small stub, that does the following:

    Void Timer_periodicStub(UArg arg)

    {

        Timer_Object *obj = (Timer_Object *)arg;

        obj->accuTicks++;

        Timer_ackInterrupt(obj);

        obj->tickFxn(obj->arg);

    }

    This is specified by using the Hwi_Params parameters passed into Timer_create(), specifically the "type" field, which can be FIQ or IRQ, respectively. References:
    Since you have source code with SYS/BIOS, you can see the code for the TMS570 Timer module in the file
    <your-sysbios-install-dir>/packages/ti/sysbios/family/arm/tms570/Timer.c
    Mark

  • Yes that's true. I've just tested both approaches, i.e. a timer by Hwi thread and the other approch a function called directly by a user-defined timer.  The last one is still handled by the Hwi_dispatcher though. The overhead seems to be in the Hwi_dispatcher. I have an application with high frequencies interrupt (20Khz) and the difference in CPU load is about 1.5% lower with no thread approch (the approch you propose).

    But it's still to high for me. I'm searching an approch to bypass the Hwi_dispatcher only for my 20Khz interrupt ISR.

     

    I've found an interresting configuration in the CSS/XDC environnement:

     

     

    :

     It seems possible to call another dispatcher. I'm interrested to configure the FIQFunc field to custom dispatcher and leave the irqFunc as it is.

    My 20Hhz ISR has to have the absolute highest priority with no preamtion possible in my application.

    Do you have any suggestions or warning with this approach?

    Do you have a dispatcher suitable for this purpose?

     

    Simon

     

  • Simon,

    Did you try the Hwi_Type_FIQ option in the Hwi_Params when creating the Hwi?

    Mark

  • BIOS' FIQ interrupt support for R4 devices is more or less undocumented. Reviewing the associated C code is also pretty missleading.

    As Mark suggests, when you create the interrupt you can set the Hwi_Params.type field to Hwi_Type_FIQ which will result in your function being called directly, bypassing any internal dispatcher.

    Beware that because your interrupt is NOT dispatched, AND because FIQs are NOT masked by BIOS, your FIQ ISR will always pre-empt the background thread (even BIOS critical regions).

    Consequently your ISR function MUST NOT INTERACT WITH BIOS OBJECTS (ie no Semaphore_post() or similar calls).

    Also,  because your ISR is invoked directly (ie not dispatched), you must declare it using the 'interrupt' keyword to ensure that the interrupted thread's register context is preserved.

    Alan

  • Thanks.

    Could-you give-me an snippet using «ti.sysbios.family.arm.tms570.Hwi» that way and the #pragma stuff.

    It looks like «ti.sysbios.family.arm.tms570.Hwi» requires Hwi_create() with a callback function like

    Void (*FuncPtr)(UArg).

    But the
    #pragma INTERRUPT(FIQ)
    needs a function like
    Void (*FuncPtr)(void), no parameter.

    Simon
     

  • Since your FIQ ISR tunction will not be invoked through the dispatcher, it will not be passed an argument.

    However, Hwi_create() demands that the function have the right signature.

    To get around this, simply cast your function as a Hwi_FuncPtr:

     

    UInt fiqIsrCount = 0;

    #pragma INTERRUPT(myFiqIsr, FIQ);

    Void myFiqIsr()
    {

       fiqIsrCount++;

    }

    Int main()

    {

        Hwi_Params params;

        Hwi_Params_init(&params);
        params.type = Hwi_Type_FIQ;
        Hwi_create(2, (Hwi_FuncPtr)myFiqIsr, &params, NULL);
        Hwi_enableFIQ();
        BIOS_start();
        return(0);

    }

  • It builds ok but doesn't work in FIQ.

    I have experimented some little things tough: if I setup the whole thing using the GUI AND using the IRQ, it works.

    After, I have used IRQ again but using this code:

    Hwi_Params params;
    Hwi_Params_init(&params);

    params.type = Hwi_Type_IRQ;
    Hwi_create(10, (Hwi_FuncPtr)myDoInt20kHz, &params, NULL);
    Hwi_enableIRQ();


    #pragma INTERRUPT(IRQ)
    #pragma CODE_STATE(32)
    void myDoInt20kHz(void)
    {
        AcknowledgeHetHighLevelInterrupt();

     }

    But with no success again.

     

    With IRQ, is the framework automatically uses the Hwi_dispatcher ? In that case, it is required to use the pragma again?

    My goal is still to use the FIQ, I'm just trying here to go step by step.

    Simon



  • IRQ interrupts defined using Hwi_create() will be routed through the BIOS interrupt dispatcher.

    The function given to Hwi_create() in this case should be a normal C function which takes one UArg argument.

    Only when using Hwi_create() to define a FIQ interrupt should the func be defined using #pragma INTERRUPT(func, FIQ).