weak function definitions for pinMode, digitalWrite, digitalRead, etc.

8bitforce

Member
Hi,

I'm working on a "yet another" adapter board that converts Teensy 4.1 to Arduino Mega 2560 form-factor, with true 5V push-pull signaling. 5V push-pull is done with the circuitry that sits between Teensy 4.1 and the outside world. My goal is to use existing mega shields with teensy 4.1

I would like to override the pinMode, digitalRead, digitalWrite, analogRead, etc. so I can configure the custom circuitry. This will help one to reuse existing Arduino Mega code as much as possible. Without overriding, I have to use custom function names, which is another thing to worry about.

1) Is is possible to modify the digital.c and a few others to achieve this?
2) Asking as a hardware person, is there any danger to enabling overriding? (I see a few other board libraries allow this - not sure if ok to mention names.).

Please DON'T do the modifications yet. First step would be to understand how much of work this will require. If helpful I can also recommend what files and which changes to make.

Thank you,

It will be something along the lines of...

C++:
// extern void  pinMode(uint8_t pin, uint8_t mode)                                            __attribute__((weak, alias("__pinMode")));
// extern void  digitalWrite(uint8_t pin, uint8_t val)                                        __attribute__((weak, alias("__digitalWrite")));
// extern int   digitalRead(uint8_t pin)                                                      __attribute__((weak, alias("__digitalRead")));
// extern void  attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode)                   __attribute__((weak, alias("__attachInterrupt")));
// extern void  attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void *arg, int mode)  __attribute__((weak, alias("__attachInterruptArg")));
// extern void  detachInterrupt(uint8_t pin)                                                  __attribute__((weak, alias("__detachInterrupt")));


// extern uint16_t analogRead(uint8_t pin)                                          __attribute__((weak, alias("__analogRead")));
// extern uint32_t analogReadMilliVolts(uint8_t pin)                                __attribute__((weak, alias("__analogReadMilliVolts")));
// extern void analogReadResolution(uint8_t bits)                                   __attribute__((weak, alias("__analogReadResolution")));
// extern void analogSetAttenuation(adc_attenuation_t attenuation)                  __attribute__((weak, alias("__analogSetAttenuation")));
// extern void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation)  __attribute__((weak, alias("__analogSetPinAttenuation")));


// ##################################################
// My custom pinMode()

void pinMode(uint8_t pin, uint8_t mode) {
  __pinMode(pin, mode);
  Serial.write("pinMode called");
}
 
Last edited:
It turns out we need the override :( - There are existing Arduino libraries (for example LiquidCrystal) that use pinMode(), digitalWrite(), digitalRead().
 
I feel like this isn't necessary; it's already possible to replace these functions, as long as you replace every externally exposed symbol in their source file.
 
Thank you for your comment.

it's already possible to replace these functions, as long as you replace every externally exposed symbol in their source file.
Would you be able to explain this a bit more? I was thinking of a teensy user modifying the library source files they downloaded (both in Arduino Library/ folder and/or platformio's library folders). This means everybody has to modify their libraries and redo it when the library is updated. If there is another way to replace, please let me know.
 
Last edited:
After spending a bit more into library sources, my learnings are:

  1. if library doesn't change pin directions, then we are good. For example, FastLED library works without problems. I think LiquidCrystal also should work (I think it doesn't read from the lcd) but I want to verify on actual hw.
  2. Platformio can patch files before build (including library files) for projects. I am currently looking into this. This will be easier for teensy users. Then work for me is to review/release a new patch when a new teensy core library is updated.
  3. It is also possible to patch Arduino libraries. This is more involved because it requires a patching implementation for all 3 OS's.
  4. fork the teensy core for the adapter board. Scares me :)

I will continue my investigations, hoping these are useful discussion for others. Admin, if you think this should move this to another area, please feel free.
 
I feel like this isn't necessary; it's already possible to replace these functions, as long as you replace every externally exposed symbol in their source file.
I am thinking you were thinking of "variants". Arduino IDE lets one to add variants for the existing boards, with slight modifications to pins definitions and a few core files. I'm going down this path now. It is a mix of options 3 and 4. I will report back once I figure out the details. Thanks again.
 
No, I wasn't. Again: if you provide your own implementations for every public function included in a specific source file from the core library, you will not get any symbol collisions.
The reason is that the core library is compiled as an archive (.a file) and the linker will only include objects that provide a needed symbol - if you've already provided those symbols in your own code the core object file that provides them won't be linked.
 
I posted a message about failure when redefining pinMode and digitalWrite. After rereading your comment, I think I have to redefine ALL the functions in a file. Let me try that and come back. Stay tuned.
 
Hurray, I confirm if I redefine all the functions in a core file, then override works. I copied the digital.c from core to the project folder and I can modify the functions without error.

One undesired side effect is I have to keep a copy of the original core functions in my project because I still use them after I configure the muxes on my adapter board. This means if the core function gets updated, I have to bring the changes. Do you have suggestion for this? Regardless, this is enough to keep me going.

thank you.
 
Back
Top