1

I'm trying to run FreeRTOS on a Raspberry Pi PicoW. I'm using Visual Studio Code with PlatformIO to connect to the Pico. I have a folder for the project where I put the FreeRTOS include files and the .c files (these files were downloaded from freertos.org, they're the FreeRTOS source files).

When I try to upload the program I get the following errors, which don't make sense since I already included the FreeRTOS source files and headers and there is no compilation error, only linker error:

Executing task: C:\Users\my_name\.platformio\penv\Scripts\platformio.exe run

Processing pico (platform: raspberrypi; board: pico) ---------------------------------------------------------------------------------------------------------------------------Verbose mode can be enabled via -v, --verbose option CONFIGURATION: https://docs.platformio.org/page/boards/raspberrypi/pico.html PLATFORM: Raspberry Pi RP2040 (1.7.0) > Raspberry Pi Pico HARDWARE: RP2040 133MHz, 264KB RAM, 2MB Flash DEBUG: Current (cmsis-dap) External (cmsis-dap, jlink, raspberrypi-swd) PACKAGES:

  • tool-rp2040tools @ 1.0.2
  • toolchain-gccarmnoneeabi @ 1.90201.191206 (9.2.1)

LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft Found 0 compatible libraries Scanning dependencies... No dependencies Building in release mode Compiling .pio\build\pico\src\Overload_PICO.o Linking .pio\build\pico\firmware.elf c:/users/my_name/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: .pio\build\pico\src\Overload_PICO.o: in function task1': Overload_PICO.c:(.text.task1+0x2): undefined reference toxTaskGetTickCount' c:/users/my_name/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: Overload_PICO.c:(.text.task1+0x14): undefined reference to xTaskGetTickCount' c:/users/my_name/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: Overload_PICO.c:(.text.task1+0x28): undefined reference toxTaskDelayUntil' c:/users/my_name/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: .pio\build\pico\src\Overload_PICO.o: in function task2': Overload_PICO.c:(.text.task2+0x2): undefined reference toxTaskGetTickCount' c:/users/my_name/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: Overload_PICO.c:(.text.task2+0x14): undefined reference to xTaskGetTickCount' c:/users/my_name/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: Overload_PICO.c:(.text.task2+0x2a): undefined reference toxTaskDelayUntil' c:/users/my_name/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: .pio\build\pico\src\Overload_PICO.o: in function task3': Overload_PICO.c:(.text.task3+0x2): undefined reference toxTaskGetTickCount' c:/users/my_name/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: Overload_PICO.c:(.text.task3+0x14): undefined reference to xTaskGetTickCount' c:/users/my_name/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: Overload_PICO.c:(.text.task3+0x2a): undefined reference toxTaskDelayUntil' c:/users/my_name/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: .pio\build\pico\src\Overload_PICO.o: in function main': Overload_PICO.c:(.text.startup.main+0x12): undefined reference toxTaskCreate' c:/users/my_name/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: Overload_PICO.c:(.text.startup.main+0x24): undefined reference to xTaskCreate' c:/users/my_name/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: Overload_PICO.c:(.text.startup.main+0x36): undefined reference toxTaskCreate' c:/users/my_name/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: Overload_PICO.c:(.text.startup.main+0x3a): undefined reference to `vTaskStartScheduler' collect2.exe: error: ld returned 1 exit status *** [.pio\build\pico\firmware.elf] Error 1 =============================================== [FAILED] Took 2.80 seconds ===============================================



Files I think are useful to know to answer my question

This is the FreeRTOSConfig.h I'm using:

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/* Use Pico SDK ISR handlers */ #define vPortSVCHandler isr_svcall #define xPortPendSVHandler isr_pendsv #define xPortSysTickHandler isr_systick

#define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configUSE_TICKLESS_IDLE 0 #define configCPU_CLOCK_HZ 133000000 #define configTICK_RATE_HZ 100 #define configMAX_PRIORITIES 5 #define configMINIMAL_STACK_SIZE 128 #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_TASK_NOTIFICATIONS 1 #define configTASK_NOTIFICATION_ARRAY_ENTRIES 3 #define configUSE_MUTEXES 0 #define configUSE_RECURSIVE_MUTEXES 0 #define configUSE_COUNTING_SEMAPHORES 0 #define configQUEUE_REGISTRY_SIZE 10 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 0 #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 #define configSTACK_DEPTH_TYPE uint16_t #define configMESSAGE_BUFFER_LENGTH_TYPE size_t

/* Memory allocation related definitions. */ #define configSUPPORT_STATIC_ALLOCATION 0 #define configSUPPORT_DYNAMIC_ALLOCATION 1 #define configAPPLICATION_ALLOCATED_HEAP 1

/* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configCHECK_FOR_STACK_OVERFLOW 0 #define configUSE_MALLOC_FAILED_HOOK 0 #define configUSE_DAEMON_TASK_STARTUP_HOOK 0

/* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configUSE_TRACE_FACILITY 0 #define configUSE_STATS_FORMATTING_FUNCTIONS 0

/* Co-routine related definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 1

/* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY 3 #define configTIMER_QUEUE_LENGTH 10 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE

/* Define to trap errors during development. */ #define configASSERT( x )

/* Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_xResumeFromISR 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 1 #define INCLUDE_xTimerPendFunctionCall 0 #define INCLUDE_xTaskAbortDelay 0 #define INCLUDE_xTaskGetHandle 0 #define INCLUDE_xTaskResumeFromISR 1

/* A header file that defines trace macro can be included here. */

#endif /* FREERTOS_CONFIG_H */

This is the platformio.ini I'm using:

[env:pico]
platform = raspberrypi
board = pico
monitor_speed = 115200

This is the portmacro.h I'm using, I'm not sure if this one is correct for the PicoW, I searched the internet and found that the Pico uses an ARM-Cortex M0 processor so I assumed this is the correct portmacro:

/*
 * FreeRTOS Kernel V10.4.6
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * https://www.FreeRTOS.org
 * https://github.com/FreeRTOS
 *
 */

#ifndef PORTMACRO_H #define PORTMACRO_H

#ifdef __cplusplus
    extern "C" {
#endif

/*-----------------------------------------------------------

  • Port specific definitions.
  • The settings in this file configure FreeRTOS correctly for the
  • given hardware and compiler.
  • These settings should not be altered.

----------------------------------------------------------- /

/* Type definitions. */ #define portCHAR char #define portFLOAT float #define portDOUBLE double #define portLONG long #define portSHORT short #define portSTACK_TYPE uint32_t #define portBASE_TYPE long

typedef portSTACK_TYPE   StackType_t;
typedef long             BaseType_t;
typedef unsigned long    UBaseType_t;

#if ( configUSE_16_BIT_TICKS == 1 )
    typedef uint16_t     TickType_t;
    #define portMAX_DELAY              ( TickType_t ) 0xffff
#else
    typedef uint32_t     TickType_t;
    #define portMAX_DELAY              ( TickType_t ) 0xffffffffUL

/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do

  • not need to be guarded with a critical section. */ #define portTICK_TYPE_IS_ATOMIC 1 #endif

/-----------------------------------------------------------/

/* Architecture specifics. / #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD attribute( ( used ) ) /-----------------------------------------------------------*/

/* Scheduler utilities. / extern void vPortYield( void ); #define portNVIC_INT_CTRL_REG ( ( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portYIELD() vPortYield() #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /-----------------------------------------------------------/

/* Critical section management. */ extern void vPortEnterCritical( void ); extern void vPortExitCritical( void ); extern uint32_t ulSetInterruptMaskFromISR( void ) attribute( ( naked ) ); extern void vClearInterruptMaskFromISR( uint32_t ulMask ) attribute( ( naked ) );

#define portSET_INTERRUPT_MASK_FROM_ISR()         ulSetInterruptMaskFromISR()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x )    vClearInterruptMaskFromISR( x )
#define portDISABLE_INTERRUPTS()                  __asm volatile ( &quot; cpsid i &quot; ::: &quot;memory&quot; )
#define portENABLE_INTERRUPTS()                   __asm volatile ( &quot; cpsie i &quot; ::: &quot;memory&quot; )
#define portENTER_CRITICAL()                      vPortEnterCritical()
#define portEXIT_CRITICAL()                       vPortExitCritical()

/-----------------------------------------------------------/

/* Tickless idle/low power functionality. / #ifndef portSUPPRESS_TICKS_AND_SLEEP extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #endif /-----------------------------------------------------------*/

/* Task function macros as described on the FreeRTOS.org WEB site. / #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )

#define portNOP()

#define portMEMORY_BARRIER()    __asm volatile ( &quot;&quot; ::: &quot;memory&quot; )

#ifdef __cplusplus
    }
#endif

#endif /* PORTMACRO_H */

Code I'm trying to upload:

#include <FreeRTOS.h>
#include <task.h>
#include <stdio.h>
#include <time.h>

//Overload happens if xTaskGetTickCount – lastTickCount (the first parm to vTaskDelayUntil) is >= period in ticks

void delay(int number_of_seconds) { // Converting time into milli_seconds int milli_seconds = 1000 * number_of_seconds;

// Storing start time
clock_t start_time = clock();

// looping till required time is not achieved
while (clock() &lt; start_time + milli_seconds)
    ;

}

void task1(); void task2(); void task3();

int main() {

//Create tasks //xTaskCreate(Task function, Task name, , Task parameter, Task priority, );
xTaskCreate(task1, "task1", 128, NULL, 1, NULL); xTaskCreate(task2, "task2", 128, NULL, 2, NULL); xTaskCreate(task3, "task3", 128, NULL, 3, NULL); vTaskStartScheduler();

}

void loop() {}

void task1() {

TickType_t waketime, period = 10 / portTICK_PERIOD_MS;

waketime = xTaskGetTickCount();

while(1) {

printf(&quot;M&quot;); //This happens almost immediately, so we need to add an artificial delay, a  to simulate a task running for a few ms, it only serves as a notification that the task started
delay(100);
if(xTaskGetTickCount() - waketime &gt;= period) printf(&quot;Overload in task 1&quot;);
vTaskDelayUntil(&amp;waketime, period);

}

}

void task2() {

TickType_t waketime, period = 1000 / portTICK_PERIOD_MS;

waketime = xTaskGetTickCount();

while(1) {

printf(&quot;E&quot;); //This happens almost immediately, so we need to add an artificial delay, a  to simulate a task running for a few ms, it only serves as a notification that the task started
delay(10);
if(xTaskGetTickCount() - waketime &gt;= period) printf(&quot;Overload in task 2&quot;);
vTaskDelayUntil(&amp;waketime, period);

}

}

void task3() {

TickType_t waketime, period = 1000 / portTICK_PERIOD_MS;

waketime = xTaskGetTickCount();

while(1) {

printf(&quot;S&quot;); //This happens almost immediately, so we need to add an artificial delay, a  to simulate a task running for a few ms, it only serves as a notification that the task started
delay(10);
if(xTaskGetTickCount() - waketime &gt;= period) printf(&quot;Overload in task 3&quot;);
vTaskDelayUntil(&amp;waketime, period);

}

}

bro
  • 21
  • 2

0 Answers0