Skip to content

Commit

Permalink
[examples] Adapt all protothreads to fibers
Browse files Browse the repository at this point in the history
  • Loading branch information
salkinium committed May 6, 2023
1 parent 6390cdd commit 0ebf256
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 86 deletions.
23 changes: 14 additions & 9 deletions examples/avr/fiber/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,10 @@ struct Test
volatile uint32_t f4counter{0};
} test;

modm::fiber::Stack<128> stack1;
modm::fiber::Stack<128> stack2;
modm::fiber::Stack<128> stack3;
modm::fiber::Stack<128> stack4;
modm::Fiber fiber1(stack1, fiber_function1);
modm::Fiber fiber2(stack2, [](){ fiber_function2(cycles); });
modm::Fiber fiber3(stack3, [](){ test.fiber_function3(); });
modm::Fiber fiber4(stack4, [cyc=uint32_t(cycles)]() mutable { cyc++; test.fiber_function4(cyc); });
modm::Fiber<> fiber1(fiber_function1);
modm::Fiber<> fiber2(+[](){ fiber_function2(cycles); });
modm::Fiber<> fiber3(+[](){ test.fiber_function3(); });
modm::Fiber<> fiber4([cyc=uint32_t(cycles)]() mutable { cyc++; test.fiber_function4(cyc); });

// ATmega2560@16MHz: 239996 yields in 2492668us, 96280 yields per second, 10386ns per yield
int
Expand All @@ -72,6 +68,11 @@ main()
MODM_LOG_INFO << "Starting fiber modm::yield benchmark..." << modm::endl;
MODM_LOG_INFO.flush();

fiber1.watermark_stack();
fiber2.watermark_stack();
fiber3.watermark_stack();
fiber4.watermark_stack();

const modm::PreciseTimestamp start = modm::PreciseClock::now();
modm::fiber::Scheduler::run();
const auto diff = (modm::PreciseClock::now() - start);
Expand All @@ -82,7 +83,11 @@ main()
MODM_LOG_INFO << " yields per second, ";
MODM_LOG_INFO << uint32_t(std::chrono::nanoseconds(diff).count() / total_counter);
MODM_LOG_INFO << "ns per yield" << modm::endl;
MODM_LOG_INFO.flush();

MODM_LOG_INFO << "Stack usage 1 = " << fiber1.stack_usage() << modm::endl;
MODM_LOG_INFO << "Stack usage 2 = " << fiber2.stack_usage() << modm::endl;
MODM_LOG_INFO << "Stack usage 3 = " << fiber3.stack_usage() << modm::endl;
MODM_LOG_INFO << "Stack usage 4 = " << fiber4.stack_usage() << modm::endl;

while(1) ;
return 0;
Expand Down
69 changes: 58 additions & 11 deletions examples/generic/fiber/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
#include <modm/board.hpp>
#include <modm/debug/logger.hpp>
#include <modm/processing.hpp>
#include <modm/driver/time/cycle_counter.hpp>

using namespace Board;
using namespace std::chrono_literals;

constexpr uint32_t cycles = 1'000'000;
constexpr uint32_t cycles = 100'000;
volatile uint32_t f1counter = 0, f2counter = 0;
uint32_t total_counter=0;
modm_fastdata modm::CycleCounter counter;

void
fiber_function1()
Expand Down Expand Up @@ -54,24 +56,58 @@ struct Test
volatile uint32_t f4counter{0};
} test;

modm_faststack modm::fiber::Stack<2048> stack1;
modm_faststack modm::fiber::Stack<2048> stack2;
modm_faststack modm::fiber::Stack<2048> stack3;
modm_faststack modm::fiber::Stack<2048> stack4;
modm_fastdata modm::Fiber fiber1(stack1, fiber_function1);
modm_fastdata modm::Fiber fiber2(stack2, [](){ fiber_function2(cycles); });
modm_fastdata modm::Fiber fiber3(stack3, [](){ test.fiber_function3(); });
modm_fastdata modm::Fiber fiber4(stack4, [cyc=uint32_t(0)]() mutable { cyc++; test.fiber_function4(cyc); });
// Single purpose fibers to time the yield
modm::Fiber<> fiber_y1(+[]()
{ counter.start(); modm::fiber::yield(); });
modm::Fiber<> fiber_y2(+[](){ counter.stop(); });

modm::Fiber<> fiber1(fiber_function1, false);
modm::Fiber<> fiber2(+[](){ fiber_function2(cycles); }, false);
modm::Fiber<> fiber3(+[](){ test.fiber_function3(); }, false);
modm::Fiber<> fiber4([cyc=uint32_t(0)]() mutable
{ cyc = cycles; test.fiber_function4(cyc); }, false);

// Restartable Fibers
extern modm::Fiber<> fiber_pong;
extern modm::Fiber<> fiber_ping;
modm::Fiber<> fiber_ping(+[](){
MODM_LOG_INFO << "ping = " << fiber_ping.stack_usage() << modm::endl;
modm::fiber::sleep(1s);
fiber_pong.start();
}, false);
modm::Fiber<> fiber_pong(+[](){
MODM_LOG_INFO << "pong = " << fiber_pong.stack_usage() << modm::endl;
modm::fiber::sleep(1s);
fiber_ping.start();
}, false);

