树莓派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
相关产品推荐
相关产品推荐

