簡體   English   中英

為 Raspberry Pi Pico 創建 IRQ 可以在 C 中工作,但不能在 C++ 中工作?

[英]Creating an IRQ for the Raspberry Pi Pico works in C but not C++?

當我用 C 編譯這段代碼時,它運行得很好,但是當我嘗試用 C++ 編譯它時,它會發送一個錯誤,我將在下面添加該錯誤。 我已經嘗試用我能想到的每個變量類型聲明函數,但沒有改變任何東西。 我也在網上搜索,但沒有找到任何幫助。

代碼:

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

void gpio_callback() {
    printf("GPIO RISE\n");
}

int main() {
    stdio_init_all();

    printf("Hello GPIO IRQ\n");
    gpio_set_irq_enabled_with_callback(2, GPIO_IRQ_EDGE_RISE, true, &gpio_callback);

    // Wait forever
    while (1);

    return 0;
}

我的 C++ CMakeFile.txt:

cmake_minimum_required(VERSION 3.19)

include(pico_sdk_import.cmake)

project(hello_gpio_irq)

pico_sdk_init()

add_executable(hello_gpio_irq hello_gpio_irq.cpp)

pico_enable_stdio_usb(hello_gpio_irq 1)
pico_enable_stdio_uart(hello_gpio_irq 0)

# pull in common dependencies
target_link_libraries(hello_gpio_irq pico_stdlib)

# create map/bin/hex file etc.
pico_add_extra_outputs(hello_gpio_irq)

我的 C 的 CmakeLists.txt:

cmake_minimum_required(VERSION 3.19)

include(pico_sdk_import.cmake)

project(hello_gpio_irq)

pico_sdk_init()

add_executable(hello_gpio_irq hello_gpio_irq.c)

pico_enable_stdio_usb(hello_gpio_irq 1)
pico_enable_stdio_uart(hello_gpio_irq 0)

# pull in common dependencies
target_link_libraries(hello_gpio_irq pico_stdlib)

# create map/bin/hex file etc.
pico_add_extra_outputs(hello_gpio_irq)

C++ 的編譯器輸出:

[main] Building folder: hello_gpio_irq 
[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /home/taylor/Documents/Programs/Pi-Pico/hello_gpio_irq/build --config Debug --target all --
[build] [2/8  12% :: 0.025] Performing build step for 'ELF2UF2Build'
[build] ninja: no work to do.
[build] [3/8  25% :: 0.057] Performing build step for 'PioasmBuild'
[build] ninja: no work to do.
[build] [4/8  37% :: 0.071] No install step for 'ELF2UF2Build'
[build] [5/8  50% :: 0.110] No install step for 'PioasmBuild'
[build] [6/8  62% :: 0.149] Completed 'ELF2UF2Build'
[build] [7/8  75% :: 0.155] Completed 'PioasmBuild'
[build] [7/8  87% :: 0.267] Building CXX object CMakeFiles/hello_gpio_irq.dir/hello_gpio_irq.cpp.obj
[build] FAILED: CMakeFiles/hello_gpio_irq.dir/hello_gpio_irq.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=\"hello_gpio_irq\" -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/hello_gpio_irq/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/hello_gpio_irq.dir/hello_gpio_irq.cpp.obj -MF CMakeFiles/hello_gpio_irq.dir/hello_gpio_irq.cpp.obj.d -o CMakeFiles/hello_gpio_irq.dir/hello_gpio_irq.cpp.obj -c /home/taylor/Documents/Programs/Pi-Pico/hello_gpio_irq/hello_gpio_irq.cpp
[build] /home/taylor/Documents/Programs/Pi-Pico/hello_gpio_irq/hello_gpio_irq.cpp: In function 'int main()':
[build] /home/taylor/Documents/Programs/Pi-Pico/hello_gpio_irq/hello_gpio_irq.cpp:13:69: error: invalid conversion from 'void (*)()' to 'gpio_irq_callback_t' {aka 'void (*)(unsigned int, long unsigned int)'} [-fpermissive]
[build]    13 |     gpio_set_irq_enabled_with_callback(2, GPIO_IRQ_EDGE_RISE, true, &gpio_callback);
[build]       |                                                                     ^~~~~~~~~~~~~~
[build]       |                                                                     |
[build]       |                                                                     void (*)()
[build] In file included from /home/taylor/pico/pico-sdk/src/common/pico_stdlib/include/pico/stdlib.h:13,
[build]                  from /home/taylor/Documents/Programs/Pi-Pico/hello_gpio_irq/hello_gpio_irq.cpp:2:
[build] /home/taylor/pico/pico-sdk/src/rp2_common/hardware_gpio/include/hardware/gpio.h:440:107: note:   initializing argument 4 of 'void gpio_set_irq_enabled_with_callback(uint, uint32_t, bool, gpio_irq_callback_t)'
[build]   440 | void gpio_set_irq_enabled_with_callback(uint gpio, uint32_t event_mask, bool enabled, gpio_irq_callback_t callback);
[build]       |                                                                                       ~~~~~~~~~~~~~~~~~~~~^~~~~~~~
[build] ninja: build stopped: subcommand failed.
[proc] The command: /usr/bin/cmake --build /home/taylor/Documents/Programs/Pi-Pico/hello_gpio_irq/build --config Debug --target all -- exited with code: 1 and signal: null
[build] Build finished with exit code 1

void gpio_set_irq_enabled_with_callback (uint gpio, 
                                         uint32_t event_mask, 
                                         bool enabled,  
                                         gpio_irq_callback_t callback)

期望最后一個參數有一個gpio_irq_callback_t ,而gpio_irq_callback_t看起來像

typedef void(* gpio_irq_callback_t) (uint gpio, uint32_t event_mask)

所以gpio_set_irq_enabled_with_callback期望

void gpio_callback() {
    printf("GPIO RISE\n");
}

成為

void gpio_callback(uint /*gpio*/, uint32_t /*event_mask*/) {
    printf("GPIO RISE\n");
}

當您選擇使用它們時,您可以取消注釋參數名稱。 在您這樣做之前,您可能會收到未使用的參數警告。

這看起來只在 C 中有效,因為 C 會編譯它。 如果您將它們調得足夠大,您可能會收到警告,因為無法保證它在運行時會正確運行。 根據調用約定,結果可能是災難性的。 例如,如果被調用者負責從堆棧中彈出參數,則void ()不期望參數並且不會彈出任何內容。 調用者壓入堆棧的兩個參數將坐在那里,將堆棧扔掉並以不可預知的方式搞砸一切。 C++ 在匹配類型方面更加謹慎,並完全拒絕該函數,因此您得到的是編譯器錯誤,而不是警告或程序在運行時崩潰。

不要試圖用演員表來解決這個問題。 您可能只會將編譯器錯誤換成運行時的異常行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM