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.

call of Api Timer_start of 28x famliy will change IER to the unexpected status

Other Parts Discussed in Thread: SYSBIOS

I am working on evaluating the SysBios 6.32.05.54 with CCS5.1 on 28335 PGF ControlCard.

I created a Clock which uses INT13 , and a Timer which use PIE 38.

The Clock is an auto start one, but the Timer was set to be started by User.

I am trying to start the timer in my task.

But what I found is that call of Api Timer_start  will cause the Clock tick to stop.

By using Log_info1to output the IER status, I found that in my case,

except IER1, PIE 38, the Timer_start  will disable all the non-zero latency interrupt bit.

Should it be a bug ?

B&R
tony 

  • Tony,

    Have you protected your code from re-entrancy issues?

    To protect against re-entrancy, surround the start/stop invocations with Hwi_disable() and Hwi_restore()calls:

     // disable interrupts if an interrupt could lead to // another call to Timer_start(). key = Hwi_disable(); Timer_stop(); ... Timer_start(); Hwi_restore(key);
    
    Steve
  • Hi Steve,

    I found that the problem was due to the task stack overflow, and after fix it every thing works fine.

    Thanks for taking your time to look at my issue!

    Tony

  • Hi Steve,

    I found that the problem was not really fixed, why it seems ok before is because I set the Hwi zeroLatencyMask to 0 by accident.

    When I recover the  Hwi zeroLatencyMask to 0x18, the problem shows up again.

    To investigate this problem further, I write the following code (the similar process will be executed in Timer_statr also):

        Log_info1("Initial IER is 0x%x\n ",IER);
    UInt hwiKey = Hwi_disable();
    UInt ierKey = Hwi_enableIER(1);

    Hwi_restoreIER(ierKey);
    Hwi_restore(hwiKey);
    Log_info1("IER is 0x%x\n ",IER);
    When the  Hwi zeroLatencyMask is set to 0, the output was correct as below:
    Initial IER is 0x303f
    IER is 0x303f
    When the Hwi zeroLatencyMask is set to 0x18,the output was not correct as below:
    Initial IER is 0x303f
    IER is 0x18
    By debuging into the generated source pie_p28FP.c, I found that the function
    ti_sysbios_family_c28_Hwi_restoreIER__E's implementation will be generated differently according to the zeroLatencyMask.
    When zeroLatencyMask was not 0,  the problem will be triggered by the following code 's implementation. 
    
    
    Bits16 ti_sysbios_family_c28_Hwi_restoreIER__E(Bits16 mask)
    {
    Bits16 nonZeroIER, oldIER;
    UInt intmKey;

    nonZeroIER = mask & 0xffe7;

    intmKey = __disable_interrupts();

    ti_sysbios_family_c28_Hwi_Module__state__V.shadowIER = nonZeroIER;
    oldIER = IER;
    IER = mask;

    __restore_interrupts(intmKey);

    return (oldIER);
    }
    
    
    Could you have a look and try to confirm this problem, and show me some solution?
    BTW: Even setting Hwi zeroLatencyMask  to 0, the zero latency Hwi response is still ok !
  • Tony,

    tony chen said:
    When the  Hwi zeroLatencyMask is set to 0, the output was correct as below:
    Initial IER is 0x303f
    IER is 0x303f

    When the Hwi zeroLatencyMask is set to 0x18,the output was not correct as below:
    Initial IER is 0x303f
    IER is 0x18

    I believe this behavior is expected.  According to the C28x Hwi module API documentation for the config Hwi_zeroLatencyIERMask:

    "Enabling zero latency mode (specifying a non-zero zeroLatencyIERMask) ... The disable call will copy the zero latency IER mask (supplied here) into the IER register."

    So, since you have set the the zero latency mask to a non-zero value of 0x18, this is the value that  is then stored into 'hwiKey' in your example code

    UInt hwiKey = Hwi_disable();

    Then, when you restore interrupts:

    Hwi_restore(hwiKey);

    that's based on hwiKey (0x18) and so the IER will reflect that.

    Steve

  • Hi Steve,

    First from the API's definition, when we use 

    Hwi_disable()&Hwi_restore(hwiKey),
    Hwi_enableIER(1)&  Hwi_restoreIER(ierKey) in pair, if there is not any other Hwi operation in between,
    After execution of the restore API,  the IER status should be restored to the state before we do disable/enable operation, either zero latency interrupt mask set or not.
    
    
    Second from the generated C28x's implementation with zero latency interrupt mask set,
    , zero latency interrupt mask was used to avoid the BIOS API's impact to the zero latency interrupt IER bit,
    since they are out of BIOS 's manipulation boundary.
    
    
    The problem is that the above special implementation has some bug in ti_sysbios_family_c28_Hwi_restoreIER__E
    , which caused the ti_sysbios_family_c28_Hwi_Module__state__V.shadowIER to be set incorrectlly, so the later call to the corresponding restore API
    can not recover the IER bit to its original state.
    
    
    Here below is the code I copied from the generated xxx_p28FP.c for your reference.
    
    
    
    
    
    
    /*
    * ======== ZERO LATENCY IMPLEMENTATION ========
    */

    /*
    * ======== Hwi_startup ========
    */
    Void ti_sysbios_family_c28_Hwi_startup__E()
    {
    ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable = TRUE;
    __enable_interrupts();
    }

    /*
    * ======== Hwi_disable ========
    */
    UInt ti_sysbios_family_c28_Hwi_disable__E()
    {
    UInt key;
    UInt intmKey;

    if (ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable == FALSE) {
    key = 0;
    }
    else {
    key = 1;
    ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable = FALSE;

    intmKey = __disable_interrupts();
    IER &= 0x18;
    __restore_interrupts(intmKey);
    }

    return(key);
    }

    /*
    * ======== Hwi_enable ========
    */
    UInt ti_sysbios_family_c28_Hwi_enable__E()
    {
    UInt key;
    UInt intmKey;

    if (ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable == TRUE) {
    key = 1;
    }
    else {
    key = 0;
    ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable = TRUE;

    intmKey = __disable_interrupts();
    IER |= ti_sysbios_family_c28_Hwi_Module__state__V.shadowIER;
    __restore_interrupts(intmKey);

    }

    return(key);
    }

    /*
    * ======== Hwi_restore ========
    */
    Void ti_sysbios_family_c28_Hwi_restore__E(UInt key)
    {
    UInt intmKey;

    if (key == 1 && ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable == 0) {
    ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable = TRUE;
    intmKey = __disable_interrupts();
    IER |= ti_sysbios_family_c28_Hwi_Module__state__V.shadowIER;
    __restore_interrupts(intmKey);
    }
    else if (key == 0 && ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable == 1) {
    ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable = 0;
    intmKey = __disable_interrupts();
    IER &= 0x18;
    __restore_interrupts(intmKey);
    }
    }

    /*
    * ======== Hwi_disableIER ========
    */
    Bits16 ti_sysbios_family_c28_Hwi_disableIER__E(Bits16 mask)
    {
    Bits16 nonZeroIER, oldIER;
    UInt intmKey;

    nonZeroIER = mask & 0xffe7;

    intmKey = __disable_interrupts();

    ti_sysbios_family_c28_Hwi_Module__state__V.shadowIER &= ~nonZeroIER;
    oldIER = IER;
    IER &= ~mask;

    __restore_interrupts(intmKey);

    return (oldIER);
    }

    /*
    * ======== Hwi_enableIER ========
    */
    Bits16 ti_sysbios_family_c28_Hwi_enableIER__E(Bits16 mask)
    {
    Bits16 nonZeroIER, oldIER;
    UInt intmKey;

    nonZeroIER = mask & 0xffe7;

    intmKey = __disable_interrupts();

    ti_sysbios_family_c28_Hwi_Module__state__V.shadowIER |= nonZeroIER;
    oldIER = IER;
    IER |= mask;

    __restore_interrupts(intmKey);

    return (oldIER);
    }

    /*
    * ======== Hwi_restoreIER ========
    */
    Bits16 ti_sysbios_family_c28_Hwi_restoreIER__E(Bits16 mask)
    {
    Bits16 nonZeroIER, oldIER;
    UInt intmKey;

    nonZeroIER = mask & 0xffe7;

    intmKey = __disable_interrupts();

    ti_sysbios_family_c28_Hwi_Module__state__V.shadowIER = nonZeroIER;
    oldIER = IER;
    IER = mask;

    __restore_interrupts(intmKey);

    return (oldIER);
    }
    
    
    
    
    
    
     
    
    
    
    
  • Hi Steve,

    First from the API definition, when we use the following functions:

    Hwi_disable()&Hwi_restore(hwiKey)
    Hwi_enableIER(1)&Hwi_restoreIER(ierKey) by pair, if there is no any other Hwi operation in between,
    After the execution of the restore function, the IER status should be recovered to the state before the disable/enable function was called.
    
    
    Second from the generated xxx_p28FP.c implementation,  when the zero latency interrupt mask was set,  it is used to avoid the zero latency interrupt IER bit
    to be impacted by the BIOS Hwi API, since the zero latency interrupt was out of BIOS manipulation boundary.
    
    
    The problem is that ti_sysbios_family_c28_Hwi_restoreIER__E's implementation has some bug, which cause the restore operation set the 
     ti_sysbios_family_c28_Hwi_Module__state__V.shadowIER incorrectly, and the IER status was not recovered as expected.

    Here below attached are the related implementation generated by  SysBios 6.32.05.54 with CCS5.1 on 28335 PGF ControlCard. (zero latency interrupt mask set to 0x18)

    /*
    * ======== ZERO LATENCY IMPLEMENTATION ========
    */

    /*
    * ======== Hwi_disable ========
    */
    UInt ti_sysbios_family_c28_Hwi_disable__E()
    {
    UInt key;
    UInt intmKey;

    if (ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable == FALSE) {
    key = 0;
    }
    else {
    key = 1;
    ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable = FALSE;

    intmKey = __disable_interrupts();
    IER &= 0x18;
    __restore_interrupts(intmKey);
    }

    return(key);
    }

    /*
    * ======== Hwi_enable ========
    */
    UInt ti_sysbios_family_c28_Hwi_enable__E()
    {
    UInt key;
    UInt intmKey;

    if (ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable == TRUE) {
    key = 1;
    }
    else {
    key = 0;
    ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable = TRUE;

    intmKey = __disable_interrupts();
    IER |= ti_sysbios_family_c28_Hwi_Module__state__V.shadowIER;
    __restore_interrupts(intmKey);

    }

    return(key);
    }

    /*
    * ======== Hwi_restore ========
    */
    Void ti_sysbios_family_c28_Hwi_restore__E(UInt key)
    {
    UInt intmKey;

    if (key == 1 && ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable == 0) {
    ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable = TRUE;
    intmKey = __disable_interrupts();
    IER |= ti_sysbios_family_c28_Hwi_Module__state__V.shadowIER;
    __restore_interrupts(intmKey);
    }
    else if (key == 0 && ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable == 1) {
    ti_sysbios_family_c28_Hwi_Module__state__V.globalEnable = 0;
    intmKey = __disable_interrupts();
    IER &= 0x18;
    __restore_interrupts(intmKey);
    }
    }

    /*
    * ======== Hwi_disableIER ========
    */
    Bits16 ti_sysbios_family_c28_Hwi_disableIER__E(Bits16 mask)
    {
    Bits16 nonZeroIER, oldIER;
    UInt intmKey;

    nonZeroIER = mask & 0xffe7;

    intmKey = __disable_interrupts();

    ti_sysbios_family_c28_Hwi_Module__state__V.shadowIER &= ~nonZeroIER;
    oldIER = IER;
    IER &= ~mask;

    __restore_interrupts(intmKey);

    return (oldIER);
    }

    /*
    * ======== Hwi_enableIER ========
    */
    Bits16 ti_sysbios_family_c28_Hwi_enableIER__E(Bits16 mask)
    {
    Bits16 nonZeroIER, oldIER;
    UInt intmKey;

    nonZeroIER = mask & 0xffe7;

    intmKey = __disable_interrupts();

    ti_sysbios_family_c28_Hwi_Module__state__V.shadowIER |= nonZeroIER;
    oldIER = IER;
    IER |= mask;

    __restore_interrupts(intmKey);

    return (oldIER);
    }

    /*
    * ======== Hwi_restoreIER ========
    */
    Bits16 ti_sysbios_family_c28_Hwi_restoreIER__E(Bits16 mask)
    {
    Bits16 nonZeroIER, oldIER;
    UInt intmKey;

    nonZeroIER = mask & 0xffe7;

    intmKey = __disable_interrupts();

    ti_sysbios_family_c28_Hwi_Module__state__V.shadowIER = nonZeroIER;
    oldIER = IER;
    IER = mask;

    __restore_interrupts(intmKey);

    return (oldIER);
    }

  • Why my reply can not be post immediately ?

  • Tony,

    There was some maintenance happening in the forums around the time you made your post.  That's probably why it was not updating right away.

    I've been digging into this issue some more and I think you are right, there is a problem here.

    We are going to continue to work here to get this resolved and in the meantime, I have filed a bug report for this to ensure that it's tracked:

    SDOCM00091671 C28x shadow IER computation incorrect

    Steve