TMS320F28388D: Unable to set interrupt priority in CM causing assert fail in FreeRTOS

Part Number: TMS320F28388D
Other Parts Discussed in Thread: C2000WARE

Tool/software:

According to the FreeRTOS port documentation for the CM, any interrupts that use BIOS API functions must have a priority above (lower priority) than ucMaxSysCallPriority. 

I am trying to configure the UART ISR ot generate in interrupt on character Rx, and have the ISR read the char and put in a message queue (pretty basic stuff). The default interrupt priority must change, but the function "Interrupt_setPriority()" seems to have no effect, the assert fail still happens. No matter what I set the UART ISR priority to, it always remains at 0. 

I tried importing the example from C2000Ware (C2000Ware/kernel/FreeRTOS/C2000_F2838x_CM_CCS) but CCS gives me an error when I try to load it, saying that compiler 22.6.2.LTS is not installed, even though it is.

This should be pretty simple, how do I fix this?

I'm running CCS 12.8.1 in Ubuntu 24.04. The assert fail occurs at line 589 of port.c: configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );

Thank you.

  • Hi Kevin,

    Let me loop in the FreeRTOS expert to take a look at this question.

    Best Regards,

    Delaney

  • Hi Kevin, 

    The compiler error is due to a version mismatch in the projectspec, you can replace your C2000Ware/kernel/FreeRTOS/Demo/C2000_F2838x_CM_CCS/CCS folder with the one linked below. (This just updates the ARM compiler version, if there is still a mismatch, you can open up the projectspec file in a text editor and manually update to your installed version. This should be resolved in the next SDK release)

    5658.CCS.zip

    Regd. the issue with Interrupt_setPriority(), how are you passing the priority for the UART interrupt, and how are you reading it back?  I am not able to recreate your issue.

    Regards, 

    Arnav

  • Hi Arnav

    This is the code to initialize the port, called from main. This is largely taken from example code:

    //! @note: Must be >= configMAX_SYSCALL_INTERRUPT_PRIORITY!!
    static uint8_t UART_ISR_PRIORITY = ( 0xc0 );    // priority 6 (6 << 7)

    void DbgPortInit(uint32_t uartBase)
    {
        // configure uart
        UART_setConfig(uartBase, UART_CLK_FREQ, baudRate, 
            (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
        // Enable the UART0 interrupt on the processor (NVIC).
        UART_registerInterrupt(INT_UART0, UART_ISR);
        // set interrupt priority
        Interrupt_setPriority(INT_UART0, UART_ISR_PRIORITY);
        // FIFO enable
        UART_enableFIFO(uartBase);
        UART_setFIFOLevel(UART0_BASE, UART_FIFO_TX1_8, UART_FIFO_RX1_8);

        // Receive interrupt configuration
        UART_clearInterruptStatus(UART0_BASE, UART_INT_RX | UART_INT_RT);
        UART_enableInterrupt(UART0_BASE, UART_INT_RX);
    }

    This is the ISR, again, largely from example code:

    __interrupt void UART_ISR(void)
    {
        uint32_t isrStat = UART_getInterruptStatus(uartBase, UART_RAW_INT);
        char ch;
        BaseType_t higherPriorityTaskWoken;
        
        if ((isrStat & (uint32_t)UART_INT_RX) == (uint32_t)UART_INT_RX) {

            while (UART_isDataAvailable(uartBase)) {
                
                ch = (char)UART_readCharNonBlocking(uartBase);
                xQueueSendFromISR(portRxQueue, &ch, &higherPriorityTaskWoken);
            }
        }


        if ((isrStat & (uint32_t)UART_INT_TX) == (uint32_t)UART_INT_TX) {
            while (UART_isSpaceAvailable(uartBase)) {
                if (xQueueReceiveFromISR(portTxQueue, &ch, &higherPriorityTaskWoken)) {
                    UART_writeCharNonBlocking(uartBase, (uint8_t)ch);   
                }
                else {
                    // queue empty disable further tx interrupts
                    UART_disableInterrupt(uartBase, UART_INT_TX);
                }
            }
        }

        UART_clearInterruptStatus(uartBase, isrStat);
        portYIELD_FROM_ISR(higherPriorityTaskWoken);
    }

    When either xQueueSendFromISR() or xQueueReceiveFromISR() is called, the processor halts on the assert on line 589 or port.c:

                configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );

    In CCS, ucCurrentPriority is 0, as is the NVIC register.

    The code that you provided does not build. I get this linker error (which is what happened in my project when I bypassed the CCS project import):

     undefined                      first referenced                       
      symbol                            in file                            
     ---------                      ----------------                       
     vPortValidateInterruptPriority ./third_party/FreeRTOS/Source/queue.obj

    I added this to FreeRTOSConfig.h to get it to build:

    #include "assert.h"
    #define configASSERT(x) assert(x)

    But now I get the assert fail. But, if I just do

    #define configASSERT

    Then it builds, but the CPU hangs in the ISR.

  • Hi Kevin,

    In Interrupt_setPriority, you should directly pass the numerical priority value, which is 6. The function takes care of the shifting internally. After this change, you should see the interrupt priority change correctly.

    Regards,

    Arnav

  • That fixed the issue, thanks.