chttpfreertostexas-instrumentscoap

How to run FreeRTOS on TM4C129EXL?


I am working on a C project for the university where a CoAP server is to be hosted on a TM4C129EXL. It is particularly important to choose a FreeRTOS operating system. Unfortunately, I had to learn that Texas Instruments has stopped supporting FreeRTOS. There are no options for me to switch to another operating system. It is for this reason that I turn to you.

I'm looking for a sample program in which Free RTOS is executed on a TM4C129EXL board. In the best case, I would be happy about a Code Composer Studio Project, as this is the IDE we work with from the university.

If you do not have any sample code available, I would be happy to receive any other information regarding FreeRTOS and CoAP of course with reference to the TM4C129EXL.


Solution

  • You did not specify if you had any requirements in terms of FreeRTOS version, but you can either:

    The procedure hereafter describes step by step how to create a minimalist FreeRTOS program with Code Composer Studio 10.3.0 and FreeRTOS v202104.00 in a Windows 10 environment using the second approach. You may have to adjust the drive letter to you specific setup, I am using D: for the purpose of this example..

    [Project creation wizzard]

    #include "FreeRTOS.h"
    #include "task.h"
    
    extern void prvSetupHardware();
    extern void main_blinky();
    
    int main(void)
    {
        /* Configure the hardware ready to run the demo. */
        prvSetupHardware();
    
        main_blinky();
    
        /* Don't expect to reach here. */
        return 0;
    }
    
    void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName)
    {
        while(1)
        {
        }
    }
    
    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_ints.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/sysctl.h"
    #include "FreeRTOS.h"
    #include "task.h"
    #include "sysctl.h"
    
    static void prvLedToggleTask();
    
    /* Priorities at which the tasks are created. */
    #define mainTOGGLE_LED_PRIORITY         ( tskIDLE_PRIORITY + 1 )
    #define TOGGLE_LED_DELAY_MS             200
    
    void main_blinky()
    {
        /* create task */
        xTaskCreate( prvLedToggleTask, "LED", configMINIMAL_STACK_SIZE, NULL, mainTOGGLE_LED_PRIORITY, NULL );
    
        /* Start the tasks and timer running. */
        vTaskStartScheduler();
    
    }
    
    static void prvLedToggleTask( void *pvParameters )
    {
        // Remove compiler warning about unused parameter. */
        ( void ) pvParameters;
    
        for( ;; )
        {
            //
            // Turn on the LED.
            //
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0);
    
            // Wait a bit
            vTaskDelay( TOGGLE_LED_DELAY_MS);
    
            //
            // Turn off the LED.
            //
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0x0);
    
            // Wait a bit
            vTaskDelay( TOGGLE_LED_DELAY_MS );
        }
    }
    
    uint32_t g_ui32SysClock;
    
    void prvSetupHardware()
    {
        // Configure PLL
        g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                             SYSCTL_OSC_MAIN |
                                             SYSCTL_USE_PLL |
                                             SYSCTL_CFG_VCO_480), 120000000);
        //
        // Enable the GPIO port that is used for the on-board LED.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
    
        //
        // Check if the peripheral access is enabled.
        //
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPION))
        {
        }
    
        //
        // Enable the GPIO pin for the LED (PN0).  Set the direction as output, and
        // enable the GPIO pin for digital function.
        //
        GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);
    }
    
    extern void xPortPendSVHandler(void);
    extern void vPortSVCHandler(void);
    extern void xPortSysTickHandler(void);
    

    The resulting code should look like:

    void ResetISR(void);
    static void NmiSR(void);
    static void FaultISR(void);
    static void IntDefaultHandler(void);
    
    extern void xPortPendSVHandler(void);
    extern void vPortSVCHandler(void);
    extern void xPortSysTickHandler(void);
    
      void (* const g_pfnVectors[])(void) =
    {
        (void (*)(void))((uint32_t)pui32Stack + sizeof(pui32Stack)),
                                                // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
        FaultISR,                               // The hard fault handler
        IntDefaultHandler,                      // The MPU fault handler
        IntDefaultHandler,                      // The bus fault handler
        IntDefaultHandler,                      // The usage fault handler
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // SVCall handler
        IntDefaultHandler,                      // Debug monitor handler
        0,                                      // Reserved
        IntDefaultHandler,                      // The PendSV handler
        IntDefaultHandler,                      // The SysTick handler
    

    Resulting code:

    void (* const g_pfnVectors[])(void) =
    {
        (void (*)(void))((uint32_t)pui32Stack + sizeof(pui32Stack)),
                                                // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
        FaultISR,                               // The hard fault handler
        IntDefaultHandler,                      // The MPU fault handler
        IntDefaultHandler,                      // The bus fault handler
        IntDefaultHandler,                      // The usage fault handler
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        vPortSVCHandler,                        // SVCall handler
        IntDefaultHandler,                      // Debug monitor handler
        0,                                      // Reserved
        xPortPendSVHandler,                     // The PendSV handler
        xPortSysTickHandler,                    // The SysTick handler
    

    GCC Compiler include directories

    #define configGENERATE_RUN_TIME_STATS       1
    #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()                              \
                                                g_vulRunTimeStatsCountValue = 0ul
    #define portGET_RUN_TIME_COUNTER_VALUE()    g_vulRunTimeStatsCountValue
    

    GCC Compiler Command-line pattern

    GCC linker Command-line pattern

    GCC linker libraries options

    In my case, I had to stop the project and to press the board resetbutton in order to the program to start.

    Finally, the LED should start blinking every 200ms.

    The complete list of files in the project once the project 'cleaned' should ultimately be:

    Folder PATH listing for volume DATA
    Volume serial number is 0E12-BCA2
    D:.
    |   .ccsproject
    |   .cproject
    |   .project
    |   blinky.c
    |   FreeRTOSConfig.h
    |   main.c
    |   tm4c1294ncpdt.lds
    |   tm4c1294ncpdt_startup_ccs_gcc.c
    |   
    +---.settings
    |       org.eclipse.cdt.codan.core.prefs
    |       org.eclipse.cdt.debug.core.prefs
    |       org.eclipse.core.resources.prefs
    |       
    +---Debug
    |   |   ccsObjs.opt
    |   |   makefile
    |   |   objects.mk
    |   |   sources.mk
    |   |   subdir_rules.mk
    |   |   subdir_vars.mk
    |   |   TM4C129EXL-FreeRTOS.map
    |   |   
    |   +---driverlib
    |   |       subdir_rules.mk
    |   |       subdir_vars.mk
    |   |       
    |   \---FreeRTOS-Kernel
    |       |   subdir_rules.mk
    |       |   subdir_vars.mk
    |       |   
    |       \---portable
    |           +---GCC
    |           |   \---ARM_CM4F
    |           |           subdir_rules.mk
    |           |           subdir_vars.mk
    |           |           
    |           \---MemMang
    |                   subdir_rules.mk
    |                   subdir_vars.mk
    |                   
    +---driverlib
    |       adc.h
    |       aes.h
    |       can.h
    |       comp.h
    |       cpu.h
    |       crc.h
    |       debug.h
    |       des.h
    |       eeprom.h
    |       emac.h
    |       epi.h
    |       flash.h
    |       fpu.h
    |       gpio.h
    |       hibernate.h
    |       i2c.h
    |       interrupt.h
    |       lcd.h
    |       libdriver.a
    |       mpu.h
    |       onewire.h
    |       pin_map.h
    |       pwm.h
    |       qei.h
    |       rom.h
    |       rom_map.h
    |       rtos_bindings.h
    |       shamd5.h
    |       ssi.h
    |       sw_crc.h
    |       sysctl.h
    |       sysexc.h
    |       systick.h
    |       timer.h
    |       uart.h
    |       udma.h
    |       usb.h
    |       watchdog.h
    |       
    +---FreeRTOS-Kernel
    |   |   croutine.c
    |   |   event_groups.c
    |   |   list.c
    |   |   queue.c
    |   |   stream_buffer.c
    |   |   tasks.c
    |   |   timers.c
    |   |   
    |   +---include
    |   |       atomic.h
    |   |       croutine.h
    |   |       deprecated_definitions.h
    |   |       event_groups.h
    |   |       FreeRTOS.h
    |   |       list.h
    |   |       message_buffer.h
    |   |       mpu_prototypes.h
    |   |       mpu_wrappers.h
    |   |       portable.h
    |   |       projdefs.h
    |   |       queue.h
    |   |       semphr.h
    |   |       StackMacros.h
    |   |       stack_macros.h
    |   |       stdint.readme
    |   |       stream_buffer.h
    |   |       task.h
    |   |       timers.h
    |   |       
    |   \---portable
    |       +---GCC
    |       |   \---ARM_CM4F
    |       |           port.c
    |       |           portmacro.h
    |       |           
    |       \---MemMang
    |               heap_4.c
    |               
    \---inc
            asmdefs.h
            hw_adc.h
            hw_aes.h
            hw_can.h
            hw_ccm.h
            hw_comp.h
            hw_des.h
            hw_eeprom.h
            hw_emac.h
            hw_epi.h
            hw_fan.h
            hw_flash.h
            hw_gpio.h
            hw_hibernate.h
            hw_i2c.h
            hw_ints.h
            hw_lcd.h
            hw_memmap.h
            hw_nvic.h
            hw_onewire.h
            hw_pwm.h
            hw_qei.h
            hw_shamd5.h
            hw_ssi.h
            hw_sysctl.h
            hw_sysexc.h
            hw_timer.h
            hw_types.h
            hw_uart.h
            hw_udma.h
            hw_usb.h
            hw_watchdog.h
            tm4c1294ncpdt.h