Overriding Core #defines

Status
Not open for further replies.

microderm

Well-known member
Is there a simple way to override a #define such as SERIAL1_RX_BUFFER_SIZE found in serial1.c, from a project level rather than within the core files? It just feels wrong to edit core files when I only want the change for one build not all builds.

If I insert this code at the top of my ino file, it doesn't work because the core has already been processed.
Code:
#ifndef SERIAL1_RX_BUFFER_SIZE
  #define SERIAL1_RX_BUFFER_SIZE 512
#endif

If I could get the pre-processor to start from the ino file then proceed as normal I could tweak the core on a project by project basis. Nice ;-)

Is this possible?
 
I think C supports #undef but not tried it in Arduino. Try #undef SERIAL1_RX_BUFFER_SIZE before the define.
 
I think C supports #undef but not tried it in Arduino. Try #undef SERIAL1_RX_BUFFER_SIZE before the define.

In theory, #undef works fine, but any use of the macro is in the .cpp file in the library or in inline functions/class definitions in the .h file, it won't see the changed value.
 
I guess that explains why I have not seen it in use in any examples.
Thanks for the clarification.
 
Unfortunately does not provide any simple way to allow you to configure things like this in the core files or library source files.

That is why for example there are some libraries, where all of the code is in the header file, which you must include in your sources. This allow your sources to set up the specifics for each device or ...

Now in this specific case, the answer may depend on which Teensy you are trying to change for. If T4, the core files were changed to allow you to call a member function with a buffer pointer to add additional storage for a specific serial ports read or write buffer. But again only for T4...

Now to this specific issue at hand..

I believe you can for example change the platform.txt file associated with Teensy boards and add change the recipe for c or c++ files to add in this define, like:
-DSERIAL1_RX_BUFFER_SIZE=512

Also I think there are members like @FrankB - who have have a modified version of platform.txt, where they have the code read in from a specific header file in your sketch folder that can have defines like this.

But the last time I looked it it, it had the side effect that all of the sketches you compile MUST have this header file or the build would fail... But you might search for threading mentioning platform.txt
 
I think C supports #undef but not tried it in Arduino. Try #undef SERIAL1_RX_BUFFER_SIZE before the define.

I can redefine SERIAL1_RX_BUFFER_SIZE, but the original values have already been used to set the buffer size. It is question of race conditions - my ino code get used after the core code initialises the system.
 
Thanks @KurtE. Sounds interesting I'll take a look at this. If the platform.txt file read is a file that lives in your current project folder (and ignores all other copies that may or may not exist in other folders) then this may be the way to go.

