侧边栏壁纸
博主头像
李振洋的博客博主等级

歌颂动荡的青春

  • 累计撰写 38 篇文章
  • 累计创建 6 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

RP2040移植FreeRTOS

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开发工程

  1. 从Raspberry Pi Pico SDK复制pico_sdk_import.cmake到工程目录

copy ${env:PICO_SDK_PATH}\external\pico_sdk_import.cmake .
  1. 将 Pico SDK 示例中的 VS Code 配置复制到项目中

copy ${env:PICO_EXAMPLES_PATH}\.vscode . -recurse
  1. 创建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()
  1. 创建代码

例如新建文件夹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)
  1. 通过运行 CMake: Configure 命令来配置项目

rp2040开发工程添加FerrRTOS

  1. 在工程目录下新建lib 文件夹,并将下载的FreeRTOS-Kernel源码解压到lib 目录下

  2. 在工程目录下的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)
  1. 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 */
  1. 测试

#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发送的数据

0

评论区