Putting code in new file, getting errors

I am trying to limit the size of the sketch ino file by putting code into other files organized by purpose like I do when I program embedded systems in a regular C environment.
But with Arduino I am getting strange “undefined reference” errors…
I have two calls inside the loop like the one shown below and both throws the error!
Why?
Is it not allowed to use C files in Arduino?
Where can I add the external C files to the project (if needed)?
If I use the Sketch/Add file command even though “All files” is selected my *.c and *.h files do not show up in the dialog…
So I assumed that Arduino takes the easy way out and treats all files in the directory as a source file, but apparently not.
This is what I have and am getting errors from:
In the main sketch ino file:

#include <ESP8266WiFi.h>
#include <FS.h>
#include <EEPROM.h>
#include "espconfig.h"  //<== Defines the config items
....
void loop() {
  uint8_t i;
  char buf[1024], cnfBuf[1024];
  int bytesAvail, bytesIn, cnfBytesAvail, cnfBytesIn;
....
        if (cnfBytesIn > 0) {
          ProcessConfigCall(cnfBuf, cnfBytesIn); //<= undefined reference here

In espconfig.h (in the same directory as the main ino file):

#ifndef __ESPCONFIG_H_
#define __ESPCONFIG_H_

#define byte unsigned char //<== should not be needed but otherwise unknown symbol

//EEPROM address defines:
#define SSID_ADDR 0
#define PWRD_ADDR 32
#define APIP_ADDR 64
#define BAUD_ADDR 68
#define TCPP_ADDR 70
#define WEBP_ADDR 72

//Struct types:
typedef struct 
{
  unsigned int chksum;
  char ssid[32];
  char passwd[32];
  byte addr[4];
  long baud;
  unsigned int tcpport;
} ESPConfiguration;

//Externals:
//extern ESPConfiguration ESPConf;

//Prototypes:
int IsValidBaud(long b);
void ProcessConfigCall(char *buf, int len);

#endif

And in the espconfig.c file:

#include "espconfig.h"

int IsValidBaud(long b)
{
  int ret=0;

  switch (b) {
    case 1200:
    case 2400:
    case 4800:
    case 9600:
    case 14400:
    case 19200:
    case 28800:
    case 38400:
    case 57600:
    case 115200:
      ret = 1;
  }
  return ret;
}
void ProcessConfigCall(char *buf, int len)
{
  //Here is where the user commands will be decoded and acted on
}

Arduino sketch files are actually C++. Thus if you want to use funtions defined in a C file (.c) you need to wrap the declarations in extern "C" {}:

//Prototypes:
#ifdef __cplusplus
extern “C” {
#endif
  int IsValidBaud(long b);
  void ProcessConfigCall(char *buf, int len);
#ifdef __cplusplus
}
#endif

Alternately you could just rename the .c file with a .cpp (C++) extension.

Thank you for your suggestion!
I did not know about the C++ thing, have never ever programmed C++.
But the file rename worked fine, so the C and C++ syntax must be close enough to be accepted.

I have a bit related question, maybe you know the answer?
How to determine the actual flash size of the module?

I am targeting the ESP-07S module (which has 32 Mbit flash). So I have set flash to "4M (1M SPIFFS)".
But since I have not gotten any such modules yet I have bought an ESP-07 in an electronics store and I am using that instead while waiting for delivery. Now I suspect that this does not have the same flash size as the 07S type has, but I don't know...

Is there some way to determine the actual flash size of the module?
I have googled and I could find a discussion on GitHub where they determine this by looking at some module data.
The problem is that they do not say HOW they are "reading flash ID"...

Do you have any suggestion?
When I verify my sketch in Arduino it says this on the bottom window when it is done:

Sketch uses 262107 bytes (25%) of program storage space. Maximum is 1044464 bytes.
Global variables use 34212 bytes (41%) of dynamic memory, leaving 47708 bytes for local variables.
Maximum is 81920 bytes.

Does this mean I can load it if I select flash as "1M (64K SPIFFS)" instead?
I have tried using EEPROM with the 4M setting but never got EEPROM to work and now I think that it might be a flash issue.

Or should I create a new thread for this question?

Basically any valid C code is valid C++ code. There are some additional features of C++ that are not supported by C. Some of them are really useful. Others are useful in some cases but also can lead to the code being really hard to understand, which is one of the complaints C programmers have about C++. I think that in the world of microcontrollers it makes sense to pick and choose the more useful C++ features and leave the rest of them alone. Most of the code you see in Arduino sketches will essentially be C. The primary exception is that most Arduino libraries use classes but the aspect of classes exposed to the library user is easy enough to understand.

Regarding the ESP8266 module flash size, it's tricky because the ESP8266 uses an external flash chip so you can't just check the ESP8266 datasheet for the information. To make matters worse the flash chip is often hidden under an RF shield so you can't just check the part number on the chip and look it up. There are a bunch of different modules and most of them are not well documented and you really have no guarantee that just because two modules have the same model number they have the same flash chips. Then there's the infuriating way that the sellers will use "M" as a unit for flash size instead of the more descriptive MB or Mb, though I'm not sure I would trust them to get that right. Even better, just say megabyte or megabit so we can be absolutely sure what they're talking about!

BosseB:
When I verify my sketch in Arduino it says this on the bottom window when it is done:

Sketch uses 262107 bytes (25%) of program storage space. Maximum is 1044464 bytes.

Global variables use 34212 bytes (41%) of dynamic memory, leaving 47708 bytes for local variables.
Maximum is 81920 bytes.

That maximum is only coming from the hardware definition you selected from the Tools menu. It's not actually read from the ESP8266 module.

The ESP8266 core for Arduino comes with an example sketch: File > Examples > ESP8266 > CheckFlashConfig. I believe that will actually read the size from the hardware and give you an accurate number.

BosseB:
I have tried using EEPROM with the 4M setting but never got EEPROM to work and now I think that it might be a flash issue.

You need to be aware that, although it has a similar API, the ESP8266 EEPROM library works differently than the standard Arduino EEPROM library so if you're looking at example code or documentation for the non-ESP8266 EEPROM library it will lead you astray. You should refer to the official documentation:
https://arduino-esp8266.readthedocs.io/en/latest/libraries.html#eeprom
Other than needing to use EEPROM.begin() and EEPROM.commit() or EEPROM.end(), the other EEPROM functions work the same as the official Arduino library and so you can use the regular reference pages for them:
https://www.arduino.cc/en/Reference/EEPROM

Thank you so much again!
I opened the example you pointed to then set my IDE for a "1M (no SPIFFS)" configuration and uploaded the sketch.
This is what is dispalyed (repeatedly on the terminal):

Flash real id:   001440E0
Flash real size: 1048576

Flash ide  size: 1048576
Flash ide speed: 40000000
Flash ide mode:  DIO
Flash Chip configuration ok.

I am assuming that the 1048576 value refers to the size in bytes, right?
So this finally gave the correct answer I was looking for, and the tool was right there inside Arduino too! :slight_smile:

Final (I hope) question:
If I want to use a bit of EEPROM with this module, how should I configure the flash for ESP-07 and how should I change it later when I get the ESP-07S (which has a 32 Mbit flash)?

Aargh, the lack of units strikes again. I remember hitting that too. It is bytes:
http://arduino-esp8266.readthedocs.io/en/latest/libraries.html?highlight=getFlashChipRealSize#esp-specific-apis
I've had submitting a fix for that sketch on my to-do list a long time. I'm going to do it now.

It took me a while to find the sketch too. I'd think there would be a documentation section for each of the ESP8266 core's custom Tools menu items and that sketch would be mentioned in the Tools > Flash Size section.

BosseB:
If I want to use a bit of EEPROM with this module, how should I configure the flash for ESP-07 and how should I change it later when I get the ESP-07S (which has a 32 Mbit flash)?

I'm not sure. I really don't have much experience with ESP8266. I've only used the WeMos D1 and D1 Mini before and I just used all the default menu selections. Hopefully someone else can give some advice on that.