操作系统嵌入式RTOS嵌入式OS【免费下载链接】FreeRTOS-KernelFreeRTOS kernel files only, submoduled into https://github.com/FreeRTOS/FreeRTOS and various other repos.项目地址https://gitcode.com/GitHub_Trending/fr/FreeRTOS-Kernel点击查看免费下载本指南以 portable/ThirdParty/GCC/RP2040/README.md 为骨架系统讲解 FreeRTOS-Kernel 官方为 Raspberry Pi PicoRP2040 双核 Cortex-M0提供的 SMP对称多处理移植版本如何在基于 Raspberry Pi Pico SDK 的 CMake 工程中引入内核、如何将任务运行在 core 0 / core 1 / 双核、如何让 FreeRTOS 任务与 pico_sync / pico_time 等 SDK 原语互通以及rp2040_config.h中的底层配置项。读完本文你将能够在 Pico 工程里完整落地 FreeRTOS SMP 移植并理解其 CMake 集成机制与源码级实现原理。Overview这是一个什么样的移植portable/ThirdParty/GCC/RP2040目录提供了可与 Raspberry Pi Pico SDK 配合使用的 SMP 版 FreeRTOS-Kernel 移植。它支持的三个核心特性均来自 README纯 CMake INTERFACE 库集成以简单、非拷贝的方式同时提供 FreeRTOS-Kernel 与各堆分配器heap allocator无需把内核代码复制进用户工程。双核调度内核与任务可以运行在 core 0、core 1或同时运行在两个核心上configNUMBER_OF_CORES控制。SDK 同步原语互通FreeRTOS 任务可以与运行在非 FreeRTOS 核心上的代码、或 IRQ 中断处理程序之间使用 SDK 的同步原语如 pico_sync 的 mutex、semaphore、queue。需要特别说明的是这个 SMP 版本也可以只跑在单核任意一个核心上但如果你的场景只是单核官方建议改用主分支中的非 SMP 移植版本效率通常更高。这一建议在 README 中明确写出理由是单核场景下 SMP 移植携带的双核同步与自旋锁开销并非必要。目录结构速览该移植的完整文件布局如下portable/ThirdParty/GCC/RP2040/ ├── CMakeLists.txt # 顶层 CMake 入口负责定位 SDK 与内核 ├── FreeRTOS_Kernel_import.cmake # 可拷贝进用户工程的导入脚本 ├── library.cmake # 定义各 INTERFACE 库目标内核、堆、静态分配 ├── pico_sdk_import.cmake # 用于拉取 Pico SDK ├── port.c # 端口核心实现调度器启动、上下文切换、SysTick、互操作 ├── LICENSE.md ├── README.md └── include/ ├── freertos_sdk_config.h # SDK - FreeRTOS 互操作桥接配置 ├── portmacro.h # 端口类型、临界区、自旋锁、多核宏定义 └── rp2040_config.h # 本移植特有的 config 配置项其中portmacro.h与rp2040_config.h定义了端口级宏port.c约 1160 行承载了从xPortStartScheduler到xPortSysTickHandler的全部底层实现是理解本移植工作原理的关键文件。Using this port三种方式将移植引入你的工程方式一拷贝 import 脚本推荐将 FreeRTOS_Kernel_import.cmake 拷贝到你的工程中然后在CMakeLists.txt中添加include(FreeRTOS_Kernel_import.cmake)该脚本会按以下优先级定位 FreeRTOS 内核对应脚本中 FreeRTOS_Kernel_import.cmake 的逻辑环境变量FREERTOS_KERNEL_PATH或 CMake 命令行参数-DFREERTOS_KERNEL_PATH/path/to/FreeRTOS-Kernel显式指定优先级最高如果 import 脚本本身位于 FreeRTOS-Kernel 仓库树内即直接 include 了仓库中的文件则自动按相对路径反推出FREERTOS_KERNEL_PATH若PICO_SDK_PATH已定义且其同级目录存在FreeRTOS-Kernel即 SDK 与内核并排布局自动默认到该路径在以Source、FreeRTOS-Kernel、FreeRTOS/Source命名的子目录中搜索内核以上均失败则输出FATAL_ERROR提示你设置FREERTOS_KERNEL_PATH。脚本内部对PICO_PLATFORM进行了分支rp2040平台使用portable/ThirdParty/GCC/RP2040rp2350-riscv与其余 RP2350 平台会分别指向对应的RP2350_RISC-V/RP2350_ARM_NTZ移植目录。最终通过add_subdirectory(... FREERTOS_KERNEL)将移植与内核接入构建。Pico SDK 版本相关的放置约束务必注意若使用1.3.1 或更早的 Raspberry Pi Pico SDKinclude(FreeRTOS_Kernel_import.cmake)这行必须出现在pico_sdk_init()之前此时 FreeRTOS 会被包含/要求进工程中所有 RP2040 target即全局生效。若使用1.3.2 及之后的 SDK可以在 CMake 构建的稍后阶段甚至子目录中再引入 FreeRTOS-Kernel 支持此时支持仅作用于显式包含 FreeRTOS 支持的那些 target。这一版本差异在 CMakeLists.txt 的源码中有直接体现当检测到_pico_sdk_inclusion_markertarget 存在即 SDK 已初始化时要求 SDK 版本至少 1.3.2 才能直接在pico_sdk_init()之后加载否则将library.cmake追加到PICO_SDK_POST_LIST_FILES在pico_sdk_init()结束时由 SDK 回调执行。此外当 SDK 版本低于 1.3.2 时会把 freertos_sdk_config.h 注入PICO_CONFIG_HEADER_FILES使全部 SDK 文件都能感知 FreeRTOS 配置。方式二add_subdirectory 直接加入作为include语句的替代方案可以直接将该目录加入构建与上述 Pico SDK 版本的放置限制相同add_subdirectory(path/to/this/directory FreeRTOS-Kernel)同样地若此时代码在 SDK 已初始化后加入CMakeLists.txt 会通过library.cmake立即注册库目标若在pico_sdk_init()之前加入则由 SDK 的 POST_LIST 机制延迟注册。CMakeLists.txt中还要求 SDK 版本不低于 1.2.0否则直接FATAL_ERROR中止构建。方式三作为内核子模块README 指出该目录是 FreeRTOS 官方仓库布局的一部分——FreeRTOS-Kernel 常作为子模块被引入各类工程。import 脚本第一行注释即说明This is a copy of FREERTOS_KERNEL_PATH/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake它既可被直接 include也可通过add_subdirectory使用。若内核是工程的一个直接子模块sub-moduleimport 脚本的自动定位逻辑第 2 步路径反推即可工作无需手工指定路径。import 脚本与 CMakeLists 的版本门槛小结场景最低 Pico SDK 版本说明顶层引入pico_sdk_init()之前1.2.0CMakeLists.txt 中强制检查pico_sdk_init()之后引入子目录/后续阶段1.3.2否则FATAL_ERRORimport 脚本放置位置1.3.1 及更早必须放在pico_sdk_init()前全局生效1.3.2 可延后链接哪些库FreeRTOS-Kernel、堆分配器与静态分配引入移植后library.cmake 会为你注册一组 INTERFACE 库目标全部无需拷贝源码、直接以 target 形式链接目标名作用FreeRTOS-Kernel-Core内核核心源码croutine.c、event_groups.c、list.c、queue.c、stream_buffer.c、tasks.c、timers.c并指向仓库根目录的includeFreeRTOS-Kernel移植层port.cinclude/链接 pico_base_headers、hardware_clocks、hardware_exception、pico_multicore定义LIB_FREERTOS_KERNEL1与FREE_RTOS_KERNEL_SMP1FreeRTOS-Kernel-Static静态分配支持configSUPPORT_STATIC_ALLOCATION1、configKERNEL_PROVIDED_STATIC_MEMORY1FreeRTOS-Kernel-Heap1~FreeRTOS-Kernel-Heap5分别链接 portable/MemMang/heap_1.c ~ heap_5.c 五种堆分配器例如要在任务中动态创建对象可在target_link_libraries中同时链接FreeRTOS-Kernel与FreeRTOS-Kernel-Heap4heap_4 是使用最广泛的通用分配器若整个工程使用静态分配则链接FreeRTOS-Kernel-Static。port.c编译时由 SDK 1.3.2 提供的PICO_CONFIG_RTOS_ADAPTER_HEADER机制引入 freertos_sdk_config.h从而让 SDK 侧代码也能感知 FreeRTOS 的互操作配置。让任务跑在哪个核心SMP 调度的实现机制configNUMBER_OF_CORES决定调度器运行在单核还是双核。从 portmacro.h 可以看到portMAX_CORE_COUNT固定为2RP2040 双 Cortex-M0 核心若configNUMBER_OF_CORES超出[1, 2]范围会在编译期#errorconfigNUMBER_OF_CORES 2时portGET_CORE_ID()映射到 SDK 的get_core_num()单核时恒为0。调度器启动路径在 port.c 的xPortStartSchedulerSMP 分支中先通过spin_lock_claim声明两个自旋锁确认从 core 0 启动后调用multicore_reset_core1()与multicore_launch_core1(...)把第二个核心也拉进调度器再由vPortStartFirstTask()启动首个任务而configTICK_CORE指定由哪个核心承接 SysTick 中断——只有 primary core 会调用vPortSetupTimerInterrupt()配置 SysTick 并装载xPortSysTickHandler见 port.c。核心间同步依靠 RP2040 硬件自旋锁spin lock。configSMP_SPINLOCK_0/configSMP_SPINLOCK_1分别用于 ISR 锁与任务锁默认取 SDK 为 RTOS 预留的PICO_SPINLOCK_ID_OS1/PICO_SPINLOCK_ID_OS2。portmacro.h中的vPortRecursiveLock实现了可重入递归自旋锁同一核心重复加锁时仅递增递归计数上限 255超出触发configASSERT计数归零才真正释放自旋锁从而支持临界区的嵌套进入/退出。Advanced Configurationrp2040_config.h 中的底层配置项README 指出部分控制底层实现细节的额外config选项定义在 include/rp2040_config.h。该头文件在 freertos_sdk_config.h 中被一并引入其全部选项均可被用户在FreeRTOSConfig.h中预先定义以覆盖默认值配置项默认值含义configUSE_DYNAMIC_EXCEPTION_HANDLERS当PICO_NO_RAM_VECTOR_TABLE 1时为0否则为1是否在运行期通过 SDK 的exception_set_exclusive_handler为各核心动态安装异常处理函数PendSV / SysTick / SVC。若用户为每个核心设置了不同的向量表偏移RAM vector table需要置 1 动态装载若使用固定向量表则置 0此时portmacro.h会直接把端口处理函数替换为 SDK 的 weak 符号isr_pendsv、isr_systick、isr_svcallconfigSUPPORT_PICO_SYNC_INTEROP编译LIB_PICO_SYNC时默认为1使 SDK pico_sync 的 sem/mutex/queue 等原语在 FreeRTOS 任务中调用时行为正确。开启后freertos_sdk_config.h会重定义 SDK 锁实现的相关钩子lock_get_caller_owner_id、lock_internal_spin_unlock_with_wait/_with_notify/_with_best_effort_wait_or_timeout指向 port.c 中的端口实现configSUPPORT_PICO_TIME_INTEROP编译LIB_PICO_TIME时默认为1使 SDK pico_time 的sleep_ms/sleep_us/sleep_until在 FreeRTOS 任务中被调用时真正在 FreeRTOS 层阻塞而非忙等通过sync_internal_yield_until_before钩子调用 port.c 中的xPortSyncInternalYieldUntilBefore实现configTICK_CORE0仅configNUMBER_OF_CORES 1时生效指定哪个核心处理 SysTick 中断configSMP_SPINLOCK_0/configSMP_SPINLOCK_1PICO_SPINLOCK_ID_OS1/PICO_SPINLOCK_ID_OS2端口使用的两个硬件自旋锁编号ISR 锁与任务锁默认采用 SDK 为 RTOS 预留的编号通常无需修改其中configSUPPORT_PICO_SYNC_INTEROP开启后还有两个连锁效果见 freertos_sdk_config.h强制PICO_USE_MALLOC_MUTEX1malloc 需要线程安全并把PICO_TIME_SLEEP_OVERHEAD_ADJUST_US默认调整为150增加可能唤醒延迟的余量。而 portmacro.h 中的portUSE_DIVIDER_SAVE_RESTORE则由 SDK 的PICO_DIVIDER_DISABLE_INTERRUPTS决定——若硬件除法器未禁中断任务上下文切换时需保存/恢复除法器状态栈底填充portSTACK_LIMIT_PADDING相应设为4字节。与 SDK 原生 API 的互通要点本移植的一个突出价值是 FreeRTOS 任务与非 FreeRTOS 核心/中断上下文可以共用 SDK 同步原语。其实现路径如下pico_sync 互通开启configSUPPORT_PICO_SYNC_INTEROP后SDK 的lock_core系列宏被替换为端口实现。freertos_sdk_config.h将lock_owner_id_t定义为uint32_t并让lock_get_caller_owner_id()调用 port.c 中的ulPortLockGetCurrentOwnerId()同时以LOCK_INVALID_OWNER_ID (uint32_t)-1标记无主状态。这样当 FreeRTOS 任务获取 SDK mutex 时端口能正确登记当前核心/任务身份并在释放时唤醒等待者。pico_time 互通开启configSUPPORT_PICO_TIME_INTEROP后sync_internal_yield_until_before(t)被替换为xPortSyncInternalYieldUntilBefore(t)使sleep_ms等函数在 FreeRTOS 任务中通过内核阻塞阻塞到指定absolute_time_t而不是占用 CPU 忙等。需要注意的是这些互通依赖 IRQ FIFO 中断prvFIFOInterruptHandler在 port.c 中调度器启动时会multicore_fifo_clear_irq()/multicore_fifo_drain()随后为当前核心安装SIO_IRQ_PROC0 get_core_num()的独占中断处理程序用于接收来自另一核心的唤醒通知IRQ 优先级设为portMIN_INTERRUPT_PRIORITY 255。核心配置建议与注意事项SMP 开关在FreeRTOSConfig.h中设置configNUMBER_OF_CORES1 或 2与configTICK_CORE。SMP 移植要求configNUMBER_OF_CORES取值合法portmacro.h 有编译期检查双核时portGET_CORE_ID()才映射真实核心号。临界区差异单核与双核的临界区宏不同——单核configNUMBER_OF_CORES 1走vPortEnterCritical/vPortExitCritical双核走vTaskEnterCritical/vTaskExitCritical及FromISR变体并配合两个递归自旋锁保护 ISR 与任务调度状态见 portmacro.h。tick 类型TickType_t由configTICK_TYPE_WIDTH_IN_BITS决定16 位时为uint16_t、portMAX_DELAY 0xffff32 位时为uint32_t、portMAX_DELAY 0xffffffffUL。32 位 tick 在 32 位架构上读写是原子的portTICK_TYPE_IS_ATOMIC1无需临界区保护。静态分配若使用FreeRTOS-Kernel-Static内核会自动提供静态内存configKERNEL_PROVIDED_STATIC_MEMORY1配合configSUPPORT_STATIC_ALLOCATION1即可免去堆分配器。Known Limitations已知限制README 明确列出本移植目前唯一的已知限制Tickless idle 尚未经过测试很可能不可用Tickless idle has not currently been tested, and is likely non-functional。也就是说低功耗的空闲 tick 抑制模式configUSE_TICKLESS_IDLE 1触发的portSUPPRESS_TICKS_AND_SLEEP在 port.c 中虽有条件编译的实现骨架但官方未验证、不建议在正式产品中直接依赖。如需低功耗请等待官方后续验证或在深入测试vPortSuppressTicksAndSleep行为后再启用。小结FreeRTOS-Kernel 的 RP2040 SMP 移植是一套「零拷贝、纯 CMake INTERFACE 库」的现代集成方案通过include(FreeRTOS_Kernel_import.cmake)或add_subdirectory即可接入基于 Pico SDK 的工程再链接FreeRTOS-Kernel 任选 Heap1~5即获得运行在单核/双核上的完整内核rp2040_config.h中的少量配置项控制异常处理器装载方式、pico_sync/pico_time 互通与自旋锁编号已知限制为 tickless idle 未经验证。理解 port.c、portmacro.h 与 library.cmake 的实现能帮助你在遇到调度或同步问题时有据可查、快速定位。赞分享操作系统嵌入式RTOS嵌入式OS【免费下载链接】FreeRTOS-KernelFreeRTOS kernel files only, submoduled into https://github.com/FreeRTOS/FreeRTOS and various other repos.项目地址https://gitcode.com/GitHub_Trending/fr/FreeRTOS-Kernel点击查看免费下载相关推荐深入解析仓颉 stringbuilder 架构StringBuilder 工具类目录结构、接口设计与工程实践指南深入解析仓颉 stringbuilder 架构StringBuilder 工具类目录结构、接口设计与工程实践指南 stringbuilder 是一个 更自由、并发编程vue-admin-better 组件库怎么选省 230KB、表格快 33%实测告诉你答案vue admin better 组件库怎么选省 230KB、表格快 33%实测告诉你答案 管理后台首屏白屏 3 秒、大表格滚到第 50 行就掉帧——这就是嵌入式硬件开发ggwave 在 RP2040 上的声音数据接收实战基于 Raspberry Pi Pico 的 rp2040-rx 示例全解析ggwave 在 RP2040 上的声音数据接收实战基于 Raspberry Pi Pico 的 rp2040 rx 示例全解析 导读 本文以 ggwave通信物联网嵌入式上一篇为什么这款开源工具能让你的网盘下载速度翻倍八大网盘直链解析实战指南下一篇Ryujinx 使用指南从安装到性能调优的 5 步实操教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考