You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Raspberry Pi Pico CMake项目头文件引入及PIO I2C链接错误排查

Raspberry Pi Pico PIO I2C 链接错误解决

问题概述

在Raspberry Pi Pico项目中添加PIO I2C功能时,编译通过但出现链接错误,提示:undefined reference to pio_i2c_read_blocking(pio_hw_t*, unsigned int, unsigned char, unsigned char*, unsigned int)

错误日志

[main] Building folder: Ghidorah 
[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /home/varun/Projects/Ghidorah/build --config Debug --target all -j 10 --
[build] [  5%] Performing build step for 'PioasmBuild'
[build] [  5%] Built target bs2_default
[build] [  5%] Performing build step for 'ELF2UF2Build'
[build] [ 16%] Built target FreeRTOS-Kernel
[build] [ 18%] Built target bs2_default_padded_checksummed_asm
[build] [100%] Built target elf2uf2
[build] [100%] Built target pioasm
[build] [ 20%] No install step for 'ELF2UF2Build'
[build] [ 20%] No install step for 'PioasmBuild'
[build] [ 23%] Completed 'PioasmBuild'
[build] [ 23%] Completed 'ELF2UF2Build'
[build] [ 32%] Built target PioasmBuild
[build] [ 34%] Built target ELF2UF2Build
[build] [ 36%] Built target Ghidorah_i2c_pio_h
[build] [ 37%] Linking CXX executable Ghidorah.elf
[build] /usr/lib/gcc/arm-none-eabi/10.3.1/../../../arm-none-eabi/bin/ld: CMakeFiles/Ghidorah.dir/Sensors/mpu6050/source/mpu6050.cpp.obj: in function `scan()':
[build] /home/varun/Projects/Ghidorah/Sensors/mpu6050/source/mpu6050.cpp:32: undefined reference to `pio_i2c_read_blocking(pio_hw_t*, unsigned int, unsigned char, unsigned char*, unsigned int)'
[build] collect2: error: ld returned 1 exit status
[build] gmake[2]: *** [CMakeFiles/Ghidorah.dir/build.make:936: Ghidorah.elf] Error 1
[build] gmake[1]: *** [CMakeFiles/Makefile2:1496: CMakeFiles/Ghidorah.dir/all] Error 2
[build] gmake: *** [Makefile:91: all] Error 2
[proc] The command: /usr/bin/cmake --build /home/varun/Projects/Ghidorah/build --config Debug --target all -j 10 -- exited with code: 2
[build] Build finished with exit code 2

当前CMakeLists.txt内容

# Generated Cmake Pico project file

cmake_minimum_required(VERSION 3.13)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

# Initialise pico_sdk from installed location
# (note this can come from environment, CMake cache etc)
set(PICO_SDK_PATH "/home/varun/Dev-Tools/pico/pico-sdk")

set(PICO_BOARD pico CACHE STRING "Board type")

# Pull in Raspberry Pi Pico SDK (must be before project)
include(pico_sdk_import.cmake)

if (PICO_SDK_VERSION_STRING VERSION_LESS "1.4.0")
  message(FATAL_ERROR "Raspberry Pi Pico SDK version 1.4.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}")
endif()

add_compile_options(-Wall
        -Wno-format          # int != int32_t as far as the compiler is concerned because gcc has int32_t as long int
        -Wno-unused-function # we have some for the docs that aren't called
        -Wno-maybe-uninitialized
        -fpermissive
        )

project(Ghidorah C CXX ASM)

# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()

# Add executable. Default name is the project name, version 0.1

add_executable(Ghidorah Ghidorah.cpp 
        Sensors/mpu6050/source/mpu6050.cpp
        Sensors/mpu9250/source/mpu9250.cpp
        Sensors/adxl345/source/adxl345.cpp
        Sensors/lsm303dhlc/source/lsm303dhlc.cpp
        pio/pio_i2c.c)

pico_generate_pio_header(Ghidorah ${CMAKE_CURRENT_SOURCE_DIR}/pio/i2c.pio)

pico_set_program_name(Ghidorah "Ghidorah")
pico_set_program_version(Ghidorah "0.1")

pico_enable_stdio_uart(Ghidorah 1)
pico_enable_stdio_usb(Ghidorah 0)

# Add the standard library to the build
target_link_libraries(Ghidorah
        pico_stdlib
        pico_multicore)

# Add the standard include files to the build
target_include_directories(Ghidorah PRIVATE
        ${CMAKE_CURRENT_LIST_DIR}
        ${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts or any other standard includes, if required
        ${CMAKE_CURRENT_SOURCE_DIR}/

        #       SENSOR Sources
        ${CMAKE_CURRENT_SOURCE_DIR}/Sensors        
        ${CMAKE_CURRENT_SOURCE_DIR}/Sensors/mpu6050/
        ${CMAKE_CURRENT_SOURCE_DIR}/Sensors/mpu6050/include
        ${CMAKE_CURRENT_SOURCE_DIR}/Sensors/mpu9250/
        ${CMAKE_CURRENT_SOURCE_DIR}/Sensors/mpu9250/include
        ${CMAKE_CURRENT_SOURCE_DIR}/Sensors/adxl345/
        ${CMAKE_CURRENT_SOURCE_DIR}/Sensors/adxl345/include
        ${CMAKE_CURRENT_SOURCE_DIR}/Sensors/lsm303dhlc/
        ${CMAKE_CURRENT_SOURCE_DIR}/Sensors/lsm303dhlc/include
        
        #       PIO Sources
        ${CMAKE_CURRENT_SOURCE_DIR}/pio
        ${CMAKE_CURRENT_SOURCE_DIR}/pio/)

add_library(FreeRTOS-Kernel STATIC
        FreeRTOS-Kernel/event_groups.c
        FreeRTOS-Kernel/list.c
        FreeRTOS-Kernel/queue.c
        FreeRTOS-Kernel/stream_buffer.c
        FreeRTOS-Kernel/tasks.c
        FreeRTOS-Kernel/timers.c
        FreeRTOS-Kernel/portable/GCC/ARM_CM0/port.c
        FreeRTOS-Kernel/portable/Common/mpu_wrappers.c
        FreeRTOS-Kernel/portable/MemMang/heap_3.c)

target_include_directories(FreeRTOS-Kernel PUBLIC
        FreeRTOS-Kernel/
        FreeRTOS-Kernel/include/
        FreeRTOS-Kernel/portable/Common/
        FreeRTOS-Kernel/portable/GCC/
        FreeRTOS-Kernel/portable/GCC/ARM_CM0/
        FreeRTOS-Kernel/portable/MemMang/)

# Add any user requested libraries
target_link_libraries(Ghidorah
        hardware_dma
        hardware_gpio
        hardware_pio
        FreeRTOS-Kernel)

pico_add_extra_outputs(Ghidorah)

解决方案

链接错误的核心原因是C++代码调用C语言实现的函数时,未声明C语言链接约定,导致编译器按C++名字修饰规则查找函数,无法匹配C语言编译的函数符号。

具体修复步骤:

  1. 修改PIO I2C头文件:在声明pio_i2c_read_blocking的头文件(如pio_i2c.h)中,用extern "C"包裹所有函数声明,示例如下:
#ifdef __cplusplus
extern "C" {
#endif

// 所有PIO I2C相关函数声明
void pio_i2c_read_blocking(pio_hw_t* pio, uint sm, uint8_t addr, uint8_t* dst, size_t len);
// 其他函数声明...

#ifdef __cplusplus
}
#endif
  1. 确认源文件编译状态:pio_i2c.c是C语言文件,CMake会自动按C规则编译,且你的配置中已将其加入add_executable,这部分无需修改。

  2. 清理重建项目:删除build目录,重新运行CMake配置和编译,确保修改生效。

额外检查点:

  • 确认pio_i2c.c中pio_i2c_read_blocking的函数签名与头文件声明完全一致(参数类型、数量、返回值类型均需匹配)。
  • 若使用Pico SDK示例中的PIO I2C代码,需确保头文件已包含上述extern "C"声明。

内容的提问来源于stack exchange,提问作者varun koganti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 16:08:09