Skip to content
Merged
Show file tree
Hide file tree
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
99 changes: 99 additions & 0 deletions examples/nucleo_h563zi/fiber/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright (c) 2026, Niklas Hauser
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <modm/board.hpp>
#include <modm/debug/logger.hpp>
#include <modm/processing.hpp>

using namespace Board;
using namespace std::chrono_literals;

namespace
{

constexpr uint32_t YieldGoal = 2'000'000;
volatile uint32_t yieldCounter = 0;
volatile uint32_t ringCounter = 0;

void
yield_worker()
{
while (true)
{
++yieldCounter;
modm::this_fiber::yield();
}
}

extern modm::Fiber<512> fiberB;
extern modm::Fiber<512> fiberC;

modm_faststack modm::Fiber<768> fiberA([]{
++ringCounter;
if ((ringCounter & 0x3ff) == 0)
{
const auto ring = uint32_t(ringCounter);
const auto yields = uint32_t(yieldCounter);
MODM_LOG_INFO << "ring=" << ring
<< " yields=" << yields
<< " A=" << fiberA.stack_usage()
<< modm::endl;
}
modm::this_fiber::yield();
fiberB.start();
});

modm_faststack modm::Fiber<512> fiberB([]{
++ringCounter;
modm::this_fiber::yield();
fiberC.start();
}, modm::fiber::Start::Later);

modm_faststack modm::Fiber<512> fiberC([]{
++ringCounter;
modm::this_fiber::yield();
fiberA.start();
}, modm::fiber::Start::Later);

modm_faststack modm::Fiber<768> fiberYield(yield_worker);

modm_faststack modm::Fiber<1024> fiberReporter([]{
while (true)
{
modm::this_fiber::sleep_for(250ms);
Leds::toggle();
const auto yields = uint32_t(yieldCounter);
const auto ring = uint32_t(ringCounter);
MODM_LOG_INFO << "report yields=" << yields
<< " ring=" << ring
<< " WY=" << fiberYield.stack_usage()
<< " WA=" << fiberA.stack_usage()
<< " WB=" << fiberB.stack_usage()
<< " WC=" << fiberC.stack_usage()
<< modm::endl;
}
});

}

int
main()
{
Board::initialize();
Leds::setOutput();

MODM_LOG_INFO << "H563ZI fiber stress example" << modm::endl;
MODM_LOG_INFO << "Exercises repeated yield and restart handover on ARMv8-M" << modm::endl;
MODM_LOG_INFO.flush();

modm::fiber::Scheduler::run(modm::fiber::Scheduler::AutoWatermark);
return 0;
}
10 changes: 10 additions & 0 deletions examples/nucleo_h563zi/fiber/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<library>
<extends>modm:nucleo-h563zi</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_h563zi/fiber</option>
</options>
<modules>
<module>modm:build:scons</module>
<module>modm:processing:fiber</module>
</modules>
</library>
16 changes: 14 additions & 2 deletions src/modm/processing/fiber/context_arm_m.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,17 @@ modm_context_start(modm_context_t*)
"orr r1, r1, #2 \n\t" // Set SPSEL
%% endif
"msr control, r1 \n\t"
"isb \t\n\t"
%#
%% if is_cm0
"ldr r1, [r0] \n\t"
"mov sp, r1 \n\t" // Set PSP to ctx->sp
%% elif with_psplim
"ldm r0, {r1-r2} \n\t"
"msr psplim, r2 \n\t" // Set PSPLIM to ctx->bottom
"mov r3, #0 \n\t"
"msr psplim, r3 \n\t" // Disable PSPLIM
"mov sp, r1 \n\t" // Set PSP to ctx->sp
"msr psplim, r2 \n\t" // Set PSPLIM to ctx->bottom
%% else
"ldr sp, [r0] \n\t" // Set PSP to ctx->sp
%% endif
Expand Down Expand Up @@ -240,8 +243,10 @@ modm_context_jump(modm_context_t*, modm_context_t*)
"mov sp, r2 \n\t" // Restore SP from to->sp
%% elif with_psplim
"ldm r1, {r1-r2} \n\t"
"mov r3, #0 \n\t"
"msr psplim, r3 \n\t" // Disable PSPLIM
"mov sp, r1 \n\t" // Restore SP from to->sp
"msr psplim, r2 \n\t" // Set PSPLIM to ctx->bottom
"mov sp, r1 \n\t" // Set PSP to ctx->sp
%% else
"ldr sp, [r1] \n\t" // Restore SP from to->sp
%% endif
Expand All @@ -260,6 +265,12 @@ modm_context_end(uintptr_t)
{
asm volatile
(
%% if with_psplim
"mov r3, #0 \n\t"
"msr psplim, r3 \n\t" // Disable PSPLIM
%#
%% endif

"mrs r1, control \n\t"
%% if is_cm0
"mov r2, #2 \n\t"
Expand All @@ -268,6 +279,7 @@ modm_context_end(uintptr_t)
"bic r1, r1, #2 \n\t" // Unset SPSEL
%% endif
"msr control, r1 \n\t"
"isb \n\t"

MODM_POP_CONTEXT()
);
Expand Down
Loading