TransWikia.com

Unresolved reference to public function from library

Arduino Asked by omar_hussein on November 6, 2020

I have three libraries that I’ve written and I’m trying to use. They’re stored as follows

Documents
├── Some/Path/To/Folder
│   └── firmware.ino
└── Arduino
    └── libraries
        ├── error
        │   ├── error.h
        │   └── error.cpp
        ├── lmp91000
        │   ├── lmp91000.h
        │   └── lmp91000.cpp
        └── tps7a7100
            ├── tps7a7100.h
            └── tps7a7100.cpp

Both lmp91000.h and tps7a7100.h have #include "../error/error.h" and are able to access variables and functions declared in error.h and error.cpp just fine.

firmware.ino includes all three libraries as you would expect them to be included and it is able to create instances of classes defined in both lmp91000 and tps7a7100 and use their methods (which depend on error). I am also able to create instances of a struct (ERROR) defined in error.h from firmware.ino, however I am not able to access functions from error.h and error.cpp. Error recived is

firmware.ino:19: undefined reference to `LOG_E(ERROR)'

However when I remove the guards in error.h that error no longer appears (implying that LOG_E can be resolved) but I get the expected errors of multiple definitions as there are multiple #include error.h.

My thoughts are that because of the guards error is not being included in a location where the sketch has access to the functions, but I may be completely off on that. I know there must be a way around this, as I’m able to access Wire.h for example from firmware.ino even though that is included in lmp91000.h – how do I solve this?

firmware.ino

#include <error.h>
#include <lmp91000.h>
#include <tps7a7100.h>
#include <Wire.h>

lmp91000 pot(12);
tpsa7100 vreg(10,9,8,7,6,5,4);

void setup() {
    Wire.begin();
    Serial.begin(115200);
    while(!Serial);
    vreg.enable();
    pot.enable();
    ERROR misc;
    misc.errorCode = 0x50;
    LOG_E(misc);
}

void loop() {
}

error.h

#ifndef error_h_included
#define error_h_included

#include "Arduino.h"


// Error Structure
typedef struct{
    int errorCode;
    char const *errorName;
    char const *errorDesc;
    bool isFatalError;
    bool shouldRetry;
}ERROR;

// Global error types
const ERROR E_SUCCESS = {0x00, "E_SUCCESS", "Success", false, false};
const ERROR E_INVALID_ARG = {0x10, "E_INVALID_ARG", "Invalid argument passed", true, false};
const ERROR E_I2C_NACK_ADDR = {0x20, "E_I2C_NACK_ADDR", "NACK on I2C address byte", false, true};
const ERROR E_I2C_NACK_DATA = {0x21, "E_I2C_NACK_DATA", "NACK on I2C data byte", false, true};
const ERROR E_I2C_BUFF_LEN = {0x22, "E_I2C_BUFF_LEN", "Transmit Data too long for I2C buffer", true, false};
const ERROR E_I2C_ERROR = {0x23, "E_I2C_ERROR", "Undefined I2C Error", true, false};
const ERROR E_I2C_TARGET_DISABLED = {0x24, "E_I2C_TARGET_DISABLED", "Target device for I2C comms disabled", false, false};
const ERROR E_I2C_READ_ERROR = {0x25, "E_I2C_READ_ERROR", "I2C Data could not be read", false, false};
const ERROR E_I2C_WRITE_ERROR = {0x26, "E_I2C_WRITE_ERROR", "Attempting to write zero bytes to I2C bus", false, false};

// Function Definitions
bool E(ERROR error_struct);
void LOG_E(ERROR error_struct);
ERROR WireErrorDecode(int code); 


#endif

error.cpp

#include "error.h"


// Error Handling Functions

// E(ERROR)
// Evaluate the successfullness of the error
// Return 0 if error is a success error
// Return >0 if error is not success error
bool E(ERROR error_struct) {
    return (int)(error_struct.errorCode & 0xF0);
}

// LOG(ERROR)
// Log the error 
void LOG_E(ERROR error_struct) {
    Serial.print(error_struct.errorCode);
    Serial.print("t");
    Serial.print(error_struct.errorName);
    Serial.print("t");
    Serial.println(error_struct.errorDesc);
}

// WireErrorDecode(code)
// Decode Wire.EndTransmission error codes
ERROR WireErrorDecode(int code) {
    switch(code) {
        case 0:
            return E_SUCCESS;
        case 1:
            return E_I2C_BUFF_LEN;
        case 2:
            return E_I2C_NACK_ADDR;
        case 3:
            return E_I2C_NACK_DATA;
        case 4:
            return E_I2C_ERROR;
        default:
            return E_INVALID_ARG;
    }
}

Update: These errors seem to be board specific – see question here

One Answer

The filename error.h is not a good name for a library. Some compilers and cores (such as the ESP32 and Curie cores) have a file error.h of their own which will be used in preference to yours.

Instead, name your library something more sensible.

Answered by Majenko on November 6, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP