Skip to content

Mock - timers and core scheduling #9121

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions cores/esp8266/Schedule.cpp
Original file line number Diff line number Diff line change
@@ -270,11 +270,9 @@ void run_scheduled_recurrent_functions()

if (yieldNow)
{
// because scheduled functions might last too long for watchdog etc,
// this is yield() in cont stack, but need to call cont_suspend directly
// to prevent recursion into run_scheduled_recurrent_functions()
// because scheduled functions might last too long for watchdog etc.
esp_schedule();
cont_suspend(g_pcont);
esp_suspend();
}
} while (current && !done);

2 changes: 1 addition & 1 deletion libraries/Ticker/src/Ticker.cpp
Original file line number Diff line number Diff line change
@@ -74,7 +74,7 @@ void Ticker::_attach(Ticker::Milliseconds milliseconds, bool repeat)

// whenever duration excedes this limit, make timer repeatable N times
// in case it is really repeatable, it will reset itself and continue as usual
size_t total = 0;
uint32_t total = 0;
if (milliseconds > DurationMax) {
total = 1;
while (milliseconds > DurationMax) {
7 changes: 5 additions & 2 deletions tests/host/Makefile
Original file line number Diff line number Diff line change
@@ -111,6 +111,7 @@ CORE_CPP_FILES := \
) \
$(abspath $(LIBRARIES_PATH)/SDFS/src/SDFS.cpp) \
$(abspath $(LIBRARIES_PATH)/SD/src/SD.cpp) \
$(abspath $(LIBRARIES_PATH)/Ticker/src/Ticker.cpp) \

CORE_C_FILES := \
$(addprefix $(abspath $(CORE_PATH))/,\
@@ -127,6 +128,7 @@ MOCK_CPP_FILES_COMMON := \
sdfs_mock.cpp \
WMath.cpp \
MockUART.cpp \
MockTimer.cpp \
MockTools.cpp \
MocklwIP.cpp \
HostWiring.cpp \
@@ -139,6 +141,7 @@ MOCK_CPP_FILES := $(MOCK_CPP_FILES_COMMON) \

MOCK_CPP_FILES_EMU := $(MOCK_CPP_FILES_COMMON) \
$(addprefix $(HOST_COMMON_ABSPATH)/,\
MockTask.cpp \
ArduinoMain.cpp \
ArduinoMainUdp.cpp \
ArduinoMainSpiffs.cpp \
@@ -184,7 +187,7 @@ PREINCLUDES := \
-include $(common)/c_types.h \

ifneq ($(D),)
OPTZ=-O0
OPTZ=-Og
DEBUG += -DDEBUG_ESP_PORT=Serial
DEBUG += -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_ESP_MDNS
endif
@@ -226,7 +229,7 @@ all: help

.PHONY: CI
CI: # run CI
$(MAKE) -f $(MAKEFILE) MKFLAGS="-Werror --coverage" LDFLAGS="--coverage" FORCE32=0 OPTZ=-O0 doCI
$(MAKE) -f $(MAKEFILE) MKFLAGS="-Werror --coverage" LDFLAGS="--coverage" FORCE32=0 OPTZ=-Og doCI

.PHONY: doCI
doCI: build-info $(OUTPUT_BINARY) valgrind test gcov
4 changes: 2 additions & 2 deletions tests/host/README.txt
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
Host Tests for Continuous Integration
-------------------------------------

make FORCE32=0 OPTZ=-O0 CI
make FORCE32=0 OPTZ=-Og CI

(FORCE32=0: https://bugs.launchpad.net/ubuntu/+source/valgrind/+bug/948004)

@@ -43,7 +43,7 @@ run it:

Optional 'V=1' enables makefile verbosity
Optional 'D=1' enables core debug messages (same as Arduino IDE's tools/debug menu)
Optional 'OPTZ=-O2' will update gcc -O option (default is -Os, -D=1 implies -O0)
Optional 'OPTZ=-O2' will update gcc -O option (default is -Os, -D=1 implies -Og)
Optional 'FORCE32=0' will use native/default gcc (default is FORCE32=1 unless gcc-multilib is not detected)
Optional 'R="<options>"' (ex: R="-b -v") runs the executable with given options after build

47 changes: 27 additions & 20 deletions tests/host/common/Arduino.cpp
Original file line number Diff line number Diff line change
@@ -15,13 +15,23 @@

#include <sys/time.h>
#include <unistd.h>

#include <functional>
#include <stdio.h>

#include <Arduino.h>
#include <Schedule.h>

static struct timeval gtod0 = { 0, 0 };
#include <thread>
#include <stdexcept>

#include <ets_sys.h>
#include <sched.h>

namespace
{

timeval gtod0 = { 0, 0 };

} // namespace

extern "C" unsigned long millis()
{
@@ -44,6 +54,12 @@ extern "C" unsigned long micros()
extern "C" void yield()
{
run_scheduled_recurrent_functions();
if (!can_yield())
{
throw std::runtime_error("should only yield from loop()!");
}

esp_yield();
}

extern "C" void loop_end()
@@ -52,25 +68,16 @@ extern "C" void loop_end()
run_scheduled_recurrent_functions();
}

extern "C" bool can_yield()
{
return true;
}

extern "C" void optimistic_yield(uint32_t interval_us)
{
(void)interval_us;
}

extern "C" void esp_suspend() { }

extern "C" void esp_schedule() { }
static auto last = std::chrono::steady_clock::now();

extern "C" void esp_yield() { }

extern "C" void esp_delay(unsigned long ms)
{
usleep(ms * 1000);
const auto now = std::chrono::steady_clock::now();
if (last - now > std::chrono::microseconds { interval_us })
{
last = now;
yield();
}
}

bool esp_try_delay(const uint32_t start_ms, const uint32_t timeout_ms, const uint32_t intvl_ms)
@@ -99,7 +106,7 @@ extern "C" void delay(unsigned long ms)

extern "C" void delayMicroseconds(unsigned int us)
{
usleep(us);
std::this_thread::sleep_for(std::chrono::microseconds { us });
}

#include "cont.h"
23 changes: 23 additions & 0 deletions tests/host/common/ArduinoCatch.cpp
Original file line number Diff line number Diff line change
@@ -16,6 +16,9 @@
#define CATCH_CONFIG_MAIN
#include "ArduinoCatch.hpp"

#include <chrono>
#include <thread>

std::ostream& operator<<(std::ostream& out, const String& str)
{
out.write(str.c_str(), str.length());
@@ -36,3 +39,23 @@ std::string StringMaker<String>::convert(String const& str)
}

} // namespace Catch

extern "C"
{
bool can_yield()
{
return true;
}

void esp_yield() { }

void esp_suspend() { }

void esp_schedule() { }

void esp_delay(unsigned long ms)
{
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}

} // extern "C"
Loading