Alternatively, I wonder if the preprocessor knows the address / filename of the ino file. If so, maybe it is possible for core code to look for a specific header file (who's name is based on the ino file name) and to include this if it exists? That way, you create a file such MyProjectName.h included in your project file that contains project specific overrides. I'll research and experiment to see if any of the steps are possible on my system (Mac).
 
It seems I misunderstand how the system works. I tried the following experiment on my iMac:
- modified Arduino.app/Contents/Java/hardware/teensy/avr/cores/teensy3/kinetis.h by adding the line: #include "Overrides.h".
- Inserted an empty file called Overrides.h in my libraries folder.
- Compiled.

This caused an error, as the file could not be found. It seems that the libraries folder is not in the immediate search path.

Next, I created a fictitious project called OverrideTest and moved the header Overrides.h into it. I modified kinetis.h by replacing the previous #include with the following conditional logic, now using the absolute path:

Code:
#define ABSOLUTE_FULL_PATH "/Users/Andy/Documents/Arduino/OverrideTest/Overrides.h"
#if __has_include ( ABSOLUTE_FULL_PATH )
    #include ABSOLUTE_FULL_PATH // Single defined string: This works! //
#endif

This works, whether or not the header file "Overrides.h" exists or not. Yay!

The problems start when I try to assign the absolute address to a #define variable using concatenation. I can concatenate my hardwired project folder with my header file name as follows:

Code:
#define ABSOLUTE_FULL_PATH "/Users/Andy/Documents/Arduino/OverrideTest/Overrides.h" // This is the result we want from concatenation //

[B]#define CONCATEN_PROJ_PATH "/Users/Andy/Documents/Arduino/OverrideTest/"
#define CONCATEN_FILE_NAME "Overrides.h"
#define CONCATEN_FULL_PATH CONCATEN_PROJ_PATH CONCATEN_FILE_NAME[/B]

#if __has_include ( ABSOLUTE_FULL_PATH )
    #include ABSOLUTE_FULL_PATH // Absolute single string: This works! //
#endif

[B]#if __has_include ( CONCATEN_FULL_PATH )
    #include CONCATEN_FULL_PATH // Concatenated string: DOESN'T WORK => Error! //
#endif[/B]

This throws the error:
Code:
In file included from /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/cores/teensy3/core_pins.h:34:0,
                 from /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/cores/teensy3/wiring.h:38,
                 from /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/cores/teensy3/WProgram.h:45,
                 from /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/cores/teensy3/Arduino.h:6,
                 from /var/folders/76/fcb9d1nn36s74kz1zlc38kxr0000gn/T/arduino_build_458632/sketch/OverrideTest.ino.cpp:1:
/Applications/Arduino.app/Contents/Java/hardware/teensy/avr/cores/teensy3/kinetis.h:48:40: [B]error: missing ')' after "__has_include__"
 #if __has_include ( CONCATEN_FULL_PATH )[/B]
                                        ^
/Applications/Arduino.app/Contents/Java/hardware/teensy/avr/cores/teensy3/kinetis.h:48:40: error: missing '(' in expression
Error compiling for board Teensy 3.6.

Printing out the value of the defines (ABSOLUTE_FULL_PATH and CONCATEN_FULL_PATH) from the ino file reveals that they have the same value! Strange!

Questions:
1) Should I be able to concatenate #defines this way?
2) Can I fix the value of a define some other way to have it represent the dynamic path to my header file?
3) Can I change the search path to include my project folder, so that I don't have to fiddle with absolute paths?
 
I misunderstood how the preprocessor worked. I have since managed to concatenate project path and folder name to make a valid token that can be used to conditionally include a header of fixed name within my project folder:

Code:
#define Q(x) #x
#define QUOTE(x) Q(x)

#define PROJECTS_FOLDER /Users/Andy/Documents/Arduino/    [COLOR="#008000"]// Constant value //[/COLOR]
[B]#define PROJECT_NAME OverrideTest[/B]                         [COLOR="#008000"]// I need to get this token! //[/COLOR]
#define HEADER_FILE /Overrides.h                          [COLOR="#008000"]// Constant value //[/COLOR]

#define INCLUDE_FILE_PATH  PROJECTS_FOLDER  HEADER_FILE  CONCATEN_FILE_NAME


#if __has_include ( QUOTE(INCLUDE_FILE_PATH) )
  #include QUOTE(INCLUDE_FILE_PATH)
#endif

The code above works and allows me to call an overrides header prior to preprocessing a header that I want to modify. This allows me to modify values such as the Serial1 buffer size. The only thing missing is that I can't get a token for the name of the project. The code above works because I hardwired the line with the project name: #define PROJECT_NAME OverrideTest. Is that possible?

I used verbose compilation and the command line to produce a list of define tokens and noted that the project name or path was not amongst them.

Additionally, I looked at the platform.txt recipes and inserted the following additional option: -I/Users/Andy/Documents/Arduino/OverrideTest/

This also allowed me to place a conditional include within serial1.c so that my override header could be included, if it happened to be within my project folder:

Code:
#if __has_include ("Overrides.h")
  #include "Overrides.h"
#endif

Again, this is only working because I hard-wired the current project path into the platform.txt recipes. I couldn't automate this in any of the recipes as the only key-values that I could find to reference the project path were:

Code:
sketch_path = /Users/Andy/Documents/Arduino/OverrideTest/OverrideTest.ino
build.project_name = OverrideTest.ino
But, I would need to remove build.project_name from the sketch_path somehow. Is that possible?
 
Per the ref in Post#5 of @KurtE ...

Here is the thread where FRANK B did some of this: HOWTO-Store-Projects-settings-(like-F_CPU-USB-Keyboard-layout)

