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.

LAUNCHXL-F28P65X: FreeRTOS Implementation in 65x

Part Number: LAUNCHXL-F28P65X
Other Parts Discussed in Thread: SYSCONFIG, C2000WARE

Tool/software:

Hi everyone,

I am trying to implement FreeRTOS for my bare metal code . I used the example code of FreeRTOS for F28P65x and modified it for my application . The task functions are executing perfectly indicating my FreeRTOS implementation is fine , but my ISR's are no longer executing . In the main body of the example code , DINT and IER, IFR where set to 0x0000 . But i re enabled the global and real time interrupts after initializing the board and rest. What exactly is stopping my ISR from executing , does FreeRTOS have a different way of handling peripheral interrupts . Can someone send a more detailed documentation on FreeRTOS. I went through most of the available documentations but i am not sure what is causing my issue.

Thank you in advance

Ashwin Bhaskar A.

  • Hi Ashwin,

    FreeRTOS does not handle the hardware peripheral interrupts, they should occur as normal. Are you disabling interrupts / entering critical sections anywhere in your FreeRTOS application? Also, which peripheral interrupts are you using, and to clarify, these interrupts work as expected without FreeRTOS?

    If you are able to attach your sample code, that would also help speed up the debug.

    Thanks,

    Arnav

  • Hi Arnav,

    I haven't disabled interrupts or entered any critical section as of yet . I implemented FreeRTOS to see if it works with my SCI interrupts. 

    I am attaching the code 

    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "FreeRTOS.h"
    #include "board.h"
    #include "c2000_freertos.h"
    #include "stdio.h"
    //
    //User Defines
    //
    
    #define BUFFER_SIZE 10
    #define FIFO_LEVEL 1
    
    //
    //Function prototypes
    //
    void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName);
    void vApplicationMallocFailedHook(void);
    void error(void);
    //
    //Task functions
    //
    void gnss_task(void *);
    void gsm_task(void *);
    
    //
    //ISR functions
    //
    void INT_SCIX_RX_ISR(void);
    void INT_SCIY_RX_ISR(void);
    void INT_SCIX_TX_ISR(void);
    void INT_SCIY_TX_ISR(void);
    //
    //global variables
    //
    char NMEA_DATA[BUFFER_SIZE] = "XXXXXXXXX";
    char RTCM[BUFFER_SIZE] = "YYYYYYYYY";
    
    volatile uint16_t scitxBcount = 0;
    volatile uint16_t scirxBcount = 0;
    volatile uint16_t scitxAcount = 0;
    volatile uint16_t scirxAcount = 0;
    
    volatile uint16_t currNMEAptr = 0; //nmea buffer pointer
    volatile uint16_t currRTCMptr = 0; //rtcm buffer pointer
    volatile uint32_t intstat = 0;
    volatile uint16_t flag = 0;
    
    //
    //ISR
    //
    
    /***********************************************************************/
    __interrupt void INT_SCIX_RX_ISR(void){  //NMEA RECIEVE DATA ISR
        //RX ERROR HANDLING, NEED TO CHANGE ACCORDING TO APPLICATION REQUIREMENT
            uint32_t rxintstat = SCI_getInterruptStatus(SCIX_BASE);
            switch(rxintstat){
            case SCI_INT_PE:
            case SCI_INT_OE:
            case SCI_INT_FE:
            case SCI_INT_RXERR:
                error();
                break;
            default:
                break;
            }
            uint16_t bytestoread = FIFO_LEVEL;
            if(currNMEAptr+bytestoread > BUFFER_SIZE){
                bytestoread = BUFFER_SIZE - currNMEAptr;
            }
            NMEA_DATA[currNMEAptr++] = SCI_readCharBlockingNonFIFO(SCIX_BASE);
            if(currNMEAptr >= BUFFER_SIZE){
                currNMEAptr = 0; //reset NMEA pointer level
            }
        scirxAcount++;
        SCI_clearOverflowStatus(SCIX_BASE);
        SCI_clearInterruptStatus(SCIX_BASE, SCI_INT_RXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    __interrupt void INT_SCIY_RX_ISR(void){  //RTCM RECIEVE DATA ISR
        //RX ERROR HANDLING, NEED TO CHANGE ACCORDING TO APPLICATION REQUIREMENT
            uint32_t rxintstat = SCI_getInterruptStatus(SCIY_BASE);
            switch(rxintstat){
            case SCI_INT_PE:
            case SCI_INT_OE:
            case SCI_INT_FE:
            case SCI_INT_RXERR:
                error();
                break;
            default:
                break;
            }
            uint16_t bytestoread = FIFO_LEVEL;
            if(currRTCMptr+bytestoread > BUFFER_SIZE){
                bytestoread = BUFFER_SIZE - currRTCMptr;
            }
            RTCM[currRTCMptr++] = SCI_readCharBlockingNonFIFO(SCIY_BASE);
            if(currRTCMptr >= BUFFER_SIZE){
                currRTCMptr = 0; //reset NMEA pointer level
            }
        flag = 1;
        scirxBcount++;
        SCI_clearOverflowStatus(SCIY_BASE);
        SCI_clearInterruptStatus(SCIY_BASE, SCI_INT_RXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    /***********************************************************************/
    __interrupt void INT_SCIX_TX_ISR(void){
        BaseType_t xHighPriorityTaskWoken = pdFALSE;
        GPIO_togglePin(LED0_GPIO);
        scitxAcount++;
        SCI_clearInterruptStatus(SCIX_BASE, SCI_INT_TXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
        portYIELD_FROM_ISR(xHighPriorityTaskWoken);
    }
    __interrupt void INT_SCIY_TX_ISR(void){
        GPIO_togglePin(LED1_GPIO);
        scitxBcount++;
        SCI_clearInterruptStatus(SCIY_BASE, SCI_INT_TXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    //
    //Task Functions
    //
    
    void gnss_task(void * data){
        for(;;){
            intstat = SCI_getInterruptStatus(SCIX_BASE);
            SCI_writeCharArray(SCIX_BASE,(uint16_t*)RTCM,sizeof(RTCM)); //TRANSMIT THE RTCM DATA
            vTaskDelay(pdMS_TO_TICKS(500));
      }
    }
    
    void gsm_task(void * data){
        for(;;){
            SCI_writeCharArray(SCIY_BASE, (uint16_t*)NMEA_DATA,sizeof(NMEA_DATA)); //TRANSMIT NMEA DATA FOR RTCM CORRECTION
            vTaskDelay(pdMS_TO_TICKS(500));
        }
    }
    
    
    //
    // Main
    //
    void main(void)
    {
    
        //
        // Initialize device clock and peripherals
        //
        Device_init();
        Interrupt_initModule();
        //
        // Disable pin locks and enable internal pull-ups.
        //
        Device_initGPIO();
        DINT;
        IER = 0x0000;
        IFR = 0x0000;
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // PinMux and Peripheral Initialization
        //
        EINT;
        ERTM;
    
        Board_init();
    
        FreeRTOS_init();
        //
        // C2000Ware Library initialization
        //
    
        //
        // Enable Global Interrupt (INTM) and real time interrupt (DBGM)
        //
    
    
        while(1)
        {
    
           // SCI_writeCharArray(SCIY_BASE, (uint16_t*)NMEA_DATA,sizeof(NMEA_DATA));
        }
    }
    
    void error(void)
    {
        asm("     ESTOP0"); // Test failed
        for (;;);
    }
    
    void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
    {
        ( void ) pcTaskName;
        ( void ) pxTask;
    
        /* Run time stack overflow checking is performed if
        configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook
        function is called if a stack overflow is detected. */
        taskDISABLE_INTERRUPTS();
        for( ;; );
    }
    
    void vApplicationMallocFailedHook( void )
    {
        taskDISABLE_INTERRUPTS();
        for( ;; );
    }
    
    
    
    
    //
    // End of File
    //
    

    The bare metal code works fine but when i enable FreeRTOS the interrupts are no longer serviced. What exactly is causing this .?

  • Hi Arnav,

    Also, which peripheral interrupts are you using, and to clarify, these interrupts work as expected without FreeRTOS?

    The SCI Interrupts work fine without FreeRTOS implementation.

    And the CPU Timer interrupts also work along with the FreeRTOS. Only the interrupts configured through PIE seems to have the issue.

    The code attached is just a sample code , i was testing to see if FreeRTOS works with peripheral interrupts , thats when i encountered this issue

    #include "driverlib.h"
    #include "device.h"
    #include "FreeRTOS.h"
    #include "board.h"
    #include "c2000_freertos.h"
    #include "stdio.h"
    //
    //User Defines
    //
    
    #define BUFFER_SIZE 10
    #define FIFO_LEVEL 1
    
    //
    //Function prototypes
    //
    void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName);
    void vApplicationMallocFailedHook(void);
    void error(void);
    //
    //Task functions
    //
    void gnss_task(void *);
    void gsm_task(void *);
    
    //
    //ISR functions
    //
    void INT_SCIX_RX_ISR(void);
    void INT_SCIY_RX_ISR(void);
    void INT_SCIX_TX_ISR(void);
    void INT_SCIY_TX_ISR(void);
    void INT_MYCPUTIMER0_ISR(void);
    //
    //global variables
    //
    char NMEA_DATA[BUFFER_SIZE] = "XXXXXXXXX";
    char RTCM[BUFFER_SIZE] = "YYYYYYYYY";
    
    volatile uint16_t scitxBcount = 0;
    volatile uint16_t scirxBcount = 0;
    volatile uint16_t scitxAcount = 0;
    volatile uint16_t scirxAcount = 0;
    
    volatile uint16_t currNMEAptr = 0; //nmea buffer pointer
    volatile uint16_t currRTCMptr = 0; //rtcm buffer pointer
    volatile uint32_t intstat = 0;
    volatile uint16_t flag = 0;
    volatile uint16_t overflowhook = 0;
    volatile uint16_t mallochook = 0;
    
    //
    //ISR
    //
    
    /***********************************************************************/
    __interrupt void INT_SCIX_RX_ISR(void){  //NMEA RECIEVE DATA ISR
        //RX ERROR HANDLING, NEED TO CHANGE ACCORDING TO APPLICATION REQUIREMENT
            uint32_t rxintstat = SCI_getInterruptStatus(SCIX_BASE);
            switch(rxintstat){
            case SCI_INT_PE:
            case SCI_INT_OE:
            case SCI_INT_FE:
            case SCI_INT_RXERR:
                error();
                break;
            default:
                break;
            }
            uint16_t bytestoread = FIFO_LEVEL;
            if(currNMEAptr+bytestoread > BUFFER_SIZE){
                bytestoread = BUFFER_SIZE - currNMEAptr;
            }
            NMEA_DATA[currNMEAptr++] = SCI_readCharBlockingNonFIFO(SCIX_BASE);
            if(currNMEAptr >= BUFFER_SIZE){
                currNMEAptr = 0; //reset NMEA pointer level
            }
        scirxAcount++;
        SCI_clearOverflowStatus(SCIX_BASE);
        SCI_clearInterruptStatus(SCIX_BASE, SCI_INT_RXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    __interrupt void INT_SCIY_RX_ISR(void){  //RTCM RECIEVE DATA ISR
        //RX ERROR HANDLING, NEED TO CHANGE ACCORDING TO APPLICATION REQUIREMENT
            uint32_t rxintstat = SCI_getInterruptStatus(SCIY_BASE);
            switch(rxintstat){
            case SCI_INT_PE:
            case SCI_INT_OE:
            case SCI_INT_FE:
            case SCI_INT_RXERR:
                error();
                break;
            default:
                break;
            }
            uint16_t bytestoread = FIFO_LEVEL;
            if(currRTCMptr+bytestoread > BUFFER_SIZE){
                bytestoread = BUFFER_SIZE - currRTCMptr;
            }
            RTCM[currRTCMptr++] = SCI_readCharBlockingNonFIFO(SCIY_BASE);
            if(currRTCMptr >= BUFFER_SIZE){
                currRTCMptr = 0; //reset NMEA pointer level
            }
        flag = 1;
        scirxBcount++;
        SCI_clearOverflowStatus(SCIY_BASE);
        SCI_clearInterruptStatus(SCIY_BASE, SCI_INT_RXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    /***********************************************************************/
    __interrupt void INT_SCIX_TX_ISR(void){
        BaseType_t xHighPriorityTaskWoken = pdFALSE;
        GPIO_togglePin(LED0_GPIO);
        scitxAcount++;
        SCI_clearInterruptStatus(SCIX_BASE, SCI_INT_TXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
        portYIELD_FROM_ISR(xHighPriorityTaskWoken);
    }
    __interrupt void INT_SCIY_TX_ISR(void){
        GPIO_togglePin(LED1_GPIO);
        scitxBcount++;
        SCI_clearInterruptStatus(SCIY_BASE, SCI_INT_TXFF);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    //
    //Task Functions
    //
    __interrupt void INT_MYCPUTIMER0_ISR(void){
        GPIO_togglePin(LED0_GPIO);
        Interrupt_clearACKGroup(INT_MYCPUTIMER0_INTERRUPT_ACK_GROUP);
    }
    void gnss_task(void * data){
        for(;;){
            intstat = SCI_getInterruptStatus(SCIX_BASE);
            SCI_writeCharArray(SCIX_BASE,(uint16_t*)RTCM,sizeof(RTCM)); //TRANSMIT THE RTCM DATA
            vTaskDelay(pdMS_TO_TICKS(500));
      }
    }
    
    void gsm_task(void * data){
        for(;;){
            SCI_writeCharArray(SCIY_BASE, (uint16_t*)NMEA_DATA,sizeof(NMEA_DATA)); //TRANSMIT NMEA DATA FOR RTCM CORRECTION
            vTaskDelay(pdMS_TO_TICKS(500));
        }
    }
    
    
    //
    // Main
    //
    void main(void)
    {
    
        //
        // Initialize device clock and peripherals
        //
        Device_init();
        Interrupt_initModule();
        //
        // Disable pin locks and enable internal pull-ups.
        //
        Device_initGPIO();
        DINT;
        IER = 0x0000;
        IFR = 0x0000;
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // PinMux and Peripheral Initialization
        //
        EINT;
        ERTM;
    
        Board_init();
    
        FreeRTOS_init();
        //
        // C2000Ware Library initialization
        //
    
        //
        // Enable Global Interrupt (INTM) and real time interrupt (DBGM)
        //
    
    
        while(1)
        {
    
           // SCI_writeCharArray(SCIY_BASE, (uint16_t*)NMEA_DATA,sizeof(NMEA_DATA));
        }
    }
    

  • Hi Ashwin, 

    In Sysconfig, can you ensure the "Enable interrupt in PIE" option is turned on for all your interrupts. This setting is off by default. 

    Thanks,

    Arnav

  • Hi Arnav

    It is enabled , I checked all possible cases with sysconfig. I have enabled everything required.

    That's not the problem fix. Also Free RTOS documentation for TI is very limited. Especially around peripheral interrupts , Is there anything else i am missing in the code that should be done? .

    Can you please share a working code of Free RTOS implementation with peripheral interrupts. The task should be preempted by interrupts and execute ISR. 

    Thanks,

    Ashwin Bhaskar A

  • Hi Ashwin,

    I am able to run your code as is, and the ISRs are executing as expected.

    Below are the Sysconfig settings used. Note that I am using the SCI modules in loopback mode.

    /**
     * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
     * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
     * @cliArgs --device "F28P65x" --part "F28P65x_256ZEJ" --package "256ZEJ" --context "CPU1" --product "C2000WARE@5.03.00.00"
     * @v2CliArgs --device "TMS320F28P659DK-Q1" --package "256ZEJ" --variant "TMS320F28P659DK8-Q1" --context "CPU1" --product "C2000WARE@5.03.00.00"
     * @versions {"tool":"1.21.0+3717"}
     */
    
    /**
     * Import the modules used in this configuration.
     */
    const sci       = scripting.addModule("/driverlib/sci.js", {}, false);
    const sci1      = sci.addInstance();
    const sci2      = sci.addInstance();
    const FREERTOS  = scripting.addModule("/kernel/freertos_tool/FREERTOS", {}, false);
    const FREERTOS1 = FREERTOS.addInstance();
    
    /**
     * Write custom configuration values to the imported modules.
     */
    sci1.$name                      = "SCIX";
    sci1.selectRegisteredInterrupts = ["registerRxInt","registerTxInt"];
    sci1.useFifo                    = false;
    sci1.enabledInterrupts          = ["SCI_INT_RXRDY_BRKDT","SCI_INT_TXRDY"];
    sci1.enabledErrorInterrupts     = ["SCI_INT_FE","SCI_INT_OE","SCI_INT_PE","SCI_INT_RXERR"];
    sci1.loopback                   = true;
    sci1.rxQual.$name               = "myGPIOQUAL0";
    sci1.txQual.$name               = "myGPIOQUAL1";
    sci1.sciRXInt.enableInterrupt   = true;
    sci1.sciTXInt.enableInterrupt   = true;
    
    sci2.selectRegisteredInterrupts = ["registerRxInt","registerTxInt"];
    sci2.useFifo                    = false;
    sci2.enabledInterrupts          = ["SCI_INT_RXRDY_BRKDT","SCI_INT_TXRDY"];
    sci2.enabledErrorInterrupts     = ["SCI_INT_FE","SCI_INT_OE","SCI_INT_PE","SCI_INT_RXERR"];
    sci2.$name                      = "SCIY";
    sci2.loopback                   = true;
    sci2.rxQual.$name               = "myGPIOQUAL0_COPY";
    sci2.txQual.$name               = "myGPIOQUAL1_COPY";
    sci2.sciRXInt.enableInterrupt   = true;
    sci2.sciTXInt.enableInterrupt   = true;
    
    FREERTOS1.$name                   = "myFREERTOS0";
    FREERTOS1.CPU_CLOCK_HZ            = 200000000;
    FREERTOS1.MINIMAL_STACK_SIZE      = 256;
    FREERTOS1.USE_MUTEXES             = true;
    FREERTOS1.USE_RECURSIVE_MUTEXES   = true;
    FREERTOS1.USE_COUNTING_SEMAPHORES = true;
    FREERTOS1.vTaskSuspend            = false;
    FREERTOS1.tasks.create(2);
    FREERTOS1.tasks[0].taskStackSize  = 256;
    FREERTOS1.tasks[0].taskPriority   = 2;
    FREERTOS1.tasks[0].taskParams     = "0xDEADBEAF";
    FREERTOS1.tasks[0].taskPointer    = "gnss_task";
    FREERTOS1.tasks[0].$name          = "gnssTask";
    FREERTOS1.tasks[1].taskStackSize  = 256;
    FREERTOS1.tasks[1].taskPriority   = 1;
    FREERTOS1.tasks[1].taskParams     = "0xBAADF00D";
    FREERTOS1.tasks[1].taskPointer    = "gsm_task";
    FREERTOS1.tasks[1].$name          = "gsmTask";
    FREERTOS1.semaphores.create(1);
    FREERTOS1.semaphores[0].$name     = "binarySem1";

    Let me know if the same works for you. Also, which version of C2000Ware are you using?

    Thanks,

    Arnav

  • Let me know if the same works for you. Also, which version of C2000Ware are you using?

    Hi Arnav,

    I will recheck it once again with sys config and get back to you .

    I believe the C2000Ware version is 5.03