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.

No scheduling with FreeRTOS on CC3200 Launchpad

Other Parts Discussed in Thread: CC3200

I'm trying to build a system with multiple tasks on a CC3200 lauchpad board with freeRTOS. I created three tasks in my main (based on the freertos demo)

All three tasks have the same priority (1) and therefore I expect that all three tasks will get the same amount of processor time.

Each task is only responsible for printing its name on the uart port:Unfortunately, I only see the highest priority task printing its name all the time and in the case that the priorities are equal I receive a faulty interrupt. What should I do to fix this?

  • Hi,

    this is the default behavior of an pre-emptive multitasking. Only a task with higher priority could pause the task or an osi_sleep(1);

    Best regards.

  • Hi,

    Thanks for your answer. osi_sleep() is however not found in my osi.h file. What do you like to accomplish with  the sleep function?

    How can I achieve a situation where all three tasks get a fair amount of processing time?

  • Sorry for the Typo mistake, i mean osi_Sleep(1);

  • Ah.. I found the function. However, it still doesn't work as I hope to.

    I have the following code for the tasks:

    void vTestTask1( void *pvParameters )
    {
        for( ;; )
        {           
          Report("1");
          osi_Sleep(10);   
        }
    }




    And the following code for creating the tasks:

     osi_TaskCreate( vTestTask1, ( signed portCHAR * ) "TASK1",
                    OSI_STACK_SIZE, NULL, 1, NULL );

    I have two tasks (both prio 1) and hope to see this as an output: 121212121 etc..

    Unfortunately, this is what I see now: 121111111 etc..

    What should I do to fix this?

  • Jan Oene Krist said:

    in the case that the priorities are equal I receive a faulty interrupt. What should I do to fix this?

    Hi Jan,
    You are receiving faulty interrupt because of sync issue as there may be chance that 2 thread trying access UART TX register at the same time. Kindly replace common\uart_if.c with attached file and let me now whether it solve issue or not. 
    1016.uart_if.c
    //*****************************************************************************
    // uart_if.c
    //
    // uart interface file: Prototypes and Macros for UARTLogger
    //
    // Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ 
    // 
    // 
    //  Redistribution and use in source and binary forms, with or without 
    //  modification, are permitted provided that the following conditions 
    //  are met:
    //
    //    Redistributions of source code must retain the above copyright 
    //    notice, this list of conditions and the following disclaimer.
    //
    //    Redistributions in binary form must reproduce the above copyright
    //    notice, this list of conditions and the following disclaimer in the 
    //    documentation and/or other materials provided with the   
    //    distribution.
    //
    //    Neither the name of Texas Instruments Incorporated nor the names of
    //    its contributors may be used to endorse or promote products derived
    //    from this software without specific prior written permission.
    //
    //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    //  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    //  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    //  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    //  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    //  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    //  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    //  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    //  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    //  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    //  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    //
    //*****************************************************************************
    
    // Standard includes
    #include <stdarg.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    // Driverlib includes
    #include "hw_types.h"
    #include "hw_memmap.h"
    #include "prcm.h"
    #include "pin.h"
    #include "uart.h"
    #include "rom.h"
    #include "rom_map.h"
    
    #include "uart_if.h"
    
    #ifdef SL_PLATFORM_MULTI_THREADED
    #include "osi.h"
    
    
    #define RTOS_MUTEX_CREATE(x)        osi_LockObjCreate(x)
    #define RTOS_MUTEX_ACQUIRE(x)       osi_LockObjLock(x, OSI_WAIT_FOREVER)
    #define RTOS_MUTEX_RELEASE(x)       osi_LockObjUnlock(x)
    #define RTOS_MUTEX_DELETE(x)        osi_LockObjDelete(x)
    #endif
    
    #define IS_SPACE(x)       (x == 32 ? 1 : 0)
    
    //*****************************************************************************
    // Global variable indicating command is present
    //*****************************************************************************
    static unsigned long __Errorlog;
    
    //*****************************************************************************
    // Global variable indicating input length
    //*****************************************************************************
    unsigned int ilen=1;
    
    #ifdef SL_PLATFORM_MULTI_THREADED
    OsiLockObj_t    g_printLock;
    #endif
    
    //*****************************************************************************
    //
    //! Initialization
    //!
    //! This function
    //!        1. Configures the UART to be used.
    //!
    //! \return none
    //
    //*****************************************************************************
    void 
    InitTerm()
    {
    #ifndef NOTERM
      MAP_UARTConfigSetExpClk(CONSOLE,MAP_PRCMPeripheralClockGet(CONSOLE_PERIPH),
                      UART_BAUD_RATE, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                       UART_CONFIG_PAR_NONE));
    #endif
      __Errorlog = 0;
      
    #ifdef SL_PLATFORM_MULTI_THREADED
      /* Create a lock object */
      RTOS_MUTEX_CREATE(&g_printLock);
    #endif  
    }
    
    //*****************************************************************************
    //
    //!    Outputs a character string to the console
    //!
    //! \param str is the pointer to the string to be printed
    //!
    //! This function
    //!        1. prints the input string character by character on to the console.
    //!
    //! \return none
    //
    //*****************************************************************************
    void 
    Message(const char *str)
    {
    #ifndef NOTERM
        if(str != NULL)
        {
            while(*str!='\0')
            {
                MAP_UARTCharPut(CONSOLE,*str++);
            }
        }
    #endif
    }
    
    //*****************************************************************************
    //
    //!    Clear the console window
    //!
    //! This function
    //!        1. clears the console window.
    //!
    //! \return none
    //
    //*****************************************************************************
    void 
    ClearTerm()
    {
    #ifdef SL_PLATFORM_MULTI_THREADED  
        RTOS_MUTEX_ACQUIRE(&g_printLock);
    #endif    
        Message("\33[2J\r");
    #ifdef SL_PLATFORM_MULTI_THREADED    
        RTOS_MUTEX_RELEASE(&g_printLock);
    #endif    
    }
    
    //*****************************************************************************
    //
    //! Error Function
    //!
    //! \param 
    //!
    //! \return none
    //! 
    //*****************************************************************************
    void 
    Error(char *pcFormat, ...)
    {
    #ifndef NOTERM
        char  cBuf[256];
        va_list list;
    #ifdef SL_PLATFORM_MULTI_THREADED    
        RTOS_MUTEX_ACQUIRE(&g_printLock);
    #endif    
        va_start(list,pcFormat);
        vsnprintf(cBuf,256,pcFormat,list);
        Message(cBuf);
    #endif
        __Errorlog++;
    #ifdef SL_PLATFORM_MULTI_THREADED    
        RTOS_MUTEX_RELEASE(&g_printLock);
    #endif    
    }
    
    //*****************************************************************************
    //
    //! Get the Command string from UART
    //!
    //! \param  pucBuffer is the command store to which command will be populated
    //! \param  ucBufLen is the length of buffer store available
    //!
    //! \return Length of the bytes received. -1 if buffer length exceeded.
    //! 
    //*****************************************************************************
    int
    GetCmd(char *pcBuffer, unsigned int uiBufLen)
    {
        char cChar;
        int iLen = 0;
        
        //
        // Wait to receive a character over UART
        //
        cChar = MAP_UARTCharGet(CONSOLE);
        
        //
        // Echo the received character
        //
        MAP_UARTCharPut(CONSOLE, cChar);
        iLen = 0;
        
        //
        // Checking the end of Command
        //
        while((cChar != '\r') && (cChar !='\n') )
        {
            //
            // Handling overflow of buffer
            //
            if(iLen >= uiBufLen)
            {
                return -1;
            }
            
            //
            // Copying Data from UART into a buffer
            //
            if(cChar != '\b')
            { 
                *(pcBuffer + iLen) = cChar;
                iLen++;
            }
            else
            {
                //
                // Deleting last character when you hit backspace 
                //
                if(iLen)
                {
                    iLen--;
                }
            }
            //
            // Wait to receive a character over UART
            //
            cChar = MAP_UARTCharGet(CONSOLE);
            
            //
            // Echo the received character
            //
            MAP_UARTCharPut(CONSOLE, cChar);
        }
    
        *(pcBuffer + iLen) = '\0';
    
        Report("\n\r");
    
        return iLen;
    }
    
    //*****************************************************************************
    //
    //!    Trim the spaces from left and right end of given string
    //!
    //! \param  Input string on which trimming happens
    //!
    //! \return length of trimmed string
    //
    //*****************************************************************************
    int TrimSpace(char * pcInput)
    {
        size_t size;
        char *endStr, *strData = pcInput;
        char index = 0;
        size = strlen(strData);
    
        if (!size)
            return 0;
    
        endStr = strData + size - 1;
        while (endStr >= strData && IS_SPACE(*endStr))
            endStr--;
        *(endStr + 1) = '\0';
    
        while (*strData && IS_SPACE(*strData))
        {
            strData++;
            index++;
        }
        memmove(pcInput,strData,strlen(strData)+1);
    
        return strlen(pcInput);
    }
    
    //*****************************************************************************
    //
    //!    prints the formatted string on to the console
    //!
    //! \param format is a pointer to the character string specifying the format in
    //!           the following arguments need to be interpreted.
    //! \param [variable number of] arguments according to the format in the first
    //!         parameters
    //! This function
    //!        1. prints the formatted error statement.
    //!
    //! \return count of characters printed
    //
    //*****************************************************************************
    int Report(const char *pcFormat, ...)
    {
     int iRet = 0;
    #ifndef NOTERM
    
      char *pcBuff, *pcTemp;
      int iSize = 256;
      
    #ifdef SL_PLATFORM_MULTI_THREADED  
      RTOS_MUTEX_ACQUIRE(&g_printLock);
    #endif
      
      va_list list;
      pcBuff = (char*)malloc(iSize);
      if(pcBuff == NULL)
      {
    #ifdef SL_PLATFORM_MULTI_THREADED    
    	  RTOS_MUTEX_RELEASE(&g_printLock);
    #endif          
          return -1;
      }
      while(1)
      {
          va_start(list,pcFormat);
          iRet = vsnprintf(pcBuff,iSize,pcFormat,list);
          va_end(list);
          if(iRet > -1 && iRet < iSize)
          {
              break;
          }
          else
          {
              iSize*=2;
              if((pcTemp=realloc(pcBuff,iSize))==NULL)
              { 
                  Message("Could not reallocate memory\n\r");
                  iRet = -1;
                  break;
              }
              else
              {
                  pcBuff=pcTemp;
              }
              
          }
      }
      Message(pcBuff);
      free(pcBuff);
    #ifdef SL_PLATFORM_MULTI_THREADED  
      RTOS_MUTEX_RELEASE(&g_printLock);
    #endif  
    #endif
      return iRet;
    }
    
    Regards,
    Aashish
  • Hi,


    Unfortunately, this did not helped with my question. It is now printing 12111111.

    Anyone with some more suggestions?

    BTW: The program I want to write eventually will have three tasks: one for reading from the uart (a message can come in at any time) one for reading TCP/IP messages (they can also come in at all time) and one for handling the messages (its polling the queue;s between the readers and the handlers)

    As a small first step I tried to get a bit familiar with the FreeRTOS, but it seems that I ran into problems that probably don't even exist in my final program.

    Does someone see any problems with this idea. Is it possible to have two running tasks reading from uart and TCP/IP? How should I do the scheduling stuff?

  • Hi Jan,

    Jan Oene Krist said:

    Unfortunately, this did not helped with my question. It is now printing 12111111.

    The given solution was meant for fault issue that occurs when 2 task try to print at the same time not for the scheduling task to get output in desire format.

    Jan Oene Krist said:

    Does someone see any problems with this idea. Is it possible to have two running tasks reading from uart and TCP/IP? How should I do the scheduling stuff?

    You can use the queue they way it is demonstrate in FreeRTOS demo. Reading task (TCP and UART) write on one end and processing task read from another end and process data.

    TCPTask()
    {

    while(1)
    {
    recv data in local buffer
    send it to queue xQueueSend()
    }

    }

    UARTTask()
    {
    while(1)
    {
    Read data from UART
    push it to queue xQueueSend()
    }

    }

    processtask()
    {
    while(1)
    {
    receive from queue xQueueReceive() // Wait for a message to arrive.
    process data
    }

    }

  • Hi Aashish,


    Many thanks for your answer. I understand this structure and the use of queues is very useful in this case.
    However, it is still not clear to me how these tasks all get a fair amount of time. The uart read function and the TCP/IP function are both blocking I think.

    If the TCP/IP task is scheduled and there are no incoming messages for a while, FreeRTOS should schedule the UART reader to check if there is a message available. How can I achieve this behavior?

  • Hi Jan,

    Jan Oene Krist said:

    If the TCP/IP task is scheduled and there are no incoming messages for a while, FreeRTOS should schedule the UART reader to check if there is a message available. How can I achieve this behavior?

    I hope it will be taken care by FreeRTOS as its rtos/scheduler job to schedule the task. So I don't think you need to explicitly schedule a task. 
    Regards,
    Aashish 
  • Hi,

    Thanks for your answer. Can you explain (or give a pointer to a webpage where it is explained) how the scheduler does this? I assume that the scheduler has a round robin scheme, but how is the length of the time slices determined if two out of three tasks are waiting for an input(and not yet hit the vDelay statement)?

  • Hi Jan,

    I don't have much fine detail of FreeRTOS but I hope "FreeRTOS Quick Start Guide" will help you to understand how freeRTOS scheduler work. Here is link http://www.freertos.org/FreeRTOS-quick-start-guide.html

    Regards,

    Aashish