Not sure if it needs any updates {beyond changes to new platform.txt for current IDE 1.8.9} or corrections and can do the needed work. It uses UNDEF and redefines things in core build - as noted … "(like-F_CPU-USB-Keyboard-layout)"

It adds defs.h to PLATFORM.txt for global application IIRC ...
 
Thanks @defragster, I have looked at that thread and tested on my machine. Couldn't get anything to work. I'll reply to that thread for help getting it to work...
 
With a little fiddling, I got it to override the CPU speed. I'll investigate further before requesting help...
 
Cool - CPU Speed was going to be my first comment for a test.

Are you on IDE 1.8.9? Did you make an updated Platform.txt?
 
Yes, I'm on 1.8.9. I didn't understand the comments about TYQT mentioned in the other thread.

I'm just going through platform.txt to note the differences to create a 1.8.9 version, now.

I presume it should say:
Code:
version=1.8.9
on the third line of the script?
 
You'll want to start with a copy of 1.8.9 PLATFORM.txt from the installed folder that knows the current Teensy build system. { I see that still shows 1.8.5 - that is under PJRC's purview }

Then make whatever other similar mods are needed to add in the defs.h usage.

TyQt is now TyCommander … it is an alternate uploader/sermon tool that can be used. It adds in after so isn't part of the stuff you want to edit before ahnd
 
Yours was similar to mine. I didn't have the following in:
Code:
## Teensy Ports Discovery (Arduino 1.8.9 with pathPrefs patch)
discovery.teensy.pattern="{runtime.hardware.path}/../tools/teensy_ports" -J2
It doesn't work for me with this in.
 
Interesting - that should be in the TD 1.47 installed on IDE 1.8.9?

If either of those versions are newer that may explain that.

It works unchanged for me if there is no defs.h in the local folder. Adding that is not liking a simple: "#define catfood 1"

I get errors on each of those three words/
 
Maybe the .gcc versus .linker was part of it - I took most of your diffs to mine - moved the .size eeprom up to the same group.

I can build, but not with a defs.h in local folder - it seems to confuse the IDE? Not sure as I never really used this much except to build FrankB's Teensy64 code.
 
@defragster, are you adding the line:
Code:
#define catfood 1
to your defs.h file? If so, that'll be the reason. It isn't really a header file. That's why FrankB wanted to change the file extension, as it is misleading. According to the other thread (you referenced above), the file should contain key-value pairs such as:
Code:
-DSERIAL1_RX_BUFFER_SIZE=522
I don't think you require an undefine statement anymore:
Code:
-USERIAL1_RX_BUFFER_SIZE
 
That's right do recall the issue with the name - that was long ago:: just adds to linker line

IIRC looking at USERIAL1_RX_BUFFER_SIZE in the source it has #ifdefined making it optional and not requiring undef for that case.
 
Confirmed '-Ucatfood' versus '-Dcatfood' in defs.h triggers this or not in the sketch:
Code:
void setup() {
  Serial.begin(9600);
  while ( !Serial && millis()<3000 );
#ifdef catfood
      Serial.println("Found catfood");
#endif
}

Also looking at : ...\hardware\teensy\avr\cores\teensy4\HardwareSerial1.cpp::
Code:
#ifndef SERIAL1_TX_BUFFER_SIZE
#define SERIAL1_TX_BUFFER_SIZE     64 // number of outgoing bytes to buffer
#endif
#ifndef SERIAL1_RX_BUFFER_SIZE
#define SERIAL1_RX_BUFFER_SIZE     64 // number of incoming bytes to buffer
#endif
#define IRQ_PRIORITY  64  // 0 = highest priority, 255 = lowest

And here is the file in use:
 
Ah, so I'd need a -UMY_DEFINE_VALUE statement if MY_DEFINE_VALUE were defined like this in the core?:
Code:
#define MY_DEFINE_VALUE 123
 
Just tried your version of platform.txt. Works perfectly! The Teensy Ports Discovery no longer a problem. I changed only one thing, the version number at the top of the script. After all it's supposed to represent the associated IDE version right? Maybe you should post it on @FrankB's thread?
 
Status
Not open for further replies.
Back
Top