RP2040移植FreeRTOS
准备材料
rp2040
Raspberry Pi Pico SDK raspberrypi/pico-sdk (github.com)
Pico VS Code
FreeRTOS-Kernel Release V11.1.0 · FreeRTOS/FreeRTOS-Kernel (github.com)
创建rp2040开发工程
从Raspberry Pi Pico SDK复制pico_sdk_import.cmake到工程目录
copy ${env:PICO_SDK_PATH}\external\pico_sdk_import.cmake .
将 Pico SDK 示例中的 VS Code 配置复制到项目中
copy ${env:PICO_EXAMPLES_PATH}\.vscode . -recurse
创建
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
# Name project
SET(ProjectName rp2040-freertos-demo)
include(pico_sdk_import.cmake)
# Define project
project(${ProjectName} C CXX ASM)
# initialize the Raspberry Pi Pico SDK
pico_sdk_init()
创建代码
例如新建文件夹src
并新建main.c
#include <stdio.h>
#include "pico/stdlib.h"
int main() {
setup_default_uart();
printf("Hello, world!\n");
return 0;
}
在src
文件夹下创建CMakeLists.txt
add_executable(main main.c)
# Add pico_stdlib library which aggregates commonly used features
target_link_libraries(${ProjectName} pico_stdlib)
# create map/bin/hex/uf2 file in addition to ELF.
pico_add_extra_outputs(${ProjectName})
在工程
文件夹下的CMakeLists.txt
添加
add_subdirectory(src)
完整的CMakeLists.txt
如下
cmake_minimum_required(VERSION 3.13)
# Name project
SET(ProjectName rp2040-freertos-demo)
include(pico_sdk_import.cmake)
# Define project
project(${ProjectName} C CXX ASM)
# initialize the Raspberry Pi Pico SDK
pico_sdk_init()
add_subdirectory(src)
通过运行 CMake: Configure 命令来配置项目
为rp2040开发工程添加FerrRTOS
在工程目录下新建
lib
文件夹,并将下载的FreeRTOS-Kernel源码解压到lib
目录下在工程目录下的
CMakeLists.txt
添加
SET(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib/FreeRTOS-Kernel)
include(${FREERTOS_KERNEL_PATH}/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake)
在
src
目录下的CMakeLists.txt
添加
target_include_directories(${ProjectName} PRIVATE
${CMAKE_CURRENT_LIST_DIR}
)
target_link_libraries(${ProjectName}
pico_stdlib
FreeRTOS-Kernel-Heap4
)
4.在src
目录下的创建FreeRTOSConfig.h
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html
*----------------------------------------------------------*/
/* Scheduler Related */
#define configUSE_PREEMPTION 1
#define configUSE_TICKLESS_IDLE 0
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configCPU_CLOCK_HZ ((unsigned long)125000000)
#define configMAX_PRIORITIES 32
#define configMINIMAL_STACK_SIZE ( configSTACK_DEPTH_TYPE ) 256
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
/* Synchronization Related */
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configUSE_QUEUE_SETS 1
#define configUSE_TIME_SLICING 1
#define configUSE_NEWLIB_REENTRANT 0
// todo need this for lwip FreeRTOS sys_arch to compile
#define configENABLE_BACKWARD_COMPATIBILITY 1
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
/* System */
#define configSTACK_DEPTH_TYPE uint32_t
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
/* Memory allocation related definitions. */
#define configSUPPORT_STATIC_ALLOCATION 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTOTAL_HEAP_SIZE (128*1024)
#define configAPPLICATION_ALLOCATED_HEAP 0
/* Hook function related definitions. */
#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 1
#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 ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH 1024
/* Interrupt nesting behaviour configuration. */
/*
#define configKERNEL_INTERRUPT_PRIORITY [dependent of processor]
#define configMAX_SYSCALL_INTERRUPT_PRIORITY [dependent on processor and application]
#define configMAX_API_CALL_INTERRUPT_PRIORITY [dependent on processor and application]
*/
#if FREE_RTOS_KERNEL_SMP // set by the RP2040 SMP port of FreeRTOS
/* SMP port only */
#define configNUMBER_OF_CORES 2
#define configTICK_CORE 0
#define configRUN_MULTIPLE_PRIORITIES 1
#endif
#if (configNUMBER_OF_CORES > 1 )
#define configUSE_CORE_AFFINITY 1
#define configUSE_MINIMAL_IDLE_HOOK 0
#define configUSE_PASSIVE_IDLE_HOOK 0
#endif
/* RP2040 specific */
#define configSUPPORT_PICO_SYNC_INTEROP 1
#define configSUPPORT_PICO_TIME_INTEROP 1
#include <assert.h>
/* Define to trap errors during development. */
#define configASSERT(x) assert(x)
/* 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_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_xTaskResumeFromISR 1
#define INCLUDE_xQueueGetMutexHolder 1
#endif /* FREERTOS_CONFIG_H */
测试
#include "FreeRTOS.h"
#include "task.h"
#include <stdio.h>
#include "pico/stdlib.h"
void led_task()
{
const uint LED_PIN = 23;
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
while (true) {
gpio_put(LED_PIN, 1);
vTaskDelay(1000);
gpio_put(LED_PIN, 0);
vTaskDelay(1000);
}
}
int main()
{
stdio_init_all();
xTaskCreate(led_task, "LED_Task", 256, NULL, 1, NULL);
vTaskStartScheduler();
while(1){};
}
在FerrRTOS使用RP2040多核
FreeRTOS 支持对称多处理 (Symmetric Multiprocessing, SMP) 的功能
SMP 允许 FreeRTOS 操作系统在多个 CPU 核心上运行,使多个任务能够并行处理,提高系统的并发性和性能
#if FREE_RTOS_KERNEL_SMP // set by the RP2040 SMP port of FreeRTOS
/* SMP port only */
#define configNUMBER_OF_CORES 2
#define configTICK_CORE 0
#define configRUN_MULTIPLE_PRIORITIES 1
#endif
#include "FreeRTOS.h"
#include "task.h"
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"
void led_task()
{
const uint LED_PIN = 23;
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
while (true) {
gpio_put(LED_PIN, 1);
vTaskDelay(500);
gpio_put(LED_PIN, 0);
vTaskDelay(500);
}
}
void uart_task()
{
const char *message = "uart_task!";
while (true) {
printf(message);
vTaskDelay(1000);
}
}
int main()
{
stdio_init_all();
TaskHandle_t led_task_Handle = NULL;
TaskHandle_t uart_task_Handle = NULL;
xTaskCreate(led_task, "LED_Task", 256, NULL, 1, &led_task_Handle);
xTaskCreate(uart_task, "UART_Task", 256, NULL, 1, &uart_task_Handle);
UBaseType_t task1_CoreAffinityMask = (1 << 0);
UBaseType_t task0_CoreAffinityMask = (1 << 1);
vTaskCoreAffinitySet(led_task_Handle, task1_CoreAffinityMask);
vTaskCoreAffinitySet(uart_task_Handle, task0_CoreAffinityMask);
vTaskStartScheduler();
while(1){};
}
将RP2040的USB虚拟为串口,在src
目录下的CMakeLists.txt
添加
在主函数中调用stdio_init_all();
初始化
这样就可以通过printf将数据输出到串口
pico_enable_stdio_usb(${ProjectName} 1)
pico_enable_stdio_uart(${ProjectName} 0)
逻辑分析仪测得LED的闪烁间隔500ms,并且通过串口助手接收到RP2040发送的数据
评论区