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

树莓派Pico C++开发:回调函数已声明却遭编译器作用域未声明报错

Raspberry Pi Pico C++ IRQ回调函数未声明问题解决

在Raspberry Pi Pico上使用C++配置IRQ时,编译代码出现回调函数“未在此作用域中声明”的错误,即便函数已定义且为全局函数。

原代码

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"

uint64_t time_between_triggers;
uint16_t times_triggered;

void shaft_speed_init(uint8_t _gpio_number, uint8_t _precision, uint8_t _counts_per_turn){
    gpio_set_irq_enabled_with_callback(2, GPIO_IRQ_EDGE_RISE, true, &_shaft_speed_gpio_callback);
}

void _shaft_speed_gpio_callback(uint16_t _gpio, uint32_t _event_mask) {
    uint64_t trigger_time;
    static uint64_t prev_trigger_time;

    trigger_time = to_us_since_boot(get_absolute_time());
    time_between_triggers = time_between_triggers + (trigger_time - prev_trigger_time);
    prev_trigger_time = trigger_time;
    times_triggered++;
}

编译错误信息

[main] Building folder: variable_rate_planter 
[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /home/taylor/Documents/Programs/Pi-Pico/variable_rate_planter/build --config Debug --target all --
[build] [2/8  12% :: 0.017] Performing build step for 'PioasmBuild'
[build] ninja: no work to do.
[build] [3/8  25% :: 0.026] Performing build step for 'ELF2UF2Build'
[build] ninja: no work to do.
[build] [4/8  37% :: 0.043] No install step for 'PioasmBuild'
[build] [5/8  50% :: 0.052] No install step for 'ELF2UF2Build'
[build] [6/8  62% :: 0.083] Completed 'PioasmBuild'
[build] [6/8  75% :: 0.095] Completed 'ELF2UF2Build'
[build] [7/8  87% :: 0.201] Building CXX object CMakeFiles/vrp.dir/main.cpp.obj
[build] FAILED: CMakeFiles/vrp.dir/main.cpp.obj 
[build] /usr/bin/arm-none-eabi-g++ -DCFG_TUSB_DEBUG=1 -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DCFG_TUSB_OS=OPT_OS_PICO -DLIB_PICO_BIT_OPS=1 -DLIB_PICO_BIT_OPS_PICO=1 -DLIB_PICO_DIVIDER=1 -DLIB_PICO_DIVIDER_HARDWARE=1 -DLIB_PICO_DOUBLE=1 -DLIB_PICO_DOUBLE_PICO=1 -DLIB_PICO_FIX_RP2040_USB_DEVICE_ENUMERATION=1 -DLIB_PICO_FLOAT=1 -DLIB_PICO_FLOAT_PICO=1 -DLIB_PICO_INT64_OPS=1 -DLIB_PICO_INT64_OPS_PICO=1 -DLIB_PICO_MALLOC=1 -DLIB_PICO_MEM_OPS=1 -DLIB_PICO_MEM_OPS_PICO=1 -DLIB_PICO_PLATFORM=1 -DLIB_PICO_PRINTF=1 -DLIB_PICO_PRINTF_PICO=1 -DLIB_PICO_RUNTIME=1 -DLIB_PICO_STANDARD_LINK=1 -DLIB_PICO_STDIO=1 -DLIB_PICO_STDIO_USB=1 -DLIB_PICO_STDLIB=1 -DLIB_PICO_SYNC=1 -DLIB_PICO_SYNC_CORE=1 -DLIB_PICO_SYNC_CRITICAL_SECTION=1 -DLIB_PICO_SYNC_MUTEX=1 -DLIB_PICO_SYNC_SEM=1 -DLIB_PICO_TIME=1 -DLIB_PICO_UNIQUE_ID=1 -DLIB_PICO_UTIL=1 -DPICO_BOARD="pico" -DPICO_BUILD=1 -DPICO_CMAKE_BUILD_TYPE="Debug" -DPICO_COPY_TO_RAM=0 -DPICO_CXX_ENABLE_EXCEPTIONS=0 -DPICO_NO_FLASH=0 -DPICO_NO_HARDWARE=0 -DPICO_ON_DEVICE=1 -DPICO_TARGET_NAME="vrp" -DPICO_USE_BLOCKED_RAM=0 -I/home/taylor/pico/pico-sdk/src/common/pico_stdlib/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_gpio/include -I/home/taylor/pico/pico-sdk/src/common/pico_base/include -I/home/taylor/Documents/Programs/Pi-Pico/variable_rate_planter/build/generated/pico_base -I/home/taylor/pico/pico-sdk/src/boards/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_platform/include -I/home/taylor/pico/pico-sdk/src/rp2040/hardware_regs/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_base/include -I/home/taylor/pico/pico-sdk/src/rp2040/hardware_structs/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_claim/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_sync/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_irq/include -I/home/taylor/pico/pico-sdk/src/common/pico_sync/include -I/home/taylor/pico/pico-sdk/src/common/pico_time/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_timer/include -I/home/taylor/pico/pico-sdk/src/common/pico_util/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_uart/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_divider/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_runtime/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_clocks/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_resets/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_pll/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_vreg/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_watchdog/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_xosc/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_printf/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_bootrom/include -I/home/taylor/pico/pico-sdk/src/common/pico_bit_ops/include -I/home/taylor/pico/pico-sdk/src/common/pico_divider/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_double/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_int64_ops/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_float/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_malloc/include -I/home/taylor/pico/pico-sdk/src/rp2_common/boot_stage2/include -I/home/taylor/pico/pico-sdk/src/common/pico_binary_info/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_stdio/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_stdio_usb/include -I/home/taylor/pico/pico-sdk/lib/tinyusb/src -I/home/taylor/pico/pico-sdk/lib/tinyusb/src/common -I/home/taylor/pico/pico-sdk/lib/tinyusb/hw -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_unique_id/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_flash/include -I/home/taylor/pico/pico-sdk/src/common/pico_usb_reset_interface/include -mcpu=cortex-m0plus -mthumb -Og -g -ffunction-sections -fdata-sections -fno-exceptions -fno-unwind-tables -fno-rtti -fno-use-cxa-atexit -MD -MT CMakeFiles/vrp.dir/main.cpp.obj -MF CMakeFiles/vrp.dir/main.cpp.obj.d -o CMakeFiles/vrp.dir/main.cpp.obj -c /home/taylor/Documents/Programs/Pi-Pico/variable_rate_planter/main.cpp
[build] In file included from /home/taylor/Documents/Programs/Pi-Pico/variable_rate_planter/main.cpp:4:
[build] /home/taylor/Documents/Programs/Pi-Pico/variable_rate_planter/shaft_speed.h: In function 'void shaft_speed_init(uint8_t, uint8_t, uint8_t)':
[build] /home/taylor/Documents/Programs/Pi-Pico/variable_rate_planter/shaft_speed.h:9:70: error: '_shaft_speed_gpio_callback' was not declared in this scope
[build]     9 |     gpio_set_irq_enabled_with_callback(2, GPIO_IRQ_EDGE_RISE, true, &_shaft_speed_gpio_callback);
[build]       |                                                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~
[build] ninja: build stopped: subcommand failed.
[proc] The command: /usr/bin/cmake --build /home/taylor/Documents/Programs/Pi-Pico/variable_rate_planter/build --config Debug --target all -- exited with code: 1 and signal: null
[build] Build finished with exit code 1

问题原因与解决方法

原因

C/C++编译规则要求:使用函数前必须先有声明或定义。原代码中shaft_speed_init调用_shaft_speed_gpio_callback时,该回调函数的定义在shaft_speed_init之后,编译器此时还未识别到该函数,因此报错。

另外从错误信息看,shaft_speed_init定义在头文件shaft_speed.h中,但回调函数仅在.cpp文件里有定义,头文件未声明该函数,导致包含头文件的编译单元找不到回调函数原型。

解决方法

方法1:添加函数原型声明

在shaft_speed_init函数之前,添加回调函数的原型声明,让编译器提前知晓函数存在:

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"

uint64_t time_between_triggers;
uint16_t times_triggered;

// 声明回调函数原型
void _shaft_speed_gpio_callback(uint16_t _gpio, uint32_t _event_mask);

void shaft_speed_init(uint8_t _gpio_number, uint8_t _precision, uint8_t _counts_per_turn){
    gpio_set_irq_enabled_with_callback(2, GPIO_IRQ_EDGE_RISE, true, &_shaft_speed_gpio_callback);
}

void _shaft_speed_gpio_callback(uint16_t _gpio, uint32_t _event_mask) {
    uint64_t trigger_time;
    static uint64_t prev_trigger_time;

    trigger_time = to_us_since_boot(get_absolute_time());
    time_between_triggers = time_between_triggers + (trigger_time - prev_trigger_time);
    prev_trigger_time = trigger_time;
    times_triggered++;
}

方法2:分文件编写时补充头文件声明

如果采用头文件(.h)和源文件(.cpp)分离结构,需在shaft_speed.h中添加回调函数声明:

// shaft_speed.h
#ifndef SHAFT_SPEED_H
#define SHAFT_SPEED_H

#include "pico/stdlib.h"
#include "hardware/gpio.h"

extern uint64_t time_between_triggers;
extern uint16_t times_triggered;

// 声明回调函数
void _shaft_speed_gpio_callback(uint16_t _gpio, uint32_t _event_mask);
void shaft_speed_init(uint8_t _gpio_number, uint8_t _precision, uint8_t _counts_per_turn);

#endif // SHAFT_SPEED_H

之后在对应的.cpp文件中实现两个函数即可,这样所有包含shaft_speed.h的编译单元都能找到回调函数原型,不会出现未声明错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:01:09