// Blue pill (M3 72MHz): Executed 1000000 in 1098591us (910256.88 yields per second)
// Feather M0 (M0+ 48MHz): Executed 1000000 in 1944692us (514220.25 yields per second)
int
main()
{
Board::initialize();
counter.initialize();
MODM_LOG_INFO << "Starting fiber modm::yield benchmark..." << modm::endl;
MODM_LOG_INFO.flush();

fiber_y1.watermark_stack();
fiber_y2.watermark_stack();
// fiber_y1, fiber_y2 were autostarted
{
modm::atomic::Lock l;
modm::fiber::Scheduler::run();
}

MODM_LOG_INFO << "Y1 stack usage: = " << fiber_y1.stack_usage() << modm::endl;
MODM_LOG_INFO << "Y2 stack usage: = " << fiber_y2.stack_usage() << modm::endl;
MODM_LOG_INFO.flush();

// the rest is manually started
fiber1.start(); fiber1.watermark_stack();
fiber2.start(); fiber2.watermark_stack();
fiber3.start(); fiber3.watermark_stack();
fiber4.start(); fiber4.watermark_stack();
const modm::PreciseTimestamp start = modm::PreciseClock::now();
modm::fiber::Scheduler::run();
const auto diff = (modm::PreciseClock::now() - start);
Expand All @@ -81,8 +117,19 @@ main()
MODM_LOG_INFO << ((total_counter * 1'000'000ull) / std::chrono::microseconds(diff).count());
MODM_LOG_INFO << " yields per second, ";
MODM_LOG_INFO << (std::chrono::nanoseconds(diff).count() / total_counter);
MODM_LOG_INFO << "ns per yield" << modm::endl;
MODM_LOG_INFO.flush();
MODM_LOG_INFO << "ns per yield slice" << modm::endl;
MODM_LOG_INFO << counter.cycles() << " cycles = " << counter.nanoseconds();
MODM_LOG_INFO << "ns per single yield" << modm::endl;

MODM_LOG_INFO << "F1 stack usage = " << fiber1.stack_usage() << modm::endl;
MODM_LOG_INFO << "F2 stack usage = " << fiber2.stack_usage() << modm::endl;
MODM_LOG_INFO << "F3 stack usage = " << fiber3.stack_usage() << modm::endl;
MODM_LOG_INFO << "F4 stack usage = " << fiber4.stack_usage() << modm::endl;

fiber_ping.watermark_stack();
fiber_pong.watermark_stack();
fiber_ping.start();
modm::fiber::Scheduler::run();

while(1) ;
return 0;
Expand Down
5 changes: 4 additions & 1 deletion examples/generic/fiber/project.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
<library>
<extends>modm:nucleo-f429zi</extends>
<!-- <extends>modm:nucleo-f429zi</extends> -->
<!-- <extends>modm:nucleo-g071rb</extends> -->
<extends>modm:disco-f469ni</extends>
<options>
<option name="modm:build:build.path">../../../build/generic/fiber</option>
<option name="modm:io:with_long_long">yes</option>
</options>
<modules>
<module>modm:build:scons</module>
<module>modm:processing:timer</module>
<module>modm:processing:fiber</module>
<module>modm:driver:cycle_counter</module>
</modules>
</library>
5 changes: 2 additions & 3 deletions examples/linux/fiber/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,14 @@ struct Test
}
} test;

modm::fiber::Stack<1024> stack1;
modm::Fiber<1024> fiber1(hello);
modm::fiber::Stack<1024> stack2;
modm::Fiber fiber1(stack1, hello);

int
main(void)
{
const char *arg = "World";
modm::Fiber fiber2(stack2, [=]() { test.world(arg); });
modm::fiber::Task fiber2(stack2, [=]() { test.world(arg); });

MODM_LOG_INFO << "Start" << modm::endl;
modm::fiber::Scheduler::run();
Expand Down
14 changes: 9 additions & 5 deletions examples/rp_pico/fiber/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fiber_function2(CoreData& d)
}
}

// put cores to mostly equalent environment
// put cores to mostly equivalent environment
modm_core0_data CoreData d0;
modm_core1_data CoreData d1;

Expand All @@ -67,13 +67,14 @@ modm_core1_noinit modm::fiber::Stack<384> stack11;
modm_core1_noinit modm::fiber::Stack<384> stack12;

