11 Commits

Author SHA1 Message Date
10b7dbc19f UPD CI workflow
Some checks failed
Build test application / build-cli-v1 (debug, DISCO_H747I, tests-bike-computer-bike-system) (push) Failing after 3s
Build test application / build-cli-v1 (debug, DISCO_H747I, tests-bike-computer-sensor-device) (push) Failing after 2s
Build test application / build-cli-v1 (debug, DISCO_H747I, tests-bike-computer-speedometer) (push) Failing after 2s
2024-11-18 09:21:22 +01:00
6867629a7a RM folder ignore for tests 2024-11-18 09:18:27 +01:00
c29ff3776e ADD answer to questions 2024-11-18 09:14:12 +01:00
9b90756e09 ADD run configurations 2024-11-18 09:14:00 +01:00
852d58b340 FIX reset task 2024-11-18 09:13:18 +01:00
818daaa9a0 FIX Static scheduling with event 2024-11-18 08:36:49 +01:00
b4d5f8028d ADD [WIP] Static scheduling with event 2024-11-17 23:09:00 +01:00
6f7ee84ea0 ADD EventQueue for static_scheduling 2024-11-17 19:13:06 +01:00
d42dcb68b1 ADD Thread sleep 2024-11-17 18:26:18 +01:00
211f362e66 ADD cpu logger 2024-11-17 18:25:48 +01:00
f079714de5 ADD bike-system super-loop with while 2024-11-17 14:20:38 +01:00
25 changed files with 430 additions and 454 deletions

View File

@ -1,4 +1,4 @@
files: ^main.cpp|^static_scheduling|^static_scheduling_with_event|^TESTS
files: ^main.cpp
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
@ -8,19 +8,17 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: "v14.0.6"
rev: 'v14.0.6'
hooks:
- id: clang-format
- repo: https://github.com/cpplint/cpplint
rev: "1.6.1"
rev: '1.6.1'
hooks:
- id: cpplint
name: cpplint
entry: cpplint --linelength=90 --filter=-build/include_subdir,-whitespace/indent,-build/namespaces,-build/c++11
- repo: local
hooks:
- id: cppcheck
name: cppcheck
require_serial: true
entry: cppcheck --enable=all --suppress=missingInclude --suppress=missingIncludeSystem --inline-suppr -i mbed-os --std=c++14 --error-exitcode=1
entry: cppcheck --enable=all --suppress=missingInclude:* --inline-suppr -i mbed-os --std=c++14 --error-exitcode=1
language: system

View File

@ -83,8 +83,3 @@ We observe a light usage of 1% of CPU. The CPU is now sleeping all the time and
`Based on the program itself and on the task scheduling, explain these two behaviors. Explain also why such behaviors may be problematic.`
We notice, that we miss such less event when is event driven (or not at all). But with a static scheduling the response time is still long because the reset task is call with a certain period.
# Issues
When compile with GCC, the full loop of static scheduling is 2 to 3 ms faster than expected.
This problem doesn't occur if we compile with ARMC6.
As the acceptable delta is 2ms and the teacher test is done with GCC, we modify the delta on the test to be 3ms

View File

