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.

DSP BIOS Hwi post Swi and Task

I am using CCS v5 with Bios_5_41_10_36 on target C6748.

I have one uart_hwi, one proc_Swi and one proc_Task, they work in the following way.

uart _hwi{

SWI_or(&Proc_Swi, 1);

}

Proc_Swi{

//some other algo here

SEM_post(Proc_Task)

}

Proc_Task{

                   while(1){

                                  Sem_pend(Proc_Task, SYS_FOREVER)

                                  My_Algo();

                     }

}

When My_Algo() is simple and takes shorter time, the code works fine i.e Uart receives start command from terminal, the algo start processing and display result on terminal.

But when My_Algo() is more complicated and takes longer time, looks like sometimes the Uart_Hwi does not response to command. The Uart_Hwi seems restart. 

I hope I explained it clearly, can anyone help me on this issue?

  • Hi Jian,

    I assume My_Algo() does not explicitly disable HWI in the code.

    In the case, one possible reason is, the code is highly optimized and there are less chance to be interrupted by delay slots of a branch, etc.

    Could you refer the section 2.12 Interrupt Flexibility Options (--interrupt_threshold Option) of SPRU187U (http://www.ti.com/lit/ug/spru187u/spru187u.pdf)?  If the issue is resolved by the option --interrupt_threshold=100 etc, it is highly likely this is the reason.

    If the above does not resolve, could you please clarify

    • Interrupt rate of uart_hwi().  In other words, how often the interrupt occurs in a second
    • Which version of compiler you are using
    • All compiler options you applied

    Regards,
    Atsushi

  • Hi Atsushi:

    Thanks for your rapid reply.

    My_algo() does not disable Hwi during run-time, it takes about 2M cycles to complete. I tried to specify the --interrupt_threshold = 0/100/2000000/3000000.

    Unfortunately, samething happen again. The Uart_Hwi was not disabled, looks like it is restarted .

    The Uart_Hwi interrupt whenever it receives a char from an external terminal, the interrup rates really depends on how fast u send a char from the terminal.

    The compiler version is Code-Gen Tool V7.2.3, the compilation option is dafault for debug mode (no opt).

     

    Regards,

    Jian

  • Jian,

    Thank you for explanation of the background and the additional information.  I understood that you did not see improvement unfortunately by the --interrupt_threshold option.

    I also understood the compiler version was 7.2.3.  To check the compiler options, may I ask you one of the followings?

    • Please find the attached screen capture.  I think you can see the actual options in the window even if you didn't explicitly specify options.
    • Another way is, you can obtain an intermediate assembly language source file by applying -k option to the compiler.  For example if the C source code is foo.c, we will get foo.asm somewhere in the project directory (or folder).  In the very begging of the assembly code, we see the following lines (an example).  It will help us to understand how compiler was processing your code.

    ;******************************************************************************
    ;* TMS320C6x C/C++ Codegen                                          PC v7.4.1 *
    ;* Date/Time created: Tue Oct 16 14:17:35 2012                                *
    ;******************************************************************************
        .compiler_opts --abi=eabi --c64p_l1d_workaround=off --endian=little --hll_source=on --long_precision_bits=32 --mem_model:code=near --mem_model:const=data --mem_model:data=far_aggregates --object_format=elf --silicon_version=6600 --symdebug:dwarf --symdebug:dwarf_version=3

    ;******************************************************************************
    ;* GLOBAL FILE PARAMETERS                                                     *
    ;*                                                                            *
    ;*   Architecture      : TMS320C66xx                                          *
    ;*   Optimization      : Enabled at level 2                                   *
    ;*   Optimizing for    : Speed                                                *
    ;*                       Based on options: -o2, no -ms                        *
    ;*   Endian            : Little                                               *
    ;*   Interrupt Thrshld : Disabled                                             *
    ;*   Data Access Model : Far Aggregate Data                                   *
    ;*   Pipelining        : Enabled                                              *
    ;*   Speculate Loads   : Enabled with threshold = 0                           *
    ;*   Memory Aliases    : Presume are aliases (pessimistic)                    *
    ;*   Debug Info        : DWARF Debug                                          *
    ;*                                                                            *
    ;******************************************************************************

    We are afraid but could you check the compiler options once again?

    Regards,
    Atsushi


  • Hi Atsushi:

    Here I managed to get it.

    ;******************************************************************************
    ;* TMS320C6x C/C++ Codegen                                          PC v7.2.3 *
    ;* Date/Time created: Wed Oct 24 16:57:08 2012                                *
    ;******************************************************************************
     .compiler_opts --abi=coffabi --c64p_l1d_workaround=off --endian=little --hll_source=on --long_precision_bits=40 --mem_model:code=near --mem_model:const=data --mem_model:data=far_aggregates --object_format=coff --silicon_version=6740 --symdebug:dwarf

    ;******************************************************************************
    ;* GLOBAL FILE PARAMETERS                                                     *
    ;*                                                                            *
    ;*   Architecture      : TMS320C674x                                          *
    ;*   Optimization      : Disabled                                             *
    ;*   Optimizing for    : Compile time, Ease of Development                    *
    ;*                                  Based on options: no -o, no -ms                      *
    ;*   Endian            :      Little                                               *
    ;*   Interrupt Thrshld : 3000000                                              *
    ;*   Data Access Model : Far Aggregate Data                                   *
    ;*   Pipelining        : Disabled                                             *
    ;*   Memory Aliases    : Presume are aliases (pessimistic)                    *
    ;*   Debug Info        : DWARF Debug                                          *
    ;*                                                                            *
    ;******************************************************************************

  • Jian,

    Can you please describe what you mean when you say the Uart_Hwi *restarts*?

    Even if the interrupt was disabled from being serviced during the algorithm, I’d expect that interrupt request to be latched and serviced once the algorithm completes.  Can you describe more about the configuration of the UART (e.g., is there internal buffering used) and its interrupt (e.g., latched versus level-triggered)?

    Also, are you using the HWI dispatcher for this interrupt?

    Thanks,
    Scott

  • Jian,

    Thank you for the information.  It seems compiler options are appropriate enough for C674x.

    In addition to the Scott's helpful suggestion, my recommendation is, you can clarify what is happening in your code by the following timing diagram (an example).  It is a common method to analyze this kind of problem.  (Please magnify the diagram by clicking.)

    Following pseudo code is to show how to use TSCL and IRP registers.  I did not show here but my recommendation is to store the register variables in a circular buffer to analyze them later.

    #include <c6x.h>

    unsigned int last_tscl_hwi;
    unsigned int last_tscl_swi;
    unsigned int last_irp;

    uart _hwi{
        last_irp = IRP;
        last_tscl_hwi = TSCL;
        SWI_or(&Proc_Swi, 1);
    }

    Proc_Swi{
        last_tscl_swi = TSCL;
        //some other algo here
        SEM_post(Proc_Task)
    }

    Proc_Task{
        while(1){
            Sem_pend(Proc_Task, SYS_FOREVER)
            My_Algo();
       }
    }

    int main(){
        TSCL = 0;  // Initialize TSCL (time stamp counter)

        // ...
    }

    The fact is TI CCS provides more sophisticated tool 'MCSA' (Multicore System Analyzer) but it requires additional know-how so I recommend the above TSCL and IRP to keep the problem simple.

    Regards,
    Atsushi

  • After I added Hwi_disable and Hwi_restore just before and after My_algo(). The system seems working fine, but I do not understand why.

    Atsushi, thanks for your reply. I tried your suggestion, looks sometimes the uart_hwi triggered during the proc_task running.

    Scott, I have the hwi_init function in main(),

    hwi_init{

                 //clear pending cpu interrupt

                //Set NMIE

                //Set GIE

               //enable Hwi 04

             //set uart interrupt (line_error|Tx|Rx)

    }

    I have the uart_Hwi_Isr(), which response to the 3 types of interrupt events, I first transmit a few chars to external terminal, then the Tx interrupt disabled.

    The Isr will listen to the Rx_data_ready and line_error event only afterwards.

    I suspect not only the Uart_hwi restart, the code entered the main() again.

  • I use Hwi(04) dispatcher with interrupt mask as 'all' .

  • Jian,

    If you are calling hwi_init() from main() you should not set NMIE or GIE in that function.  Those will be enabled automatically by DSP/BIOS, later in the startup process when it is appropriate. 

    Clearing any pending interrupt from the UART peripheral, configuring and enabling the interrupts at the UART peripheral-level are OK, but you must not modify NMIE and GIE in main(). 

    Can you remove those enables and see if that resolves the issue?

    Thanks,
    Scott

  • Hi Scott:

    I removed the GIE and NMIE set in main(), it makes no differnece. I understand the bios will set these two registers before and after the main().

    But I found after I add the Hwi_disable and Hwi_restore before and after the My_algo(), it works as expected. I think we should use the hwi_disable and hwi_restore to protect the critical section and make sure it will never be interrupted/preempted by high-priority thread(Hwi/Swi), am I right to say that?

  • Jian,

    The main concern with doing the HWI_disable/HWI_restore during the whole algorithm execution is the latency that it will cause in being able to service interrupts quickly, and the corresponding delay that will be caused for preemption by higher priority TSK and SWI.  I expect blocking the Uart_Hwi and Proc_Swi may not be an issue (if they are only there to start MyAlgo), but other HWI, SWI, and TSK in the system will also be locked, and that may cause other issues.  Basically… you’ll be locking out the CPU from doing ANYTHING else during that algorithm, which you say may take a long time to run.

    Is MyAlgo() written entirely in C?  If so, then the code generated by the compiler *should* protect critical regions (like software pipelines) from interrupts.  So, I think the usage of HWI_disable/HWI_restore is just masking some inherent problem in the application, because I don’t think this should be necessary.

    If portions of MyAlgo() are written in assembly, then it would be good to do an analysis of that code and add interrupt disable/restore to protect vulnerable regions.  If these regions are small, then it may significantly reduce the impact on interrupt latency, versus HWI_disable/HWI_restore around the whole algorithm.

    Scott

  • Hi Scott:

    My_algo() is written in C, no assembly. It takes 2M cycles to complete and looks that it is not protected from preemption.  The Uart_hwi keep preempting it and I am confused.