modm_core0_data
modm::Fiber fiber01(stack01, []() { fiber_function1(d0); }, 0);
modm::fiber::Task fiber01(stack01, []() { fiber_function1(d0); });
modm_core0_data
modm::Fiber fiber02(stack02, []() { fiber_function2(d0); }, 0);
modm::fiber::Task fiber02(stack02, []() { fiber_function2(d0); });
// Do not autostart these fibers, otherwise they run on the Core0 scheduler!
modm_core1_data
modm::Fiber fiber11(stack11, []() { fiber_function1(d1); }, 1);
modm::fiber::Task fiber11(stack11, []() { fiber_function1(d1); }, false);
modm_core1_data
modm::Fiber fiber12(stack12, []() { fiber_function2(d1); }, 1);
modm::fiber::Task fiber12(stack12, []() { fiber_function2(d1); }, false);

template<typename TimeDiff>
static void
Expand All @@ -92,6 +93,9 @@ print_result(const CoreData& d, TimeDiff diff)
void
core1_main()
{
// Start the fibers on the Core1 scheduler
fiber11.start();
fiber12.start();
const modm::PreciseTimestamp start = modm::PreciseClock::now();
modm::fiber::Scheduler::run();
const auto diff = (modm::PreciseClock::now() - start);
Expand Down
6 changes: 1 addition & 5 deletions examples/stm32f3_discovery/accelerometer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,13 @@ class ReaderThread : public modm::pt::Protothread

ReaderThread reader;


int
main()
{
Board::initialize();
Board::initializeLsm3();

while (true)
{
reader.update();
}
modm::fiber::Scheduler::run();

return 0;
}
1 change: 1 addition & 0 deletions examples/stm32f3_discovery/accelerometer/project.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<extends>modm:disco-f303vc</extends>
<options>
<option name="modm:build:build.path">../../../build/stm32f3_discovery/accelerometer</option>
<option name="modm:processing:protothread:use_fiber">yes</option>
</options>
<modules>
<module>modm:math:filter</module>
Expand Down
84 changes: 36 additions & 48 deletions examples/stm32f3_discovery/rotation/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ using namespace Board;

// maps arbitrary gpios to a bit
using LedRingLeft = SoftwareGpioPort<
Board::LedSouth, // 4
// Board::LedSouth, // 4
Board::LedSouthWest, // 3
Board::LedWest, // 2
Board::LedNorthWest, // 1
Board::LedNorth // 0
>;
// Symmetry \o/
using LedRingRight = SoftwareGpioPort<
Board::LedSouth, // 4
// Board::LedSouth, // 4
Board::LedSouthEast, // 3
Board::LedEast, // 2
Board::LedNorthEast, // 1
Expand All @@ -39,68 +39,56 @@ Board::l3g::Gyroscope::Data data;
Board::l3g::Gyroscope gyro(data);


class ReaderThread : public modm::pt::Protothread
modm::Fiber<> fiber1([]()
{
public:
bool
update()
{
PT_BEGIN();

// initialize with limited range of 250 degrees per second
PT_CALL(gyro.configure(gyro.Scale::Dps250));

while (true)
{
// read out the sensor
PT_CALL(gyro.readRotation());
// initialize with limited range of 250 degrees per second
gyro.configure(gyro.Scale::Dps250);

// update the moving average
averageZ.update(gyro.getData().getZ());
modm::filter::MovingAverage<float, 25> averageZ;
while (true)
{
// read out the sensor
gyro.readRotation();

{
float value = averageZ.getValue();
// normalize rotation and scale by 5 leds
uint16_t leds = abs(value / 200 * 5);
leds = (1ul << leds) - 1;
// update the moving average
averageZ.update(gyro.getData().getZ());

// use left or right half ring depending on sign
if (value < 0) {
LedRingRight::write(0);
LedRingLeft::write(leds);
}
else {
LedRingLeft::write(0);
LedRingRight::write(leds);
}
}
float value = averageZ.getValue();
// normalize rotation and scale by 5 leds
uint16_t leds = abs(value / 200 * 5);
leds = (1ul << leds) - 1;

// repeat every 5 ms
timeout.restart(5ms);
PT_WAIT_UNTIL(timeout.isExpired());
// use left or right half ring depending on sign
if (value < 0) {
LedRingRight::write(0);
LedRingLeft::write(leds);
}
else {
LedRingLeft::write(0);
LedRingRight::write(leds);
}

PT_END();
// repeat every 5 ms
modm::fiber::sleep(5ms);
}
});

private:
modm::ShortTimeout timeout;
modm::filter::MovingAverage<float, 25> averageZ;
};

ReaderThread reader;

modm::Fiber<> fiber2([]()
{
while (true)
{
Board::LedSouth::toggle();
modm::fiber::sleep(1s);
}
});

int
main()
{
Board::initialize();
Board::initializeL3g();

while (true)
{
reader.update();
}
modm::fiber::Scheduler::run();

return 0;
}
1 change: 1 addition & 0 deletions examples/stm32f3_discovery/rotation/project.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<extends>modm:disco-f303vc</extends>
<options>
<option name="modm:build:build.path">../../../build/stm32f3_discovery/rotation</option>
<option name="modm:processing:protothread:use_fiber">yes</option>
</options>
<modules>
<module>modm:math:filter</module>
Expand Down
Loading

0 comments on commit 0ebf256

Please sign in to comment.