@ -24,16 +24,16 @@
#include <chrono>
#include "greentea-client/test_env.h"
#include "mbed.h"
#include "static_scheduling/bike_system.hpp"
#include "static_scheduling_with_event/bike_system.hpp"
#include "greentea-client/test_env.h"
#include "mbed.h"
#include "task_logger.hpp"
#include "unity/unity.h"
#include "utest/utest.h"
namespace utest {
namespace v1 {
using namespace utest::v1;
// test_bike_system handler function
static void test_bike_system() {
@ -59,7 +59,7 @@ static void test_bike_system() {
800000us, 400000us, 1600000us, 800000us, 1600000us, 1600000us};
// allow for 2 msecs offset
uint64_t deltaUs = 3000;
uint64_t deltaUs = 2000;
for (uint8_t taskIndex = 0; taskIndex < advembsof::TaskLogger::kNbrOfTasks;
taskIndex++) {
TEST_ASSERT_UINT64_WITHIN(
@ -80,8 +80,7 @@ static void test_bike_system_event_queue() {
// run the bike system in a separate thread
Thread thread;
thread.start(
callback(&bikeSystem, &static_scheduling::BikeSystem::startWithEventQueue));
thread.start(callback(&bikeSystem, &static_scheduling::BikeSystem::startWithEventQueue));
// let the bike system run for 20 secs
ThisThread::sleep_for(20s);
@ -97,7 +96,7 @@ static void test_bike_system_event_queue() {
800000us, 400000us, 1600000us, 800000us, 1600000us, 1600000us};
// allow for 2 msecs offset (with EventQueue)
uint64_t deltaUs = 3000;
uint64_t deltaUs = 2000;
for (uint8_t taskIndex = 0; taskIndex < advembsof::TaskLogger::kNbrOfTasks;
taskIndex++) {
TEST_ASSERT_UINT64_WITHIN(
@ -130,7 +129,7 @@ static void test_bike_system_with_event() {
800000us, 400000us, 1600000us, 800000us, 1600000us, 1600000us};
// allow for 2 msecs offset (with EventQueue)
uint64_t deltaUs = 3000;
uint64_t deltaUs = 2000;
for (uint8_t taskIndex = 0; taskIndex < advembsof::TaskLogger::kNbrOfTasks;
taskIndex++) {
TEST_ASSERT_UINT64_WITHIN(
@ -140,9 +139,9 @@ static void test_bike_system_with_event() {
}
}
static status_t greentea_setup(const size_t number_of_cases) {
// Here, we specify the timeout (60s) and the host test (a built-in host test
// or the name of our Python file)
static utest::v1::status_t greentea_setup(const size_t number_of_cases) {
// Here, we specify the timeout (60s) and the host test (a built-in host test or the
// name of our Python file)
GREENTEA_SETUP(180, "default_auto");
return greentea_test_setup_handler(number_of_cases);
@ -157,7 +156,4 @@ static Case cases[] = {
static Specification specification(greentea_setup, cases);
}; // namespace v1
}; // namespace utest
int main() { return !utest::v1::Harness::run(utest::v1::specification); }
int main() { return !Harness::run(specification); }

View File

@ -29,8 +29,7 @@
#include "unity/unity.h"
#include "utest/utest.h"
namespace utest {
namespace v1 {
using namespace utest::v1;
// test_hdc1000 test handler function
static control_t test_sensor_device(const size_t call_count) {
@ -54,9 +53,9 @@ static control_t test_sensor_device(const size_t call_count) {
return CaseNext;
}
static status_t greentea_setup(const size_t number_of_cases) {
// Here, we specify the timeout (60s) and the host test (a built-in host test
// or the name of our Python file)
static utest::v1::status_t greentea_setup(const size_t number_of_cases) {
// Here, we specify the timeout (60s) and the host test (a built-in host test or the
// name of our Python file)
GREENTEA_SETUP(60, "default_auto");
return greentea_test_setup_handler(number_of_cases);
@ -66,7 +65,5 @@ static status_t greentea_setup(const size_t number_of_cases) {
static Case cases[] = {Case("test sensor device", test_sensor_device)};
static Specification specification(greentea_setup, cases);
}; // namespace v1
}; // namespace utest
int main() { return !utest::v1::Harness::run(utest::v1::specification); }
int main() { return !Harness::run(specification); }

View File

@ -32,14 +32,13 @@
#include "unity/unity.h"
#include "utest/utest.h"
using namespace utest::v1;
// allow for 0.1 km/h difference
static constexpr float kAllowedSpeedDelta = 0.1f;
// allow for 1m difference
static constexpr float kAllowedDistanceDelta = 1.0f / 1000.0;
namespace utest {
namespace v1 {
// function called by test handler functions for verifying the current speed
void check_current_speed(const std::chrono::milliseconds& pedalRotationTime,
uint8_t traySize,
@ -76,8 +75,7 @@ float compute_distance(const std::chrono::milliseconds& pedalRotationTime,
float trayGearRatio = static_cast<float>(traySize) / static_cast<float>(gearSize);
float distancePerPedalTurn = trayGearRatio * wheelCircumference;
// distancePerPedalTurn is expressed in m, divide per 1000 for a distance in
// km
// distancePerPedalTurn is expressed in m, divide per 1000 for a distance in km
return (distancePerPedalTurn * pedalRotations) / 1000.0;
}
@ -88,8 +86,7 @@ void check_distance(const std::chrono::milliseconds& pedalRotationTime,
float wheelCircumference,
const std::chrono::milliseconds& travelTime,
float distance) {
// distancePerPedalTurn is expressed in m, divide per 1000 for a distance in
// km
// distancePerPedalTurn is expressed in m, divide per 1000 for a distance in km
float expectedDistance = compute_distance(
pedalRotationTime, traySize, gearSize, wheelCircumference, travelTime);
printf(" Expected distance is %f, current distance is %f\n",
@ -337,9 +334,9 @@ static control_t test_reset(const size_t call_count) {
return CaseNext;
}
static status_t greentea_setup(const size_t number_of_cases) {
// Here, we specify the timeout (60s) and the host test (a built-in host test
// or the name of our Python file)
static utest::v1::status_t greentea_setup(const size_t number_of_cases) {
// Here, we specify the timeout (60s) and the host test (a built-in host test or the
// name of our Python file)
GREENTEA_SETUP(180, "default_auto");
return greentea_test_setup_handler(number_of_cases);
@ -353,7 +350,5 @@ static Case cases[] = {
Case("test speedometer reset", test_reset)};
static Specification specification(greentea_setup, cases);
}; // namespace v1
}; // namespace utest
int main() { return !utest::v1::Harness::run(utest::v1::specification); }
int main() { return !Harness::run(specification); }

View File

@ -27,8 +27,7 @@
#include "unity/unity.h"
#include "utest/utest.h"
namespace utest {
namespace v1 {
using namespace utest::v1;
// test handler function
static control_t always_succeed(const size_t call_count) {
@ -39,9 +38,9 @@ static control_t always_succeed(const size_t call_count) {
return CaseNext;
}
static status_t greentea_setup(const size_t number_of_cases) {
// Here, we specify the timeout (60s) and the host test (a built-in host test
// or the name of our Python file)
static utest::v1::status_t greentea_setup(const size_t number_of_cases) {
// Here, we specify the timeout (60s) and the host test (a built-in host test or the
// name of our Python file)
GREENTEA_SETUP(60, "default_auto");
return greentea_test_setup_handler(number_of_cases);
@ -52,7 +51,4 @@ static Case cases[] = {Case("always succeed test", always_succeed)};
static Specification specification(greentea_setup, cases);
}; // namespace v1
}; // namespace utest
int main() { return !utest::v1::Harness::run(utest::v1::specification); }
int main() { return !Harness::run(specification); }

View File

@ -24,14 +24,12 @@
* @version 0.2.0
***************************************************************************/
#include "greentea-client/test_env.h" // NOLINT
#include "mbed.h" // NOLINT
#include "unity/unity.h" // NOLINT
#include "utest/utest.h" // NOLINT
namespace utest {
namespace v1 {
#include "greentea-client/test_env.h"
#include "mbed.h"
#include "unity/unity.h"
#include "utest/utest.h"
using namespace utest::v1;
struct Test {
Test() {
_instanceCount++;
@ -50,8 +48,7 @@ struct Test {
uint32_t Test::_instanceCount = 0;
/**
* Test that a shared pointer correctly manages the lifetime of the underlying
* raw pointer
* Test that a shared pointer correctly manages the lifetime of the underlying raw pointer
*/
void test_single_sharedptr_lifetime() {
// Sanity-check value of counter
@ -69,8 +66,8 @@ void test_single_sharedptr_lifetime() {
}
/**
* Test that multiple instances of shared pointers correctly manage the
* reference count to release the object at the correct point
* Test that multiple instances of shared pointers correctly manage the reference count
* to release the object at the correct point
*/
void test_instance_sharing() {
std::shared_ptr<Test> shared_ptr1(nullptr);
@ -148,7 +145,7 @@ void test_unique_ptr_transfer() {
p2.reset();
TEST_ASSERT_EQUAL(0, Test::_instanceCount);
TEST_ASSERT(!p1); // cppcheck-suppress accessMoved
TEST_ASSERT(!p1);
TEST_ASSERT(!p2);
}
@ -226,13 +223,14 @@ void test_unique_ptr_swap() {
TEST_ASSERT_EQUAL(0, Test::_instanceCount);
}
/*******************
* RAW PTR EXERCISE *
*******************/
/**
* Test that a shared pointer correctly manages the lifetime of the underlying
* raw pointer
* Test that a shared pointer correctly manages the lifetime of the underlying raw pointer
*/
void test_single_raw_ptr_lifetime() {
// Sanity-check value of counter
@ -262,9 +260,9 @@ void test_single_raw_ptr_lifetime() {
TEST_ASSERT_EQUAL(0, Test::_instanceCount);
}
static status_t greentea_setup(const size_t number_of_cases) {
// Here, we specify the timeout (60s) and the host test (a built-in host test
// or the name of our Python file)
static utest::v1::status_t greentea_setup(const size_t number_of_cases) {
// Here, we specify the timeout (60s) and the host test (a built-in host test or the
// name of our Python file)
GREENTEA_SETUP(60, "default_auto");
return greentea_test_setup_handler(number_of_cases);
}
@ -287,7 +285,4 @@ static Case cases[] = {
static Specification specification(greentea_setup, cases);
}; // namespace v1
}; // namespace utest
int main() { return !utest::v1::Harness::run(utest::v1::specification); }
int main() { return !Harness::run(specification); }

View File

@ -110,7 +110,7 @@ void Speedometer::computeSpeed() {
// TODO : done
//Distance run with one pedal turn = tray size / rear gear size * circumference of the wheel
constexpr float ms_in_hour = static_cast<float>(3600 * 1000);
float pedal_rotation_per_hour = ms_in_hour / std::chrono::duration_cast<std::chrono::milliseconds>(_pedalRotationTime).count();
float pedal_rotation_per_hour = ms_in_hour / static_cast<float>(_pedalRotationTime.count());
float gear_ratio = static_cast<float>(kTraySize) / static_cast<float>(this->_gearSize);
float wheel_dist_km = static_cast<float>(this->kWheelCircumference) / 1000.0;
this->_currentSpeed = gear_ratio * wheel_dist_km * pedal_rotation_per_hour;

View File

@ -57,12 +57,16 @@ static constexpr std::chrono::milliseconds kCPUTaskPeriod = 1
static constexpr std::chrono::milliseconds kCPUTaskDelay = 0ms;
static constexpr std::chrono::milliseconds kCPUTaskComputationTime = 0ms;
BikeSystem::BikeSystem()
: _gearDevice(_timer),
BikeSystem::BikeSystem() :
_gearDevice(_timer),
_pedalDevice(_timer),
_resetDevice(_timer),
_speedometer(_timer),
_cpuLogger(_timer) {}
_cpuLogger(_timer)
{
}
void BikeSystem::start() {
tr_info("Starting Super-Loop without event handling");
@ -84,6 +88,8 @@ void BikeSystem::start() {
speedDistanceTask(); // 200ms : 1300ms -> 1500ms
resetTask(); // 100ms : 1500ms -> 1600ms
// register the time at the end of the cyclic schedule period and print the
// elapsed time for the period
std::chrono::microseconds endTime = _timer.elapsed_time();
@ -91,6 +97,8 @@ void BikeSystem::start() {
std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
tr_debug("Repeating cycle time is %" PRIu64 " milliseconds", cycle.count());
// TODO: implement loop exit when applicable
// Done
bool fStop = false;
core_util_atomic_load(&fStop);
if (fStop) {
@ -100,10 +108,12 @@ void BikeSystem::start() {
#if !defined(MBED_TEST_MODE)
_cpuLogger.printStats();
#endif
}
}
void BikeSystem::startWithEventQueue() {
tr_info("Starting Super-Loop with event handling");
init();
@ -115,8 +125,7 @@ void BikeSystem::startWithEventQueue() {
gearEvent.period(kGearTaskPeriod);
gearEvent.post();
Event<void()> speedDistanceEvent(&eventQueue,
callback(this, &BikeSystem::speedDistanceTask));
Event<void()> speedDistanceEvent(&eventQueue, callback(this, &BikeSystem::speedDistanceTask));
speedDistanceEvent.delay(kSpeedDistanceTaskDelay);
speedDistanceEvent.period(kSpeedDistanceTaskPeriod);
speedDistanceEvent.post();
@ -131,8 +140,7 @@ void BikeSystem::startWithEventQueue() {
resetEvent.period(kResetTaskPeriod);
resetEvent.post();
Event<void()> temperatureEvent(&eventQueue,
callback(this, &BikeSystem::temperatureTask));
Event<void()> temperatureEvent(&eventQueue, callback(this, &BikeSystem::temperatureTask));
temperatureEvent.delay(kTemperatureTaskDelay);
temperatureEvent.period(kTemperatureTaskPeriod);
temperatureEvent.post();
@ -187,7 +195,8 @@ void BikeSystem::gearTask() {
_currentGearSize = _gearDevice.getCurrentGearSize();
_taskLogger.logPeriodAndExecutionTime(
_timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime);
_timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime
);
}
void BikeSystem::speedDistanceTask() {
@ -202,7 +211,8 @@ void BikeSystem::speedDistanceTask() {
_traveledDistance = _speedometer.getDistance();
_taskLogger.logPeriodAndExecutionTime(
_timer, advembsof::TaskLogger::kSpeedTaskIndex, taskStartTime);
_timer, advembsof::TaskLogger::kSpeedTaskIndex, taskStartTime
);
}
void BikeSystem::temperatureTask() {
@ -215,14 +225,16 @@ void BikeSystem::temperatureTask() {
tr_warn("Tick2 %" PRIu64, _timer.elapsed_time().count());
ThisThread::sleep_for(std::chrono::duration_cast<std::chrono::milliseconds>(
kTemperatureTaskComputationTime - (_timer.elapsed_time() - taskStartTime)));
ThisThread::sleep_for(
std::chrono::duration_cast<std::chrono::milliseconds>(
kTemperatureTaskComputationTime - (_timer.elapsed_time() - taskStartTime)
)
);
// simulate task computation by waiting for the required task computation time
// std::chrono::microseconds elapsedTime =
// std::chrono::microseconds::zero(); while (elapsedTime <
// kTemperatureTaskComputationTime) {
// std::chrono::microseconds elapsedTime = std::chrono::microseconds::zero();
// while (elapsedTime < kTemperatureTaskComputationTime) {
// elapsedTime = _timer.elapsed_time() - taskStartTime;
// }
@ -251,14 +263,16 @@ void BikeSystem::displayTask1() {
_displayDevice.displaySpeed(_currentSpeed);
_displayDevice.displayDistance(_traveledDistance);
ThisThread::sleep_for(std::chrono::duration_cast<std::chrono::milliseconds>(
kDisplayTask1ComputationTime - (_timer.elapsed_time() - taskStartTime)));
ThisThread::sleep_for(
std::chrono::duration_cast<std::chrono::milliseconds>(
kDisplayTask1ComputationTime - (_timer.elapsed_time() - taskStartTime)
)
);
// simulate task computation by waiting for the required task computation time
// std::chrono::microseconds elapsedTime =
// std::chrono::microseconds::zero(); while (elapsedTime <
// kDisplayTask1ComputationTime) {
// std::chrono::microseconds elapsedTime = std::chrono::microseconds::zero();
// while (elapsedTime < kDisplayTask1ComputationTime) {
// elapsedTime = _timer.elapsed_time() - taskStartTime;
// }
@ -271,20 +285,24 @@ void BikeSystem::displayTask2() {
_displayDevice.displayTemperature(_currentTemperature);
ThisThread::sleep_for(std::chrono::duration_cast<std::chrono::milliseconds>(
kDisplayTask2ComputationTime - (_timer.elapsed_time() - taskStartTime)));
ThisThread::sleep_for(
std::chrono::duration_cast<std::chrono::milliseconds>(
kDisplayTask2ComputationTime - (_timer.elapsed_time() - taskStartTime)
)
);
// simulate task computation by waiting for the required task computation time
// std::chrono::microseconds elapsedTime =
// std::chrono::microseconds::zero(); while (elapsedTime <
// kDisplayTask2ComputationTime) {
// std::chrono::microseconds elapsedTime = std::chrono::microseconds::zero();
// while (elapsedTime < kDisplayTask2ComputationTime) {
// elapsedTime = _timer.elapsed_time() - taskStartTime;
// }
_taskLogger.logPeriodAndExecutionTime(
_timer, advembsof::TaskLogger::kDisplayTask2Index, taskStartTime);
}
void BikeSystem::cpuTask() { _cpuLogger.printStats(); }
void BikeSystem::cpuTask() {
_cpuLogger.printStats();
}
} // namespace static_scheduling

View File

@ -25,9 +25,9 @@
#pragma once
// from advembsof
#include "cpu_logger.hpp"
#include "display_device.hpp"
#include "task_logger.hpp"
#include "cpu_logger.hpp"
// from common
#include "sensor_device.hpp"

View File

@ -1,16 +1,3 @@
// Copyright 2022 Haute école d'ingénierie et d'architecture de Fribourg
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/****************************************************************************
* @file pedal_device.cpp
* @author Rémi Heredero <remi@heredero.ch>
@ -39,15 +26,16 @@ static constexpr std::chrono::microseconds kTaskRunTime = 200000us;
PedalDevice::PedalDevice(Timer& timer) : _timer(timer) {}
std::chrono::milliseconds PedalDevice::getCurrentRotationTime() {
// TODO
std::chrono::microseconds initialTime = _timer.elapsed_time();
std::chrono::microseconds elapsedTime = std::chrono::microseconds::zero();
// we bound the change to one increment/decrement per call
bool hasChanged = false;
while (elapsedTime < kTaskRunTime) {
if (!hasChanged) {
disco::Joystick::State joystickState =
disco::Joystick::getInstance().getState();
disco::Joystick::State joystickState = disco::Joystick::getInstance().getState();
switch (joystickState) {
case disco::Joystick::State::LeftPressed:
@ -81,4 +69,4 @@ void PedalDevice::decreaseRotationSpeed() {
_pedalRotationTime += bike_computer::kDeltaPedalRotationTime;
}
} // namespace static_scheduling
}

View File

@ -1,17 +1,3 @@
// Copyright 2022 Haute école d'ingénierie et d'architecture de Fribourg
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/****************************************************************************
* @file reset_device.cpp
* @author Rémi Heredero <remi@heredero.ch>
@ -35,6 +21,7 @@
static constexpr uint8_t kPolarityPressed = 1;
#endif
#if MBED_CONF_MBED_TRACE_ENABLE
#define TRACE_GROUP "ResetDevice"
#endif // MBED_CONF_MBED_TRACE_ENABLE
@ -60,10 +47,17 @@ bool ResetDevice::checkReset() {
}
return isPressed;
}
std::chrono::microseconds ResetDevice::getPressTime() { return _pressTime; }
std::chrono::microseconds ResetDevice::getPressTime() {
return _pressTime;
}
void ResetDevice::onRise() { _pressTime = _timer.elapsed_time(); }
void ResetDevice::onRise() {
_pressTime = _timer.elapsed_time();
}
} // namespace static_scheduling
}

View File

@ -63,14 +63,19 @@ static constexpr std::chrono::milliseconds kCPUTaskPeriod = 1600ms;
static constexpr std::chrono::milliseconds kCPUTaskDelay = 1200ms;
static constexpr std::chrono::milliseconds kCPUTaskComputationTime = 100ms;
BikeSystem::BikeSystem()
: _gearDevice(),
BikeSystem::BikeSystem() :
_gearDevice(),
_pedalDevice(),
_resetDevice(callback(this, &BikeSystem::onReset)),
_speedometer(_timer),
_cpuLogger(_timer) {}
_cpuLogger(_timer)
{
}
void BikeSystem::start() {
tr_info("Starting Super-Loop with event handling");
init();
@ -82,8 +87,7 @@ void BikeSystem::start() {
gearEvent.period(kGearTaskPeriod);
gearEvent.post();
Event<void()> speedDistanceEvent(&eventQueue,
callback(this, &BikeSystem::speedDistanceTask));
Event<void()> speedDistanceEvent(&eventQueue, callback(this, &BikeSystem::speedDistanceTask));
speedDistanceEvent.delay(kSpeedDistanceTaskDelay);
speedDistanceEvent.period(kSpeedDistanceTaskPeriod);
speedDistanceEvent.post();
@ -98,8 +102,7 @@ void BikeSystem::start() {
resetEvent.period(kResetTaskPeriod);
resetEvent.post();
Event<void()> temperatureEvent(&eventQueue,
callback(this, &BikeSystem::temperatureTask));
Event<void()> temperatureEvent(&eventQueue, callback(this, &BikeSystem::temperatureTask));
temperatureEvent.delay(kTemperatureTaskDelay);
temperatureEvent.period(kTemperatureTaskPeriod);
temperatureEvent.post();
@ -159,7 +162,8 @@ void BikeSystem::gearTask() {
_currentGearSize = _gearDevice.getCurrentGearSize();
_taskLogger.logPeriodAndExecutionTime(
_timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime);
_timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime
);
}
void BikeSystem::speedDistanceTask() {
@ -173,7 +177,8 @@ void BikeSystem::speedDistanceTask() {
_traveledDistance = _speedometer.getDistance();
_taskLogger.logPeriodAndExecutionTime(
_timer, advembsof::TaskLogger::kSpeedTaskIndex, taskStartTime);
_timer, advembsof::TaskLogger::kSpeedTaskIndex, taskStartTime
);
}
void BikeSystem::temperatureTask() {
@ -186,8 +191,11 @@ void BikeSystem::temperatureTask() {
//tr_warn("Tick2 %" PRIu64, _timer.elapsed_time().count());
ThisThread::sleep_for(std::chrono::duration_cast<std::chrono::milliseconds>(
kTemperatureTaskComputationTime - (_timer.elapsed_time() - taskStartTime)));
ThisThread::sleep_for(
std::chrono::duration_cast<std::chrono::milliseconds>(
kTemperatureTaskComputationTime - (_timer.elapsed_time() - taskStartTime)
)
);
_taskLogger.logPeriodAndExecutionTime(
_timer, advembsof::TaskLogger::kTemperatureTaskIndex, taskStartTime);
@ -215,8 +223,11 @@ void BikeSystem::displayTask1() {
_displayDevice.displaySpeed(_currentSpeed);
_displayDevice.displayDistance(_traveledDistance);
ThisThread::sleep_for(std::chrono::duration_cast<std::chrono::milliseconds>(
kDisplayTask1ComputationTime - (_timer.elapsed_time() - taskStartTime)));
ThisThread::sleep_for(
std::chrono::duration_cast<std::chrono::milliseconds>(
kDisplayTask1ComputationTime - (_timer.elapsed_time() - taskStartTime)
)
);
_taskLogger.logPeriodAndExecutionTime(
_timer, advembsof::TaskLogger::kDisplayTask1Index, taskStartTime);
@ -227,13 +238,18 @@ void BikeSystem::displayTask2() {
_displayDevice.displayTemperature(_currentTemperature);
ThisThread::sleep_for(std::chrono::duration_cast<std::chrono::milliseconds>(
kDisplayTask2ComputationTime - (_timer.elapsed_time() - taskStartTime)));
ThisThread::sleep_for(
std::chrono::duration_cast<std::chrono::milliseconds>(
kDisplayTask2ComputationTime - (_timer.elapsed_time() - taskStartTime)
)
);
_taskLogger.logPeriodAndExecutionTime(
_timer, advembsof::TaskLogger::kDisplayTask2Index, taskStartTime);
}
void BikeSystem::cpuTask() { _cpuLogger.printStats(); }
void BikeSystem::cpuTask() {
_cpuLogger.printStats();
}
} // namespace static_scheduling_with_event
} // namespace static_scheduling

View File

@ -25,9 +25,9 @@
#pragma once
// from advembsof
#include "cpu_logger.hpp"
#include "display_device.hpp"
#include "task_logger.hpp"
#include "cpu_logger.hpp"
// from common
#include "sensor_device.hpp"
@ -108,4 +108,4 @@ class BikeSystem {
advembsof::CPULogger _cpuLogger;
};
} // namespace static_scheduling_with_event
} // namespace static_scheduling

View File

@ -38,12 +38,17 @@
namespace static_scheduling_with_event {
GearDevice::GearDevice() {
disco::Joystick::getInstance().setUpCallback(callback(this, &GearDevice::onUp));
disco::Joystick::getInstance().setDownCallback(callback(this, &GearDevice::onDown));
disco::Joystick::getInstance().setUpCallback(
callback(this, &GearDevice::onUp));
disco::Joystick::getInstance().setDownCallback(
callback(this, &GearDevice::onDown));
}
uint8_t GearDevice::getCurrentGear() { return core_util_atomic_load_u8(&_currentGear); }
uint8_t GearDevice::getCurrentGear() {
return core_util_atomic_load_u8(&_currentGear);
}
uint8_t GearDevice::getCurrentGearSize() const {
return bike_computer::kMaxGearSize - core_util_atomic_load_u8(&_currentGear);
@ -61,4 +66,4 @@ void GearDevice::onDown() {
}
}
} // namespace static_scheduling_with_event
} // namespace static_scheduling

View File

@ -33,7 +33,7 @@ namespace static_scheduling_with_event {
class GearDevice {
public:
GearDevice(); // NOLINT(runtime/references)
explicit GearDevice(); // NOLINT(runtime/references)
// make the class non copyable
GearDevice(GearDevice&) = delete;
@ -51,4 +51,4 @@ class GearDevice {
volatile uint8_t _currentGear = bike_computer::kMinGear;
};
} // namespace static_scheduling_with_event
} // namespace static_scheduling

View File

@ -1,17 +1,3 @@
// Copyright 2022 Haute école d'ingénierie et d'architecture de Fribourg
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/****************************************************************************
* @file pedal_device.cpp
* @author Rémi Heredero <remi@heredero.ch>
@ -37,15 +23,18 @@
namespace static_scheduling_with_event {
PedalDevice::PedalDevice() {
disco::Joystick::getInstance().setLeftCallback(callback(this, &PedalDevice::onLeft));
disco::Joystick::getInstance().setLeftCallback(
callback(this, &PedalDevice::onLeft)
);
disco::Joystick::getInstance().setRightCallback(
callback(this, &PedalDevice::onRight));
callback(this, &PedalDevice::onRight)
);
}
std::chrono::milliseconds PedalDevice::getCurrentRotationTime() {
uint32_t currentStep = core_util_atomic_load_u32(&_currentStep);
return bike_computer::kMinPedalRotationTime +
currentStep * bike_computer::kDeltaPedalRotationTime;
return bike_computer::kMinPedalRotationTime + currentStep * bike_computer::kDeltaPedalRotationTime;
}
void PedalDevice::increaseRotationSpeed() {
@ -62,8 +51,12 @@ void PedalDevice::decreaseRotationSpeed() {
}
}
void PedalDevice::onLeft() { decreaseRotationSpeed(); }
void PedalDevice::onLeft() {
decreaseRotationSpeed();
}
void PedalDevice::onRight() { increaseRotationSpeed(); }
void PedalDevice::onRight() {
increaseRotationSpeed();
}
} // namespace static_scheduling_with_event
}

View File

@ -51,9 +51,10 @@ class PedalDevice {
// data members
volatile uint32_t _currentStep = static_cast<uint32_t>(
(bike_computer::kInitialPedalRotationTime - bike_computer::kMinPedalRotationTime)
.count() /
bike_computer::kDeltaPedalRotationTime.count());
(
bike_computer::kInitialPedalRotationTime - bike_computer::kMinPedalRotationTime
).count() / bike_computer::kDeltaPedalRotationTime.count()
);
};
} // namespace static_scheduling_with_event
} // namespace static_scheduling

View File

@ -1,17 +1,3 @@
// Copyright 2022 Haute école d'ingénierie et d'architecture de Fribourg
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/****************************************************************************
* @file reset_device.cpp
* @author Rémi Heredero <remi@heredero.ch>
@ -35,6 +21,7 @@
static constexpr uint8_t kPolarityPressed = 1;
#endif
#if MBED_CONF_MBED_TRACE_ENABLE
#define TRACE_GROUP "ResetDevice"
#endif // MBED_CONF_MBED_TRACE_ENABLE
@ -45,4 +32,5 @@ ResetDevice::ResetDevice(Callback<void()> cb) : _resetButton(PUSH_BUTTON) {
_resetButton.fall(cb);
}
} // namespace static_scheduling_with_event
}

View File

@ -39,9 +39,10 @@ class ResetDevice {
ResetDevice& operator=(ResetDevice&) = delete;
private:
// data members
// instance representing the reset button
InterruptIn _resetButton;
};
} // namespace static_scheduling_with_event
} // namespace static_scheduling