FreeRTOS on Teknic Clearcore, task created but not scheduled

Hello,

I’m completely new to FreeRTOS and trying to use it on a Teknic Clearcore board (specifications below)

image

Although a working demo would have been helpful to start the project with, one didn’t exist for these specs, so I followed instructions online on setting up all the components–the portable/GCC/ARM_CM4F/, portable/MemMang, the FreeRTOSConfig.h, etc. I have configAssert configured as well.

The project builds and the output suggests that the tasks are being successfully created but not vTaskStartScheduler() does not actually schedule the task. I’m working on a very simple blinky test to start with.

I suspect it’s something to do with the SysTick_Handler but I’m not sure how to resolve the conflict between the Clearcore board library’s SysTick_Handler and FreeRTOS’s. (#define xPortSysTickHandler SysTick_Handler crashes a build when uncommented). I also don’t have a debugger, hence the Serial prints.

I’d love any tips and advice on this! Thank you.

FreeRTOSConfig.h

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H


#ifdef __cplusplus
extern "C" {
#endif

#define configUSE_PREEMPTION                    1
#define configUSE_IDLE_HOOK                     0
#define configUSE_TICK_HOOK                     0
#define configCPU_CLOCK_HZ                      ( 120000000UL )
#define configTICK_RATE_HZ                      ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES                    ( 5 )
#define configMINIMAL_STACK_SIZE                ( ( unsigned short ) 120 )
#define configTOTAL_HEAP_SIZE                   ( ( size_t ) ( 30 * 1024 ) )
#define configMAX_TASK_NAME_LEN                 ( 10 )
#define configUSE_TRACE_FACILITY                1
#define configUSE_16_BIT_TICKS                  0
#define configIDLE_SHOULD_YIELD                 1
#define configUSE_MUTEXES                       1
#define configQUEUE_REGISTRY_SIZE               8
#define configCHECK_FOR_STACK_OVERFLOW          0
#define configUSE_RECURSIVE_MUTEXES             1
#define configUSE_MALLOC_FAILED_HOOK            0
#define configUSE_APPLICATION_TASK_TAG          0
#define configUSE_COUNTING_SEMAPHORES           1
#define configGENERATE_RUN_TIME_STATS           0
#define configSUPPORT_DYNAMIC_ALLOCATION         1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1


/* Co-routine definitions. */
#define configUSE_CO_ROUTINES                   0
#define configMAX_CO_ROUTINE_PRIORITIES         ( 2 )

/* Software timer definitions. */
#define configUSE_TIMERS                        1
#define configTIMER_TASK_PRIORITY               ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH                5
#define configTIMER_TASK_STACK_DEPTH            ( configMINIMAL_STACK_SIZE )

/* Define configASSERT() to call vAssertCalled() if the assertion fails. The assertion
   has failed if the value of the parameter passed into configASSERT() equals zero. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }	
    

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet                1
#define INCLUDE_uxTaskPriorityGet               1
#define INCLUDE_vTaskDelete                     1
#define INCLUDE_vTaskCleanUpResources           1
#define INCLUDE_vTaskSuspend                    1
#define INCLUDE_vTaskDelayUntil                 1
#define INCLUDE_vTaskDelay                      1

/* Cortex-M specific definitions. */
#define configPRIO_BITS                         3
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x7
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5

#define configKERNEL_INTERRUPT_PRIORITY         ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

/* Map FreeRTOS handlers to SAM E53 Interrupt Vectors */
#define vPortSVCHandler     SVC_Handler
#define xPortPendSVHandler  PendSV_Handler
// #define xPortSysTickHandler SysTick_Handler
// #define SysTick_Handler xPortSysTickHandler



#ifdef __cplusplus
}
#endif

#endif /* FREERTOS_CONFIG_H */


main.cpp

#include "ClearCore.h"
#include "FreeRTOS.h"
#include "task.h"
#include <Arduino.h>

#define SerialPort ConnectorUsb
#define triggerPin ConnectorIO1

extern "C" {
    /**
     * This function is called by FreeRTOS when an assertion fails.
     * @param pcFile The name of the file where the error occurred.
     * @param ulLine The line number where the error occurred.
     */
    void vAssertCalled( const char *pcFile, unsigned long ulLine ) {
        // 1. Stop all other tasks
        noInterrupts(); 

        // 2. Report the error (Since you have no debugger)
        // If Serial is initialized, try to print the location
        Serial.print("FREERTOS ASSERT FAILED: ");
        Serial.print(pcFile);
        Serial.print(" Line: ");
        Serial.println(ulLine);
    }
}


// Task function to blink a Digital Output
void vBlinkTask(void *pvParameters) {
    SerialPort.SendLine("checkpoint2");

    for(;;) {
        SerialPort.SendLine("checkpoint2.5");
        triggerPin.OutputPulsesStart(500, 500, 1, false);
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}



int main(void) {
    SerialPort.Mode(Connector::USB_CDC);
    SerialPort.Speed(115200);
    SerialPort.PortOpen();
    Delay_ms(3000);
    SerialPort.SendLine("checkpoint0");

    triggerPin.Mode(Connector::OUTPUT_DIGITAL);

    BaseType_t xReturned;
    SerialPort.SendLine("checkpoint0.5");

    // TaskHandle_t xHandle;
    
    xReturned = xTaskCreate(
        vBlinkTask,       // Function that implements the task
        "Blinky",         // Text name for the task
        1000,              // Stack size in words
        ( void * ) NULL,             // Parameter passed into the task
        4,                // Priority 
        NULL              // Task handle
    );
    Delay_ms(2000);

    SerialPort.SendLine("checkpoint1");

    configASSERT(xReturned == pdPASS);
    if (xReturned == pdPASS)    {
        SerialPort.SendLine("Task created successfully");
    } else {
        SerialPort.SendLine("Task creation failed");
    }

    vTaskStartScheduler();
    
    // Will not get here unless there is insufficient RAM.
    SerialPort.SendLine("checkpoint3");
    while(1){
        // SerialPort.SendLine("checkpoint3");
        // Delay_ms(1000);
    }
}

Are you not able to remove the SysTick_Handler from Clearcore board library? Why so?

You need that #define and commenting it is likely not the right thing.

I wasn’t able to track down where it was defined

Is it possible for you to share your complete code? May be put in a GitHub repo and share link?