EDIT - I've gone in a lot more depth now, and evaluated all the libraries that are even potentially included, even if not used. I found that the major difference between the two is the inclusion of stm32duino/STM32Duino FreeRTOS. As soon as I remove this dependency it starts working. I assume it is the overriding of the new operator that is not working because this particular test sketch did not initialize free rtos, even though it was on the build path.
----
I've been trying to track down a very strange issue in attachInterrupt, so strange that I didn't even want to post it until I could reliably recreate it. It seems that in some conditions attachInterrupt does not register and it seems to matter that other classes are present in the sketch. It seems very localized to the build environment. I am also a platformIO user, and have one project where this is a problem, one where it is not.
Problem is, I cannot fully isolate it. I post the code below as the closest I have got to isolating, but I have to say, it does not reliably recreate the issue, it may be there is a particular configuration of compiler / settings that creates this problem. But I can't understand how more people would not have seen this?
Unless you think there's some benefit in investigating further I was going to delete the faulty project and configuration and just start over in the working project (and hope it doesn't come back).
Code: Select all
/**
* My environment is platformIO (CLion IDE), I've tried this on various versions of the Stm32Duino platform back to
* about a year ago. In one project it reliably fails, in the other it works perfectly.
*
* Unfortunately, I cannot run the sketch in Arduino as I'd have to add the board I'm using to the boards file there.
* I know the board is working properly when the marked line below is commented out.
*
*/
#include <Arduino.h>
// First we create an interface that we will use later - to create a virtual table.
class MyAbstraction {
public:
virtual void pinDirection(uint8_t pin, uint8_t mode)=0;
};
// Then we create the implementation that has the pinDirection method implementation.
class MyAbstractionImpl : public MyAbstraction {
public:
void pinDirection(uint8_t pin, uint8_t mode) override {
pinMode(pin, mode);
}
};
volatile int counter;
void interruptCallback() {
// in the interrupt we just increment the counter
counter++;
}
void setup() {
// commenting out this line makes the sketch work in the environment that fails.
auto* digitalIo = new MyAbstractionImpl();
Serial.begin(115200);
pinMode(PC8, INPUT_PULLUP);
// here we register the interrupt
::attachInterrupt(digitalPinToInterrupt(PC8), interruptCallback, CHANGE);
}
void loop() {
// we just print out the contents of the counter every second.
Serial.print("Counter is ");
Serial.println(counter);
delay(1000);
}