arkhipenko / TaskScheduler

Cooperative multitasking for Arduino, ESPx, STM32, nRF and other microcontrollers
http://playground.arduino.cc/Code/TaskScheduler
BSD 3-Clause "New" or "Revised" License
1.2k stars 221 forks source link

Defined tasks not working depending on files alphabetical order #117

Open vvinjj opened 3 years ago

vvinjj commented 3 years ago

Based on: TaskScheduler/examples/Scheduler_example16_Multitab/Scheduler_example16_Multitab.ino It says that Arduino IDE plays some dirty tricks on main sketch file and it rearranges #includes, blindly creates forward definitions. However, developing in PlatformIO I faced the bug that the blank .ino file workaround didn't help and one of my tasks which was defined in file didn't want to execute. After couple of hours on trying to narrow down the issue, found that if I simply rename the file where my task is to make it appear alphabetically earlier than main.cpp, then it fixes the issue.

Example: ultrasound.cpp & ultrasound.h -> contains Task loopUltrasound which periodically invokes itself; main.cpp -> defines Scheduler runner; setup() and loop() with runner.execute();

Workaround Fix:

Alternative workaround Fix:

Not sure why it behaves such way, but I hope it helps to narrow down the issue.

arkhipenko commented 3 years ago

As usual, need to see the source code to be able to attempt to help.

vvinjj commented 3 years ago

Source code: https://github.com/vvinjj/TaskShedulerAbcIssue

arkhipenko commented 3 years ago

Unfortunately, I do not use Platform.io, but on the surface of things: why not include the external reference to scheduler into aTaks.h file since you need it to create a task in aTask.cpp?

vvinjj commented 3 years ago

Perhaps you misunderstood the issue as TaskA is working anyway, but TaskZ is not (but is structurally identical, only file name is different). Refactored example to be compatible with Arduino IDE: https://github.com/vvinjj/ArduinoTaskSchedulerAbcIssue If you rename taskZ.cpp to taskB.cpp, close IDE and re-open (as IDE has some cache related bug) then compile, you will see that both tasks starts working.

arkhipenko commented 3 years ago

Indeed, it does not work, probably because of the sequence of declarations. I am not using CPP/HPP files for Arduino, so never saw this issue. As a workaround this works:

header.hpp:

#include <TaskSchedulerDeclarations.h>

//Let the runner object be a global, single instance shared between object files.
extern Scheduler runner;
extern Task taskA;
extern Task taskZ;

aTask.cpp:

#include <Arduino.h>
#include "header.hpp"
void printTaskA();
Task taskA(TASK_SECOND, TASK_ONCE, &printTaskA);

void printTaskA() {
  Serial.println("taskA is working as appears alphabetically earlier than main.cpp");
  taskA.restartDelayed(TASK_SECOND);
}

zTask.cpp:

#include <Arduino.h>
#include "header.hpp"
void printTaskZ();
Task taskZ(TASK_SECOND, TASK_ONCE, &printTaskZ);

void printTaskZ() {
  Serial.println("taskZ is NOT working as appears alphabetically later than main.cpp");
  taskZ.restartDelayed(TASK_SECOND);
}

main.cpp:

#include <Arduino.h>
#include "header.hpp"

Scheduler runner; //Let the scheduler live here, in the main file

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  runner.addTask(taskA);
  runner.addTask(taskZ);
  runner.enableAll();
}

void loop() {
  runner.execute();
}

Please let me know if you find a more elegant solution.

vvinjj commented 3 years ago

I think in your solution you can remove from header.hpp: extern Scheduler runner; as not needed anymore. As I mentioned initially I was trying to utilize the example taken from: TaskScheduler/examples/Scheduler_example16_Multitab/ which uses the CPP/HPP files. So, the only thing I can suggest is to either update the example to make it a bit clear about such potential issue or add the current example for guidance. More generally I think the only way to prevent the issue from happening would require non-backwards compatible library code change to initialize the runner differently in relation to its tasks. Thanks for your library anyway.

PPCM commented 2 years ago

I am using PlatformIO too and I have the same issue, where frusting I changed main.cp to zzzmain.cpp according the workaround from @vvinjj

@arkhipenko It will usefull to put this information clearly somewhere to prevent people to looking for a bug in their own code And perhaps found a solution to prevent that...

Very usefull lib, thanks