Search code examples
visual-studio-codeincludeesp32uartespressif-idf

Implicit declaration of function 'uart_isr_register' despite including library and espressif seeing the function and can shows me the definition


This is my first post here, so please let me know if I'm doing something wrong. I'm trying to create an interrupt-based UART receive task on my ESP32S3. It should be straightforward, but unfortunately, I'm encountering an issue. When I compile the code in Visual Studio Code in combination with the Espressif IDE, I get the following error: "implicit declaration of function 'uart_isr_register'; did you mean 'gpio_isr_register'?" To the best of my knowledge, this error typically occurs when a library is not found. However, I've included it with the line '#include "driver/uart.h," and if I go to the definition, it finds it perfectly in the UART code."

below my included libraries:

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "driver/uart.h"
#include "string.h"
#include "driver/gpio.h"
#include "stdbool.h"
#include "esp_attr.h"

and here the function where the error occurs:

void serialComInit(void){
    const uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };
    // We won't use a buffer for sending data.
    struct receiveDataObj rxObject[1];
    uart_param_config(UART_NUM_1, &uart_config);
    uart_set_pin(UART_NUM_1, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
    uart_driver_install(UART_NUM_1, RX_BUF_SIZE * 2, 0, 0, NULL, 0);
    uart_isr_register(UART_NUM_1, uart_rx_intr_handler, rxObject, ESP_INTR_FLAG_IRAM, NULL);
    uart_enable_rx_intr(UART_NUM_1);
}

the function it points to is shown below:

void IRAM_ATTR uart_rx_intr_handler(struct receiveDataObj *rxPtr){
    static const char *RX_TASK_TAG = "RX_TASK";
    esp_log_level_set(RX_TASK_TAG, ESP_LOG_INFO);
    uint8_t* data = (uint8_t*) malloc(RX_BUF_SIZE+1);
    while (1) {
        rxPtr->rxBytes = uart_read_bytes(UART_NUM_1, data, RX_BUF_SIZE, portMAX_DELAY);
        if (rxPtr->rxBytes > 0) {
            data[rxPtr->rxBytes] = 0;
            rxPtr->incomingData = (char*)malloc(rxPtr->rxBytes + 1);
                if (rxPtr->incomingData) {
                    memcpy(rxPtr->incomingData, data, rxPtr->rxBytes);
                    rxPtr->incomingData[rxPtr->rxBytes] = '\0'; // Null-terminate the string
                }
            ESP_LOGI(RX_TASK_TAG, "Read %d bytes: '%s'", rxPtr->rxBytes, data);
            //ESP_LOG_BUFFER_HEXDUMP(RX_TASK_TAG, data, rxBytes, ESP_LOG_INFO);
            if(strstr(rxPtr->incomingData, "+CMQTTRXSTART:") != NULL ){
                ESP_LOGI("COMS","RECEIVED MQTT COMMAND");
                mqttCommand = true;
            }
        }
    }
    free(data);
}

I've tried placing the function in different files. i've added ifndef's. excluded the gpio library but that only resulted in the error "did you mean ledc_isr_register?" So I don't know what to do at the moment.


Solution

  • The error "implicit declaration of a function" happens when a function is called before being declared, not when "a library isn't found". Declaration can be done in your own code before it uses the function or in a header file.

    You're expecting to uart_isr_register() to be declared in drivers/uart.h - it is not.

    You can confirm this by looking at the contents of that file. ESP-IDF is open source, so you can inspect the file in its Github repo.

    According to ESP-IDF's documentation, was removed in ESP-IDF 5.0 as the UART driver now registers for the interrupt itself. You can find this easily by searching the repository for uart_isr_register. The solution is just to remove this line of code as it's no longer needed.