Udefined reference to a function but library is included

Hi,

I am trying to use an own library in Arduino IDE. I followed the steps shown here to add my own library.
My files are located in ~/Documents/Arduino/libraries/RTT

I am using the #include “SEGGER_RTT.h” directive and i get no error related to finding the .h file
However, when I compile the sketch I get the error undefined reference to `SEGGER_RTT_WriteString(unsigned int, char const*)’

I post my code below:

// Copyright (c) Sandeep Mistry. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

// Import libraries (BLEPeripheral depends on SPI)
#include <SPI.h>
#include <BLEPeripheral.h>
#include "SEGGER_RTT.h" 

// define pins (varies per shield/board)
#define BLE_REQ     10
#define BLE_RDY     2
#define BLE_RST     9

// LED and button pin
#define LED_PIN     3
#define BUTTON_PIN  4

// create peripheral instance, see pinouts above
BLEPeripheral            blePeripheral        = BLEPeripheral(BLE_REQ, BLE_RDY, BLE_RST);

// create service
BLEService               ledService           = BLEService("19b10010e8f2537e4f6cd104768a1214");

// create switch and button characteristic
BLECharCharacteristic    switchCharacteristic = BLECharCharacteristic("19b10011e8f2537e4f6cd104768a1214", BLERead | BLEWrite);
BLECharCharacteristic    buttonCharacteristic = BLECharCharacteristic("19b10012e8f2537e4f6cd104768a1214", BLERead | BLENotify);

void setup() {
  Serial.begin(115200);
#if defined (__AVR_ATmega32U4__)
  delay(5000);  //5 seconds delay for enabling to see the start up comments on the serial board
#endif

  // set LED pin to output mode, button pin to input mode
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT);

  // set advertised local name and service UUID
  blePeripheral.setLocalName("LED Switch");
  blePeripheral.setAdvertisedServiceUuid(ledService.uuid());

  // add service and characteristics
  blePeripheral.addAttribute(ledService);
  blePeripheral.addAttribute(switchCharacteristic);
  blePeripheral.addAttribute(buttonCharacteristic);

  // begin initialization
  blePeripheral.begin();

  Serial.println(F("BLE LED Switch Peripheral"));
  SEGGER_RTT_WriteString(0, "Hello World!\n");
}

void loop() {
  
  // poll peripheral
  blePeripheral.poll();

  // read the current button pin state
  char buttonValue = digitalRead(BUTTON_PIN);

  // has the value changed since the last read
  bool buttonChanged = (buttonCharacteristic.value() != buttonValue);

  if (buttonChanged) {
    // button state changed, update characteristics
    switchCharacteristic.setValue(buttonValue);
    buttonCharacteristic.setValue(buttonValue);
  }

  if (switchCharacteristic.written() || buttonChanged) {
    // update LED, either central has written to characteristic or button state has changed
    if (switchCharacteristic.value()) {
      Serial.println(F("LED on"));
      digitalWrite(LED_PIN, HIGH);
    } else {
      Serial.println(F("LED off"));
      digitalWrite(LED_PIN, LOW);
    }
  }
}

And the SEGGER_RTT.h file content:

/*********************************************************************
*              SEGGER MICROCONTROLLER SYSTEME GmbH                   *
*        Solutions for real time microcontroller applications        *
**********************************************************************
*                                                                    *
*        (c) 1996-2014 SEGGER Microcontroller Systeme GmbH           *
*                                                                    *
* Internet: www.segger.com Support: support@segger.com               *
*                                                                    *
**********************************************************************
----------------------------------------------------------------------
File    : SEGGER_RTT.h
Date    : 17 Dec 2014
Purpose : Implementation of SEGGER real-time terminal which allows
          real-time terminal communication on targets which support
          debugger memory accesses while the CPU is running.
---------------------------END-OF-HEADER------------------------------
*/

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/
#define SEGGER_RTT_MODE_MASK                  (3 << 0)

#define SEGGER_RTT_MODE_NO_BLOCK_SKIP         (0)
#define SEGGER_RTT_MODE_NO_BLOCK_TRIM         (1 << 0)
#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL    (1 << 1)

#define RTT_CTRL_RESET                "e[0m"

#define RTT_CTRL_CLEAR                "e[2J"

#define RTT_CTRL_TEXT_BLACK           "e[2;30m"
#define RTT_CTRL_TEXT_RED             "e[2;31m"
#define RTT_CTRL_TEXT_GREEN           "e[2;32m"
#define RTT_CTRL_TEXT_YELLOW          "e[2;33m"
#define RTT_CTRL_TEXT_BLUE            "e[2;34m"
#define RTT_CTRL_TEXT_MAGENTA         "e[2;35m"
#define RTT_CTRL_TEXT_CYAN            "e[2;36m"
#define RTT_CTRL_TEXT_WHITE           "e[2;37m"

#define RTT_CTRL_TEXT_BRIGHT_BLACK    "e[1;30m"
#define RTT_CTRL_TEXT_BRIGHT_RED      "e[1;31m"
#define RTT_CTRL_TEXT_BRIGHT_GREEN    "e[1;32m"
#define RTT_CTRL_TEXT_BRIGHT_YELLOW   "e[1;33m"
#define RTT_CTRL_TEXT_BRIGHT_BLUE     "e[1;34m"
#define RTT_CTRL_TEXT_BRIGHT_MAGENTA  "e[1;35m"
#define RTT_CTRL_TEXT_BRIGHT_CYAN     "e[1;36m"
#define RTT_CTRL_TEXT_BRIGHT_WHITE    "e[1;37m"

#define RTT_CTRL_BG_BLACK             "e[24;40m"
#define RTT_CTRL_BG_RED               "e[24;41m"
#define RTT_CTRL_BG_GREEN             "e[24;42m"
#define RTT_CTRL_BG_YELLOW            "e[24;43m"
#define RTT_CTRL_BG_BLUE              "e[24;44m"
#define RTT_CTRL_BG_MAGENTA           "e[24;45m"
#define RTT_CTRL_BG_CYAN              "e[24;46m"
#define RTT_CTRL_BG_WHITE             "e[24;47m"

#define RTT_CTRL_BG_BRIGHT_BLACK      "e[4;40m"
#define RTT_CTRL_BG_BRIGHT_RED        "e[4;41m"
#define RTT_CTRL_BG_BRIGHT_GREEN      "e[4;42m"
#define RTT_CTRL_BG_BRIGHT_YELLOW     "e[4;43m"
#define RTT_CTRL_BG_BRIGHT_BLUE       "e[4;44m"
#define RTT_CTRL_BG_BRIGHT_MAGENTA    "e[4;45m"
#define RTT_CTRL_BG_BRIGHT_CYAN       "e[4;46m"
#define RTT_CTRL_BG_BRIGHT_WHITE      "e[4;47m"


/*********************************************************************
*
*       RTT API functions
*
**********************************************************************
*/

int     SEGGER_RTT_Read             (unsigned BufferIndex,       char* pBuffer, unsigned BufferSize);
int     SEGGER_RTT_Write            (unsigned BufferIndex, const char* pBuffer, unsigned NumBytes);
int     SEGGER_RTT_WriteString      (unsigned BufferIndex, const char* s);

int     SEGGER_RTT_GetKey           (void);
int     SEGGER_RTT_WaitKey          (void);
int     SEGGER_RTT_HasKey           (void);

int     SEGGER_RTT_ConfigUpBuffer   (unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags);
int     SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags);

void    SEGGER_RTT_Init             (void);

/*********************************************************************
*
*       RTT "Terminal" API functions
*
**********************************************************************
*/
void    SEGGER_RTT_SetTerminal        (char TerminalId);
int     SEGGER_RTT_TerminalOut        (char TerminalId, const char* s);

/*********************************************************************
*
*       RTT printf functions (require SEGGER_RTT_printf.c)
*
**********************************************************************
*/
int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...);

/*************************** End of file ****************************/

Please can some point me towards what I’m doing wrong?
Thanks!

My files are located in ~/Documents/Arduino/libraries/RTT

#include "SEGGER_RTT.h"

This form of #include will make the compiler look in the sketch directory for the .h and other library files

Try

#include <SEGGER_RTT.h>

which will make the compiler look at the normal library locations

Thanks,

Unfortunately I have tried both ways and both return the same error.

I have found the solution. The files in the library are .c files, and Arduino must be told that the library uses c files instead of cpp

Using

extern "C"{
#include <SEGGER_RTT.h>
}

instead of just #include <SEGGER_RTT.h> fixed the error

Presumably there is a .cpp file to go with the .h file

Hi,

My files are located in ~/Documents/Arduino/libraries/RTT

If your library files are called;

#include "SEGGER_RTT.h"

Then I think the directory they are in has to have the same name as the library files;

/Documents/Arduino/libraries/SEGGER_RTT

Check the other libraries

Tom... :slight_smile:

I think the directory they are in has to have the same name as the library files;

I agree with you but note that the OP says

I am using the #include "SEGGER_RTT.h" directive and i get no error related to finding the .h file

I suspect that there is more going on here than we are being told and/or that the OP is aware of. Seeing the full error messages would be helpful

Have you tried this ? undefined reference to `SEGGER_RTT_WriteString' · Issue #1 · monpetit/inventus-factory-examples · GitHub

asl07:
Thanks,

Unfortunately I have tried both ways and both return the same error.

I have found the solution. The files in the library are .c files, and Arduino must be told that the library uses c files instead of cpp

Using

extern "C"{

#include <SEGGER_RTT.h>
}



instead of just #include <SEGGER_RTT.h> fixed the error

You can fix this in your library. At the top of SEGGER_RTT.h, check to see if the compiler is the C++ compiler. If so, put the ‘extern “C” {’ around the body of the include file:

#ifdef __cplusplus 
extern "C" { 
#endif 
	/* Declarations of this file */
#ifdef __cplusplus 
} 
#endif

That way the ‘extern “C”’ is automatic.