0. 参考

https://github.com/raspberrypi/pico-sdk


1. 背景

在RP2040芯片上,基于FreeRTOS开发一个项目,那么至少依赖两个组件:

  • RP2040的SDK
  • FreeRTOS内核及RP2040移植层

这两个组件有官方维护的开源代码仓库,我们将把它们作为开源组件引入到自己的项目中。

假设目录结构如下(注意,引用的开源组件的目录不要创建,在后文使用submodule创建)

.
├── freertos    (open source)
├── rp2040_sdk  (open source)
├── include
│   └── FreeRTOSConfig.h
├── main.c
└── CMakeLists.txt

2. 拉取开源代码

安装编译工具链。(命令来自pico-sdk官方文档,根据需要自行安装)

sudo apt install cmake python3 build-essential gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib

在项目的根目录下,添加submodule,并拉取代码。这里指定的目录名是分别用来存放两个开源仓库的代码的。

git submodule add https://github.com/FreeRTOS/FreeRTOS-Kernel.git freertos
git submodule add https://github.com/raspberrypi/pico-sdk.git rp2040_sdk
git submodule update --init

3. 适配文件

3.1 FreeRTOS配置文件

pico-examples官方仓库为FreeRTOS适配的配置文件FreeRTOSConfig.h拷贝一份到你自己的项目include目录中,作为初始模版,后续开发可以再修改里面的配置。

.
├── freertos
├── rp2040_sdk
├── include
│   └── FreeRTOSConfig.h
├── main.c
└── CMakeLists.txt

3.2 CMake

在项目的根目录的CMakeLists.txt写入以下内容。

cmake_minimum_required(VERSION 3.13...3.27)
# note: this must happen before project()
# pico-sdk root directory
set(RP2040_SDK_PATH rp2040_sdk)
# FreeRTOS root directory
set(FREERTOS_PATH freertos)
# initialize pico-sdk and FreeRTOS from submodule
include(${RP2040_SDK_PATH}/pico_sdk_init.cmake)
include(${FREERTOS_PATH}/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake)

# project name
project(my_project)

# ======================= pico-sdk =======================
# initialize the Raspberry Pi Pico SDK
pico_sdk_init()

# ======================= FreeRTOS =======================
# create INTERFACE target: freertos_config
add_library(freertos_config INTERFACE)
target_include_directories(freertos_config SYSTEM
INTERFACE
include
)
target_compile_definitions(freertos_config
INTERFACE
projCOVERAGE_TEST=0
)

# create target: freertos_kernel
set( FREERTOS_HEAP "4" CACHE STRING "" FORCE)
# Select the native compile PORT
set( FREERTOS_PORT "GCC_POSIX" CACHE STRING "" FORCE)
# Select the cross-compile PORT
if (CMAKE_CROSSCOMPILING)
    set(FREERTOS_PORT "GCC_RP2040" CACHE STRING "" FORCE)
endif()
add_subdirectory(${FREERTOS_PATH})

# ======================= my code =======================
add_executable(${PROJECT_NAME}
    main.c
)

target_include_directories(${PROJECT_NAME}
PRIVATE
    include
)

target_link_libraries(${PROJECT_NAME}
    freertos_config
    freertos_kernel
    pico_stdlib
    pico_async_context_freertos
)

# create map/bin/hex/uf2 file in addition to ELF.
pico_add_extra_outputs(${PROJECT_NAME})
  • FREERTOS_HEAP是堆内存管理实现方法,1-5的区别可以参考官方文档,类型4是最常用的。
  • FREERTOS_PORT是移植层,根据需要在freertos代码中自行查找确认,我这里使用GCC_RP2040(注意,native compile port是为了在本机模拟运行的,不需要修改它)。

3.3 main.c

这里以pico-examples官方仓库为FreeRTOS适配的源文件hello_freertos.c为例,将其内容拷贝至本地的main.c


4. 构建

在项目的根目录,新建目录build(这个目录就是编译链接使用的临时目录,记得把它添加到.gitignore,避免diff),然后执行下面的命令进行编译和链接。

cd build
rm -rf * && cmake .. && make

最后可以看到很多文件,我们要烧录进flash里的,就是其中的.uf2文件。


5. 烧录

  1. 按住树莓派PICO上的BOOTSEL按钮,插入USB连接线,电脑会识别出新的存储设备。
  2. .uf2文件放入该存储设备,就会开始烧录文件,烧录完成后自动弹出设备。

6. 测试

观察main.c的示例代码可知,它创建了一个任务,通过GPIO_0控制LED闪烁,我们后续可以用一个LED连接到GPIO_0和GND来测试是否符合预期。