From c92de22c09f251ee3b6e5678321d911b0851e013 Mon Sep 17 00:00:00 2001 From: fastium Date: Tue, 26 Nov 2024 16:26:41 +0100 Subject: [PATCH 01/28] ADD create files for multi tasking and modify the main --- main.cpp | 4 +- multi_tasking/bike_system.cpp | 255 +++++++++++++++++++++++++++++++++ multi_tasking/bike_system.hpp | 111 ++++++++++++++ multi_tasking/gear_device.cpp | 69 +++++++++ multi_tasking/gear_device.hpp | 54 +++++++ multi_tasking/pedal_device.cpp | 62 ++++++++ multi_tasking/pedal_device.hpp | 60 ++++++++ multi_tasking/reset_device.cpp | 36 +++++ multi_tasking/reset_device.hpp | 48 +++++++ 9 files changed, 697 insertions(+), 2 deletions(-) create mode 100644 multi_tasking/bike_system.cpp create mode 100644 multi_tasking/bike_system.hpp create mode 100644 multi_tasking/gear_device.cpp create mode 100644 multi_tasking/gear_device.hpp create mode 100644 multi_tasking/pedal_device.cpp create mode 100644 multi_tasking/pedal_device.hpp create mode 100644 multi_tasking/reset_device.cpp create mode 100644 multi_tasking/reset_device.hpp diff --git a/main.cpp b/main.cpp index f8b2f75..ec5fb49 100644 --- a/main.cpp +++ b/main.cpp @@ -8,7 +8,7 @@ #include "mbed.h" // NOLINT #include "mbed_trace.h" //#include "static_scheduling/bike_system.hpp" -#include "static_scheduling_with_event/bike_system.hpp" +#include "multi_tasking/bike_system.hpp" #if defined(MBED_CONF_MBED_TRACE_ENABLE) #define TRACE_GROUP "MAIN" @@ -23,7 +23,7 @@ int main() { // bikeSystem.start(); // bikeSystem.startWithEventQueue(); - static_scheduling_with_event::BikeSystem bikeSystem; + multi_tasking::BikeSystem bikeSystem; bikeSystem.start(); } diff --git a/multi_tasking/bike_system.cpp b/multi_tasking/bike_system.cpp new file mode 100644 index 0000000..b037753 --- /dev/null +++ b/multi_tasking/bike_system.cpp @@ -0,0 +1,255 @@ +// 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 bike_system.cpp + * @author Serge Ayer + * @author Rémi Heredero + * @author Yann Sierro + * + * @brief Bike System implementation (static scheduling) + * + * @date 2023-11-15 + * @version 1.1.0 + ***************************************************************************/ + +#include "bike_system.hpp" + +#include + +#include "mbed_trace.h" +#if MBED_CONF_MBED_TRACE_ENABLE +#define TRACE_GROUP "BikeSystem" +#endif // MBED_CONF_MBED_TRACE_ENABLE + +namespace multi_tasking { + +static constexpr std::chrono::milliseconds kGearTaskPeriod = 800ms; +static constexpr std::chrono::milliseconds kGearTaskDelay = 0ms; +static constexpr std::chrono::milliseconds kGearTaskComputationTime = 100ms; + +static constexpr std::chrono::milliseconds kSpeedDistanceTaskPeriod = 400ms; +static constexpr std::chrono::milliseconds kSpeedDistanceTaskDelay = 100ms; +static constexpr std::chrono::milliseconds kSpeedDistanceTaskComputationTime = 200ms; + +static constexpr std::chrono::milliseconds kDisplayTask1Period = 1600ms; +static constexpr std::chrono::milliseconds kDisplayTask1Delay = 300ms; +static constexpr std::chrono::milliseconds kDisplayTask1ComputationTime = 200ms; + +static constexpr std::chrono::milliseconds kResetTaskPeriod = 800ms; +static constexpr std::chrono::milliseconds kResetTaskDelay = 700ms; +static constexpr std::chrono::milliseconds kResetTaskComputationTime = 100ms; + +static constexpr std::chrono::milliseconds kTemperatureTaskPeriod = 1600ms; +static constexpr std::chrono::milliseconds kTemperatureTaskDelay = 1100ms; +static constexpr std::chrono::milliseconds kTemperatureTaskComputationTime = 100ms; + +static constexpr std::chrono::milliseconds kDisplayTask2Period = 1600ms; +static constexpr std::chrono::milliseconds kDisplayTask2Delay = 1200ms; +static constexpr std::chrono::milliseconds kDisplayTask2ComputationTime = 100ms; + +static constexpr std::chrono::milliseconds kCPUTaskPeriod = 1600ms; +static constexpr std::chrono::milliseconds kCPUTaskDelay = 1200ms; +static constexpr std::chrono::milliseconds kCPUTaskComputationTime = 100ms; + + +BikeSystem::BikeSystem() : + _gearDevice(), + _pedalDevice(), + _resetDevice(callback(this, &BikeSystem::onReset)), + _speedometer(_timer), + _cpuLogger(_timer) +{ + +} + +void BikeSystem::start() { + + tr_info("Starting Super-Loop with event handling"); + + init(); + + EventQueue eventQueue; + + Event gearEvent(&eventQueue, callback(this, &BikeSystem::gearTask)); + gearEvent.delay(kGearTaskDelay); + gearEvent.period(kGearTaskPeriod); + gearEvent.post(); + + Event speedDistanceEvent(&eventQueue, callback(this, &BikeSystem::speedDistanceTask)); + speedDistanceEvent.delay(kSpeedDistanceTaskDelay); + speedDistanceEvent.period(kSpeedDistanceTaskPeriod); + speedDistanceEvent.post(); + + Event display1Event(&eventQueue, callback(this, &BikeSystem::displayTask1)); + display1Event.delay(kDisplayTask1Delay); + display1Event.period(kDisplayTask1Period); + display1Event.post(); + + Event resetEvent(&eventQueue, callback(this, &BikeSystem::resetTask)); + resetEvent.delay(kResetTaskDelay); + resetEvent.period(kResetTaskPeriod); + resetEvent.post(); + + Event temperatureEvent(&eventQueue, callback(this, &BikeSystem::temperatureTask)); + temperatureEvent.delay(kTemperatureTaskDelay); + temperatureEvent.period(kTemperatureTaskPeriod); + temperatureEvent.post(); + + Event display2Event(&eventQueue, callback(this, &BikeSystem::displayTask2)); + display2Event.delay(kDisplayTask2Delay); + display2Event.period(kDisplayTask2Period); + display2Event.post(); + + #if !defined(MBED_TEST_MODE) + Event cpuEvent(&eventQueue, callback(this, &BikeSystem::cpuTask)); + cpuEvent.delay(kCPUTaskDelay); + cpuEvent.period(kCPUTaskPeriod); + cpuEvent.post(); + #endif + + eventQueue.dispatch_forever(); +} + +void BikeSystem::onReset() { + _resetTime = _timer.elapsed_time(); + core_util_atomic_store_bool(&_resetFlag, true); +} + +void BikeSystem::stop() { core_util_atomic_store_bool(&_stopFlag, true); } + +#if defined(MBED_TEST_MODE) +const advembsof::TaskLogger& BikeSystem::getTaskLogger() { return _taskLogger; } +#endif // defined(MBED_TEST_MODE) + +void BikeSystem::init() { + // start the timer + _timer.start(); + + // initialize the lcd display + disco::ReturnCode rc = _displayDevice.init(); + if (rc != disco::ReturnCode::Ok) { + tr_error("Failed to initialized the lcd display: %d", static_cast(rc)); + } + + // initialize the sensor device + bool present = _sensorDevice.init(); + if (!present) { + tr_error("Sensor not present or initialization failed"); + } + + // enable/disable task logging + _taskLogger.enable(true); +} + +void BikeSystem::gearTask() { + // gear task + auto taskStartTime = _timer.elapsed_time(); + + // no need to protect access to data members (single threaded) + _currentGear = _gearDevice.getCurrentGear(); + _currentGearSize = _gearDevice.getCurrentGearSize(); + + _taskLogger.logPeriodAndExecutionTime( + _timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime + ); +} + +void BikeSystem::speedDistanceTask() { + auto taskStartTime = _timer.elapsed_time(); + + const auto pedalRotationTime = _pedalDevice.getCurrentRotationTime(); + _speedometer.setCurrentRotationTime(pedalRotationTime); + _speedometer.setGearSize(_currentGearSize); + + _currentSpeed = _speedometer.getCurrentSpeed(); + _traveledDistance = _speedometer.getDistance(); + + _taskLogger.logPeriodAndExecutionTime( + _timer, advembsof::TaskLogger::kSpeedTaskIndex, taskStartTime + ); +} + +void BikeSystem::temperatureTask() { + auto taskStartTime = _timer.elapsed_time(); + + //tr_warn("Tick1 %" PRIu64, _timer.elapsed_time().count()); + + // no need to protect access to data members (single threaded) + _currentTemperature = _sensorDevice.readTemperature(); + + //tr_warn("Tick2 %" PRIu64, _timer.elapsed_time().count()); + + ThisThread::sleep_for( + std::chrono::duration_cast( + kTemperatureTaskComputationTime - (_timer.elapsed_time() - taskStartTime) + ) + ); + + _taskLogger.logPeriodAndExecutionTime( + _timer, advembsof::TaskLogger::kTemperatureTaskIndex, taskStartTime); +} + +void BikeSystem::resetTask() { + auto taskStartTime = _timer.elapsed_time(); + + if (core_util_atomic_load_bool(&_resetFlag)) { + std::chrono::microseconds responseTime = _timer.elapsed_time() - _resetTime; + tr_info("Reset task: response time is %" PRIu64 " usecs", responseTime.count()); + _speedometer.reset(); + + core_util_atomic_store_bool(&_resetFlag, false); + } + + _taskLogger.logPeriodAndExecutionTime( + _timer, advembsof::TaskLogger::kResetTaskIndex, taskStartTime); +} + +void BikeSystem::displayTask1() { + auto taskStartTime = _timer.elapsed_time(); + + _displayDevice.displayGear(_currentGear); + _displayDevice.displaySpeed(_currentSpeed); + _displayDevice.displayDistance(_traveledDistance); + + ThisThread::sleep_for( + std::chrono::duration_cast( + kDisplayTask1ComputationTime - (_timer.elapsed_time() - taskStartTime) + ) + ); + + _taskLogger.logPeriodAndExecutionTime( + _timer, advembsof::TaskLogger::kDisplayTask1Index, taskStartTime); +} + +void BikeSystem::displayTask2() { + auto taskStartTime = _timer.elapsed_time(); + + _displayDevice.displayTemperature(_currentTemperature); + + ThisThread::sleep_for( + std::chrono::duration_cast( + kDisplayTask2ComputationTime - (_timer.elapsed_time() - taskStartTime) + ) + ); + + _taskLogger.logPeriodAndExecutionTime( + _timer, advembsof::TaskLogger::kDisplayTask2Index, taskStartTime); +} + +void BikeSystem::cpuTask() { + _cpuLogger.printStats(); +} + +} // namespace static_scheduling diff --git a/multi_tasking/bike_system.hpp b/multi_tasking/bike_system.hpp new file mode 100644 index 0000000..d9de4d0 --- /dev/null +++ b/multi_tasking/bike_system.hpp @@ -0,0 +1,111 @@ +// 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 bike_system.hpp + * @author Serge Ayer + * + * @brief Bike System header file (static scheduling) + * + * @date 2023-08-20 + * @version 1.0.0 + ***************************************************************************/ + +#pragma once + +// from advembsof +#include "display_device.hpp" +#include "task_logger.hpp" +#include "cpu_logger.hpp" + +// from common +#include "sensor_device.hpp" +#include "speedometer.hpp" + +// local +#include "gear_device.hpp" +#include "pedal_device.hpp" +#include "reset_device.hpp" + +namespace multi_tasking { + +class BikeSystem { + public: + // constructor + BikeSystem(); + + // make the class non copyable + BikeSystem(BikeSystem&) = delete; + BikeSystem& operator=(BikeSystem&) = delete; + + // method called in main() for starting the system + void start(); + + // method called in main() for starting the sysytem with the event queue + void startWithEventQueue(); + + // method called for stopping the system + void stop(); + +#if defined(MBED_TEST_MODE) + const advembsof::TaskLogger& getTaskLogger(); +#endif // defined(MBED_TEST_MODE) + + private: + // private methods + void init(); + void onReset(); + void gearTask(); + void speedDistanceTask(); + void temperatureTask(); + void resetTask(); + void displayTask1(); + void displayTask2(); + void cpuTask(); + + // stop flag, used for stopping the super-loop (set in stop()) + bool _stopFlag = false; + + std::chrono::microseconds _resetTime = std::chrono::microseconds::zero(); + volatile bool _resetFlag = false; + + // timer instance used for loggint task time and used by ResetDevice + Timer _timer; + // data member that represents the device for manipulating the gear + GearDevice _gearDevice; + uint8_t _currentGear = bike_computer::kMinGear; + uint8_t _currentGearSize = bike_computer::kMinGearSize; + // data member that represents the device for manipulating the pedal rotation + // speed/time + PedalDevice _pedalDevice; + float _currentSpeed = 0.0f; + float _traveledDistance = 0.0f; + // data member that represents the device used for resetting + ResetDevice _resetDevice; + // data member that represents the device display + advembsof::DisplayDevice _displayDevice; + // data member that represents the device for counting wheel rotations + bike_computer::Speedometer _speedometer; + // data member that represents the sensor device + bike_computer::SensorDevice _sensorDevice; + float _currentTemperature = 0.0f; + + // used for logging task info + advembsof::TaskLogger _taskLogger; + + // cpu logger to measure cpu usage + advembsof::CPULogger _cpuLogger; +}; + +} // namespace static_scheduling diff --git a/multi_tasking/gear_device.cpp b/multi_tasking/gear_device.cpp new file mode 100644 index 0000000..2d58274 --- /dev/null +++ b/multi_tasking/gear_device.cpp @@ -0,0 +1,69 @@ +// 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 gear_device.cpp + * @author Serge Ayer + * @author Rémi Heredero + * @author Yann Sierro + * + * @brief Gear Device implementation (static scheduling) + * + * @date 2023-11-17 + * @version 1.1.0 + ***************************************************************************/ + +#include "gear_device.hpp" + +// from disco_h747i/wrappers +#include + +#include "joystick.hpp" +#include "mbed_trace.h" + +#if MBED_CONF_MBED_TRACE_ENABLE +#define TRACE_GROUP "GearDevice" +#endif // MBED_CONF_MBED_TRACE_ENABLE + +namespace multi_tasking { + + +GearDevice::GearDevice() { + 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::getCurrentGearSize() const { + return bike_computer::kMaxGearSize - core_util_atomic_load_u8(&_currentGear); +} + +void GearDevice::onUp() { + if (_currentGear < bike_computer::kMaxGear) { + core_util_atomic_incr_u8(&_currentGear, 1); + } +} + +void GearDevice::onDown() { + if (_currentGear > bike_computer::kMinGear) { + core_util_atomic_decr_u8(&_currentGear, 1); + } +} + +} // namespace static_scheduling diff --git a/multi_tasking/gear_device.hpp b/multi_tasking/gear_device.hpp new file mode 100644 index 0000000..156be30 --- /dev/null +++ b/multi_tasking/gear_device.hpp @@ -0,0 +1,54 @@ +// 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 gear_device.hpp + * @author Serge Ayer + * @author Rémi Heredero + * @author Yann Sierro + * + * @brief Gear Device header file (static scheduling) + * + * @date 2023-11-17 + * @version 1.1.0 + ***************************************************************************/ + +#pragma once + +#include "constants.hpp" +#include "mbed.h" + +namespace multi_tasking { + +class GearDevice { + public: + explicit GearDevice(); // NOLINT(runtime/references) + + // make the class non copyable + GearDevice(GearDevice&) = delete; + GearDevice& operator=(GearDevice&) = delete; + + // method called for updating the bike system + uint8_t getCurrentGear(); + uint8_t getCurrentGearSize() const; + + void onUp(); + void onDown(); + + private: + // data members + volatile uint8_t _currentGear = bike_computer::kMinGear; +}; + +} // namespace static_scheduling diff --git a/multi_tasking/pedal_device.cpp b/multi_tasking/pedal_device.cpp new file mode 100644 index 0000000..350d0ac --- /dev/null +++ b/multi_tasking/pedal_device.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +* @file pedal_device.cpp +* @author Rémi Heredero +* @author Yann Sierro +* +* @brief Pedal Device implementation (static scheduling) +* @date 2024-11-17 +* @version 1.1.0 +****************************************************************************/ + +#include "pedal_device.hpp" + +// from disco_h747i/wrappers +#include + +#include "joystick.hpp" +#include "mbed_trace.h" + +#if MBED_CONF_MBED_TRACE_ENABLE +#define TRACE_GROUP "PedalDevice" +#endif // MBED_CONF_MBED_TRACE_ENABLE + +namespace multi_tasking { + + PedalDevice::PedalDevice() { + disco::Joystick::getInstance().setLeftCallback( + callback(this, &PedalDevice::onLeft) + ); + disco::Joystick::getInstance().setRightCallback( + 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; + } + + void PedalDevice::increaseRotationSpeed() { + uint32_t currentStep = core_util_atomic_load_u32(&_currentStep); + if (currentStep > 0) { + core_util_atomic_decr_u32(&_currentStep, 1); + } + } + + void PedalDevice::decreaseRotationSpeed() { + uint32_t currentStep = core_util_atomic_load_u32(&_currentStep); + if (currentStep < bike_computer::kNbrOfSteps) { + core_util_atomic_incr_u32(&_currentStep, 1); + } + } + + void PedalDevice::onLeft() { + decreaseRotationSpeed(); + } + + void PedalDevice::onRight() { + increaseRotationSpeed(); + } + +} diff --git a/multi_tasking/pedal_device.hpp b/multi_tasking/pedal_device.hpp new file mode 100644 index 0000000..7bb60cd --- /dev/null +++ b/multi_tasking/pedal_device.hpp @@ -0,0 +1,60 @@ +// 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.hpp + * @author Serge Ayer + * @author Rémi Heredero + * @author Yann Sierro + * + * @brief Pedal System header file (static scheduling) + * + * @date 2023-11-17 + * @version 1.1.0 + ***************************************************************************/ + +#pragma once + +#include "constants.hpp" +#include "mbed.h" + +namespace multi_tasking { + +class PedalDevice { + public: + PedalDevice(); // NOLINT(runtime/references) + + // make the class non copyable + PedalDevice(PedalDevice&) = delete; + PedalDevice& operator=(PedalDevice&) = delete; + + // method called for updating the bike system + std::chrono::milliseconds getCurrentRotationTime(); + + private: + // private methods + void onLeft(); + void onRight(); + void increaseRotationSpeed(); + void decreaseRotationSpeed(); + + // data members + volatile uint32_t _currentStep = static_cast( + ( + bike_computer::kInitialPedalRotationTime - bike_computer::kMinPedalRotationTime + ).count() / bike_computer::kDeltaPedalRotationTime.count() + ); +}; + +} // namespace static_scheduling diff --git a/multi_tasking/reset_device.cpp b/multi_tasking/reset_device.cpp new file mode 100644 index 0000000..65a6747 --- /dev/null +++ b/multi_tasking/reset_device.cpp @@ -0,0 +1,36 @@ +/**************************************************************************** +* @file reset_device.cpp +* @author Rémi Heredero +* @author Yann Sierro +* +* @brief Reset Device implementation (static scheduling with event) +* @date 2024-11-17 +* @version 1.1.0 +****************************************************************************/ + +#include "reset_device.hpp" + +// from disco_h747i/wrappers +#include + +#include "joystick.hpp" +#include "mbed_trace.h" + +#if defined(TARGET_DISCO_H747I) +#define PUSH_BUTTON BUTTON1 +static constexpr uint8_t kPolarityPressed = 1; +#endif + + +#if MBED_CONF_MBED_TRACE_ENABLE +#define TRACE_GROUP "ResetDevice" +#endif // MBED_CONF_MBED_TRACE_ENABLE + +namespace multi_tasking { + + ResetDevice::ResetDevice(Callback cb) : _resetButton(PUSH_BUTTON) { + _resetButton.fall(cb); + } + + +} diff --git a/multi_tasking/reset_device.hpp b/multi_tasking/reset_device.hpp new file mode 100644 index 0000000..0df096f --- /dev/null +++ b/multi_tasking/reset_device.hpp @@ -0,0 +1,48 @@ +// 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.hpp + * @author Serge Ayer + * @author Rémi Heredero + * @author Yann Sierro + * + * @brief ResetDevice header file (static scheduling with event) + * + * @date 2023-11-17 + * @version 1.1.0 + ***************************************************************************/ + +#pragma once + +#include "mbed.h" + +namespace multi_tasking { + +class ResetDevice { + public: + explicit ResetDevice(Callback cb); // NOLINT(runtime/references) + + // make the class non copyable + ResetDevice(ResetDevice&) = delete; + ResetDevice& operator=(ResetDevice&) = delete; + + private: + + // data members + // instance representing the reset button + InterruptIn _resetButton; +}; + +} // namespace static_scheduling From 7b5bcfc35e2fd198a3649a3e37c93cc04069f3a4 Mon Sep 17 00:00:00 2001 From: fastium Date: Tue, 26 Nov 2024 16:43:08 +0100 Subject: [PATCH 02/28] ADD typo pre-commit --- main.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main.cpp b/main.cpp index ec5fb49..30f271c 100644 --- a/main.cpp +++ b/main.cpp @@ -5,9 +5,9 @@ #if !MBED_TEST_MODE -#include "mbed.h" // NOLINT -#include "mbed_trace.h" -//#include "static_scheduling/bike_system.hpp" +#include "mbed.h" // NOLINT +#include "mbed_trace.h" // NOLINT +// #include "static_scheduling/bike_system.hpp" #include "multi_tasking/bike_system.hpp" #if defined(MBED_CONF_MBED_TRACE_ENABLE) @@ -19,9 +19,9 @@ int main() { mbed_trace_init(); #endif - // static_scheduling::BikeSystem bikeSystem; - // bikeSystem.start(); - // bikeSystem.startWithEventQueue(); + // static_scheduling::BikeSystem bikeSystem; + // bikeSystem.start(); + // bikeSystem.startWithEventQueue(); multi_tasking::BikeSystem bikeSystem; bikeSystem.start(); From c4ff5361e9aa7c38751a32074bffcc66cc6b4a0b Mon Sep 17 00:00:00 2001 From: fastium Date: Tue, 17 Dec 2024 15:37:16 +0100 Subject: [PATCH 03/28] ADD isr queue --- multi_tasking/bike_system.cpp | 4 ++++ multi_tasking/bike_system.hpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/multi_tasking/bike_system.cpp b/multi_tasking/bike_system.cpp index b037753..3954cbe 100644 --- a/multi_tasking/bike_system.cpp +++ b/multi_tasking/bike_system.cpp @@ -76,6 +76,10 @@ BikeSystem::BikeSystem() : void BikeSystem::start() { + // new thread dedicated for ISRs with its event queue + + + tr_info("Starting Super-Loop with event handling"); init(); diff --git a/multi_tasking/bike_system.hpp b/multi_tasking/bike_system.hpp index d9de4d0..a4e057c 100644 --- a/multi_tasking/bike_system.hpp +++ b/multi_tasking/bike_system.hpp @@ -25,6 +25,7 @@ #pragma once // from advembsof +#include "EventQueue.h" #include "display_device.hpp" #include "task_logger.hpp" #include "cpu_logger.hpp" @@ -106,6 +107,9 @@ class BikeSystem { // cpu logger to measure cpu usage advembsof::CPULogger _cpuLogger; + + // Event queues + EventQueue * _isrEventQueue; }; } // namespace static_scheduling From da79a18cd9549111730d8003a0385bd0aa53202f Mon Sep 17 00:00:00 2001 From: fastium Date: Tue, 17 Dec 2024 16:20:09 +0100 Subject: [PATCH 04/28] ADD correct disco lib in gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ab749f6..7762feb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,5 @@ projectfiles *.py* BUILD mbed-os -DISCO_h747i +DISCO_H74I advdembsof_library From 69bc8785a80ccf6250629c9b7be5f4ab5fe2a895 Mon Sep 17 00:00:00 2001 From: fastium Date: Mon, 30 Dec 2024 16:56:04 +0100 Subject: [PATCH 05/28] ADD threads dispatcher and drive reset with event --- multi_tasking/bike_system.cpp | 147 +++++++-------------------------- multi_tasking/bike_system.hpp | 27 +++--- multi_tasking/reset_device.cpp | 26 +++--- 3 files changed, 56 insertions(+), 144 deletions(-) diff --git a/multi_tasking/bike_system.cpp b/multi_tasking/bike_system.cpp index 3954cbe..f8bd60e 100644 --- a/multi_tasking/bike_system.cpp +++ b/multi_tasking/bike_system.cpp @@ -35,104 +35,29 @@ namespace multi_tasking { -static constexpr std::chrono::milliseconds kGearTaskPeriod = 800ms; -static constexpr std::chrono::milliseconds kGearTaskDelay = 0ms; -static constexpr std::chrono::milliseconds kGearTaskComputationTime = 100ms; - -static constexpr std::chrono::milliseconds kSpeedDistanceTaskPeriod = 400ms; -static constexpr std::chrono::milliseconds kSpeedDistanceTaskDelay = 100ms; -static constexpr std::chrono::milliseconds kSpeedDistanceTaskComputationTime = 200ms; - -static constexpr std::chrono::milliseconds kDisplayTask1Period = 1600ms; -static constexpr std::chrono::milliseconds kDisplayTask1Delay = 300ms; -static constexpr std::chrono::milliseconds kDisplayTask1ComputationTime = 200ms; - -static constexpr std::chrono::milliseconds kResetTaskPeriod = 800ms; -static constexpr std::chrono::milliseconds kResetTaskDelay = 700ms; -static constexpr std::chrono::milliseconds kResetTaskComputationTime = 100ms; - -static constexpr std::chrono::milliseconds kTemperatureTaskPeriod = 1600ms; -static constexpr std::chrono::milliseconds kTemperatureTaskDelay = 1100ms; -static constexpr std::chrono::milliseconds kTemperatureTaskComputationTime = 100ms; - -static constexpr std::chrono::milliseconds kDisplayTask2Period = 1600ms; -static constexpr std::chrono::milliseconds kDisplayTask2Delay = 1200ms; -static constexpr std::chrono::milliseconds kDisplayTask2ComputationTime = 100ms; - -static constexpr std::chrono::milliseconds kCPUTaskPeriod = 1600ms; -static constexpr std::chrono::milliseconds kCPUTaskDelay = 1200ms; -static constexpr std::chrono::milliseconds kCPUTaskComputationTime = 100ms; - - -BikeSystem::BikeSystem() : - _gearDevice(), - _pedalDevice(), - _resetDevice(callback(this, &BikeSystem::onReset)), - _speedometer(_timer), - _cpuLogger(_timer) -{ - -} +BikeSystem::BikeSystem() + : _gearDevice(), + _pedalDevice(), + _resetDevice(callback(this, &BikeSystem::onReset)), + _speedometer(_timer), + _cpuLogger(_timer) {} void BikeSystem::start() { - // new thread dedicated for ISRs with its event queue - - tr_info("Starting Super-Loop with event handling"); init(); - EventQueue eventQueue; - - Event gearEvent(&eventQueue, callback(this, &BikeSystem::gearTask)); - gearEvent.delay(kGearTaskDelay); - gearEvent.period(kGearTaskPeriod); - gearEvent.post(); - - Event speedDistanceEvent(&eventQueue, callback(this, &BikeSystem::speedDistanceTask)); - speedDistanceEvent.delay(kSpeedDistanceTaskDelay); - speedDistanceEvent.period(kSpeedDistanceTaskPeriod); - speedDistanceEvent.post(); - - Event display1Event(&eventQueue, callback(this, &BikeSystem::displayTask1)); - display1Event.delay(kDisplayTask1Delay); - display1Event.period(kDisplayTask1Period); - display1Event.post(); - - Event resetEvent(&eventQueue, callback(this, &BikeSystem::resetTask)); - resetEvent.delay(kResetTaskDelay); - resetEvent.period(kResetTaskPeriod); - resetEvent.post(); - - Event temperatureEvent(&eventQueue, callback(this, &BikeSystem::temperatureTask)); - temperatureEvent.delay(kTemperatureTaskDelay); - temperatureEvent.period(kTemperatureTaskPeriod); - temperatureEvent.post(); - - Event display2Event(&eventQueue, callback(this, &BikeSystem::displayTask2)); - display2Event.delay(kDisplayTask2Delay); - display2Event.period(kDisplayTask2Period); - display2Event.post(); - - #if !defined(MBED_TEST_MODE) - Event cpuEvent(&eventQueue, callback(this, &BikeSystem::cpuTask)); - cpuEvent.delay(kCPUTaskDelay); - cpuEvent.period(kCPUTaskPeriod); - cpuEvent.post(); - #endif - - eventQueue.dispatch_forever(); + _isrEventThread.start(callback(this, &BikeSystem::dispatch_isr_events)); + _mainEventThread.start(callback(this, &BikeSystem::dispatch_events)); } void BikeSystem::onReset() { - _resetTime = _timer.elapsed_time(); - core_util_atomic_store_bool(&_resetFlag, true); + Event resetEvent(&_isrEventQueue, callback(this, &BikeSystem::resetTask)); + resetEvent.post(); } -void BikeSystem::stop() { core_util_atomic_store_bool(&_stopFlag, true); } - #if defined(MBED_TEST_MODE) const advembsof::TaskLogger& BikeSystem::getTaskLogger() { return _taskLogger; } #endif // defined(MBED_TEST_MODE) @@ -166,8 +91,7 @@ void BikeSystem::gearTask() { _currentGearSize = _gearDevice.getCurrentGearSize(); _taskLogger.logPeriodAndExecutionTime( - _timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime - ); + _timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime); } void BikeSystem::speedDistanceTask() { @@ -177,29 +101,25 @@ void BikeSystem::speedDistanceTask() { _speedometer.setCurrentRotationTime(pedalRotationTime); _speedometer.setGearSize(_currentGearSize); - _currentSpeed = _speedometer.getCurrentSpeed(); + _currentSpeed = _speedometer.getCurrentSpeed(); _traveledDistance = _speedometer.getDistance(); _taskLogger.logPeriodAndExecutionTime( - _timer, advembsof::TaskLogger::kSpeedTaskIndex, taskStartTime - ); + _timer, advembsof::TaskLogger::kSpeedTaskIndex, taskStartTime); } void BikeSystem::temperatureTask() { auto taskStartTime = _timer.elapsed_time(); - //tr_warn("Tick1 %" PRIu64, _timer.elapsed_time().count()); + // tr_warn("Tick1 %" PRIu64, _timer.elapsed_time().count()); // no need to protect access to data members (single threaded) _currentTemperature = _sensorDevice.readTemperature(); - //tr_warn("Tick2 %" PRIu64, _timer.elapsed_time().count()); + // tr_warn("Tick2 %" PRIu64, _timer.elapsed_time().count()); - ThisThread::sleep_for( - std::chrono::duration_cast( - kTemperatureTaskComputationTime - (_timer.elapsed_time() - taskStartTime) - ) - ); + ThisThread::sleep_for(std::chrono::duration_cast( + kTemperatureTaskComputationTime - (_timer.elapsed_time() - taskStartTime))); _taskLogger.logPeriodAndExecutionTime( _timer, advembsof::TaskLogger::kTemperatureTaskIndex, taskStartTime); @@ -208,13 +128,8 @@ void BikeSystem::temperatureTask() { void BikeSystem::resetTask() { auto taskStartTime = _timer.elapsed_time(); - if (core_util_atomic_load_bool(&_resetFlag)) { - std::chrono::microseconds responseTime = _timer.elapsed_time() - _resetTime; - tr_info("Reset task: response time is %" PRIu64 " usecs", responseTime.count()); - _speedometer.reset(); - - core_util_atomic_store_bool(&_resetFlag, false); - } + tr_info("Reset task: response time is %" PRIu64 " usecs", responseTime.count()); + _speedometer.reset(); _taskLogger.logPeriodAndExecutionTime( _timer, advembsof::TaskLogger::kResetTaskIndex, taskStartTime); @@ -227,11 +142,8 @@ void BikeSystem::displayTask1() { _displayDevice.displaySpeed(_currentSpeed); _displayDevice.displayDistance(_traveledDistance); - ThisThread::sleep_for( - std::chrono::duration_cast( - kDisplayTask1ComputationTime - (_timer.elapsed_time() - taskStartTime) - ) - ); + ThisThread::sleep_for(std::chrono::duration_cast( + kDisplayTask1ComputationTime - (_timer.elapsed_time() - taskStartTime))); _taskLogger.logPeriodAndExecutionTime( _timer, advembsof::TaskLogger::kDisplayTask1Index, taskStartTime); @@ -242,18 +154,17 @@ void BikeSystem::displayTask2() { _displayDevice.displayTemperature(_currentTemperature); - ThisThread::sleep_for( - std::chrono::duration_cast( - kDisplayTask2ComputationTime - (_timer.elapsed_time() - taskStartTime) - ) - ); + ThisThread::sleep_for(std::chrono::duration_cast( + 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 +void BikeSystem::dispatch_isr_events() { _isrEventQueue.dispatch_forever(); } + +void BikeSystem::dispatch_events() { _eventQueue.dispatch_forever(); } + +} // namespace multi_tasking diff --git a/multi_tasking/bike_system.hpp b/multi_tasking/bike_system.hpp index a4e057c..0cd81ee 100644 --- a/multi_tasking/bike_system.hpp +++ b/multi_tasking/bike_system.hpp @@ -26,9 +26,10 @@ // from advembsof #include "EventQueue.h" -#include "display_device.hpp" -#include "task_logger.hpp" #include "cpu_logger.hpp" +#include "display_device.hpp" +#include "mbed.h" +#include "task_logger.hpp" // from common #include "sensor_device.hpp" @@ -75,22 +76,16 @@ class BikeSystem { void displayTask2(); void cpuTask(); - // stop flag, used for stopping the super-loop (set in stop()) - bool _stopFlag = false; - - std::chrono::microseconds _resetTime = std::chrono::microseconds::zero(); - volatile bool _resetFlag = false; - // timer instance used for loggint task time and used by ResetDevice Timer _timer; // data member that represents the device for manipulating the gear GearDevice _gearDevice; - uint8_t _currentGear = bike_computer::kMinGear; + uint8_t _currentGear = bike_computer::kMinGear; uint8_t _currentGearSize = bike_computer::kMinGearSize; // data member that represents the device for manipulating the pedal rotation // speed/time PedalDevice _pedalDevice; - float _currentSpeed = 0.0f; + float _currentSpeed = 0.0f; float _traveledDistance = 0.0f; // data member that represents the device used for resetting ResetDevice _resetDevice; @@ -109,7 +104,15 @@ class BikeSystem { advembsof::CPULogger _cpuLogger; // Event queues - EventQueue * _isrEventQueue; + EventQueue _isrEventQueue; + EventQueue _eventQueue; + + // Tread for isr events + Thread _isrEventThread; + Thread _mainEventThread; + + void dispatch_isr_events(); + void dispatch_events(); }; -} // namespace static_scheduling +} // namespace multi_tasking diff --git a/multi_tasking/reset_device.cpp b/multi_tasking/reset_device.cpp index 65a6747..0d055ef 100644 --- a/multi_tasking/reset_device.cpp +++ b/multi_tasking/reset_device.cpp @@ -1,12 +1,12 @@ /**************************************************************************** -* @file reset_device.cpp -* @author Rémi Heredero -* @author Yann Sierro -* -* @brief Reset Device implementation (static scheduling with event) -* @date 2024-11-17 -* @version 1.1.0 -****************************************************************************/ + * @file reset_device.cpp + * @author Rémi Heredero + * @author Yann Sierro + * + * @brief Reset Device implementation (static scheduling with event) + * @date 2024-11-17 + * @version 1.1.0 + ****************************************************************************/ #include "reset_device.hpp" @@ -21,16 +21,14 @@ static constexpr uint8_t kPolarityPressed = 1; #endif - #if MBED_CONF_MBED_TRACE_ENABLE #define TRACE_GROUP "ResetDevice" #endif // MBED_CONF_MBED_TRACE_ENABLE namespace multi_tasking { - ResetDevice::ResetDevice(Callback cb) : _resetButton(PUSH_BUTTON) { - _resetButton.fall(cb); - } - - +ResetDevice::ResetDevice(Callback cb) : _resetButton(PUSH_BUTTON) { + _resetButton.fall(cb); } + +} // namespace multi_tasking From ca33d26769d63f94325f0b6beaf381477eb29cae Mon Sep 17 00:00:00 2001 From: fastium Date: Mon, 30 Dec 2024 17:52:08 +0100 Subject: [PATCH 06/28] FIX cpplint errors --- .pre-commit-config.yaml | 5 +- multi_tasking/gear_device.cpp | 13 ++--- multi_tasking/gear_device.hpp | 4 +- multi_tasking/pedal_device.cpp | 97 ++++++++++++++++++---------------- multi_tasking/pedal_device.hpp | 9 ++-- multi_tasking/reset_device.cpp | 14 +++++ multi_tasking/reset_device.hpp | 3 +- 7 files changed, 79 insertions(+), 66 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 17409a6..edf10e4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -files: ^main.cpp|^static_scheduling|^static_scheduling_with_event|^TESTS +files: ^main.cpp|^static_scheduling|^static_scheduling_with_event|^TESTS|^multi_tasking repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.3.0 @@ -22,6 +22,5 @@ repos: - id: cppcheck name: cppcheck require_serial: true - entry: cppcheck --enable=all --suppress=missingInclude --inline-suppr -i mbed-os --std=c++14 --error-exitcode=1 - # --suppress=missingIncludeSystem + entry: cppcheck --enable=all --suppress=missingInclude --suppress=missingIncludeSystem --suppress=unusedFunction --inline-suppr -i mbed-os --std=c++14 --error-exitcode=1 language: system diff --git a/multi_tasking/gear_device.cpp b/multi_tasking/gear_device.cpp index 2d58274..3377c3b 100644 --- a/multi_tasking/gear_device.cpp +++ b/multi_tasking/gear_device.cpp @@ -38,17 +38,12 @@ namespace multi_tasking { - 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); @@ -66,4 +61,4 @@ void GearDevice::onDown() { } } -} // namespace static_scheduling +} // namespace multi_tasking diff --git a/multi_tasking/gear_device.hpp b/multi_tasking/gear_device.hpp index 156be30..d21578f 100644 --- a/multi_tasking/gear_device.hpp +++ b/multi_tasking/gear_device.hpp @@ -33,7 +33,7 @@ namespace multi_tasking { class GearDevice { public: - explicit GearDevice(); // NOLINT(runtime/references) + 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 +} // namespace multi_tasking diff --git a/multi_tasking/pedal_device.cpp b/multi_tasking/pedal_device.cpp index 350d0ac..c4c5214 100644 --- a/multi_tasking/pedal_device.cpp +++ b/multi_tasking/pedal_device.cpp @@ -1,12 +1,26 @@ +// 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 -* @author Yann Sierro -* -* @brief Pedal Device implementation (static scheduling) -* @date 2024-11-17 -* @version 1.1.0 -****************************************************************************/ + * @file pedal_device.cpp + * @author Rémi Heredero + * @author Yann Sierro + * + * @brief Pedal Device implementation (static scheduling) + * @date 2024-11-17 + * @version 1.1.0 + ****************************************************************************/ #include "pedal_device.hpp" @@ -22,41 +36,34 @@ namespace multi_tasking { - PedalDevice::PedalDevice() { - disco::Joystick::getInstance().setLeftCallback( - callback(this, &PedalDevice::onLeft) - ); - disco::Joystick::getInstance().setRightCallback( - 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; - } - - void PedalDevice::increaseRotationSpeed() { - uint32_t currentStep = core_util_atomic_load_u32(&_currentStep); - if (currentStep > 0) { - core_util_atomic_decr_u32(&_currentStep, 1); - } - } - - void PedalDevice::decreaseRotationSpeed() { - uint32_t currentStep = core_util_atomic_load_u32(&_currentStep); - if (currentStep < bike_computer::kNbrOfSteps) { - core_util_atomic_incr_u32(&_currentStep, 1); - } - } - - void PedalDevice::onLeft() { - decreaseRotationSpeed(); - } - - void PedalDevice::onRight() { - increaseRotationSpeed(); - } - +PedalDevice::PedalDevice() { + disco::Joystick::getInstance().setLeftCallback(callback(this, &PedalDevice::onLeft)); + disco::Joystick::getInstance().setRightCallback( + 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; +} + +void PedalDevice::increaseRotationSpeed() { + uint32_t currentStep = core_util_atomic_load_u32(&_currentStep); + if (currentStep > 0) { + core_util_atomic_decr_u32(&_currentStep, 1); + } +} + +void PedalDevice::decreaseRotationSpeed() { + uint32_t currentStep = core_util_atomic_load_u32(&_currentStep); + if (currentStep < bike_computer::kNbrOfSteps) { + core_util_atomic_incr_u32(&_currentStep, 1); + } +} + +void PedalDevice::onLeft() { decreaseRotationSpeed(); } + +void PedalDevice::onRight() { increaseRotationSpeed(); } + +} // namespace multi_tasking diff --git a/multi_tasking/pedal_device.hpp b/multi_tasking/pedal_device.hpp index 7bb60cd..60ab832 100644 --- a/multi_tasking/pedal_device.hpp +++ b/multi_tasking/pedal_device.hpp @@ -51,10 +51,9 @@ class PedalDevice { // data members volatile uint32_t _currentStep = static_cast( - ( - 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 +} // namespace multi_tasking diff --git a/multi_tasking/reset_device.cpp b/multi_tasking/reset_device.cpp index 0d055ef..f4a1fdb 100644 --- a/multi_tasking/reset_device.cpp +++ b/multi_tasking/reset_device.cpp @@ -1,3 +1,17 @@ +// 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 diff --git a/multi_tasking/reset_device.hpp b/multi_tasking/reset_device.hpp index 0df096f..c0a57a5 100644 --- a/multi_tasking/reset_device.hpp +++ b/multi_tasking/reset_device.hpp @@ -39,10 +39,9 @@ class ResetDevice { ResetDevice& operator=(ResetDevice&) = delete; private: - // data members // instance representing the reset button InterruptIn _resetButton; }; -} // namespace static_scheduling +} // namespace multi_tasking From 031b98a0f777caecee9e2b587a6078adc200db24 Mon Sep 17 00:00:00 2001 From: fastium Date: Tue, 31 Dec 2024 08:37:19 +0100 Subject: [PATCH 07/28] FIX lib disco in gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7762feb..41eff4a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,5 @@ projectfiles *.py* BUILD mbed-os -DISCO_H74I +DISCO_H747I advdembsof_library From 34a57162bac6db32c3103ea452ea57896c6119c4 Mon Sep 17 00:00:00 2001 From: fastium Date: Tue, 31 Dec 2024 10:31:00 +0100 Subject: [PATCH 08/28] ADD reset button with its own dispatch queue --- main.cpp | 5 ++- multi_tasking/bike_system.cpp | 74 +++++++++++++++++++++++++++++++---- multi_tasking/bike_system.hpp | 2 +- 3 files changed, 71 insertions(+), 10 deletions(-) diff --git a/main.cpp b/main.cpp index 30f271c..17a3e63 100644 --- a/main.cpp +++ b/main.cpp @@ -7,7 +7,7 @@ #include "mbed.h" // NOLINT #include "mbed_trace.h" // NOLINT -// #include "static_scheduling/bike_system.hpp" +// #include "static_scheduling_with_event/bike_system.hpp" #include "multi_tasking/bike_system.hpp" #if defined(MBED_CONF_MBED_TRACE_ENABLE) @@ -21,7 +21,8 @@ int main() { // static_scheduling::BikeSystem bikeSystem; // bikeSystem.start(); - // bikeSystem.startWithEventQueue(); + // static_scheduling_with_event::BikeSystem bikeSystem; + // bikeSystem.start(); multi_tasking::BikeSystem bikeSystem; bikeSystem.start(); diff --git a/multi_tasking/bike_system.cpp b/multi_tasking/bike_system.cpp index f8bd60e..3bbd1b2 100644 --- a/multi_tasking/bike_system.cpp +++ b/multi_tasking/bike_system.cpp @@ -35,6 +35,28 @@ namespace multi_tasking { +static constexpr std::chrono::milliseconds kGearTaskPeriod = 800ms; +static constexpr std::chrono::milliseconds kGearTaskDelay = 0ms; +static constexpr std::chrono::milliseconds kGearTaskComputationTime = 100ms; +static constexpr std::chrono::milliseconds kSpeedDistanceTaskPeriod = 400ms; +static constexpr std::chrono::milliseconds kSpeedDistanceTaskDelay = 0ms; // 0 or 100ms +static constexpr std::chrono::milliseconds kSpeedDistanceTaskComputationTime = 200ms; +static constexpr std::chrono::milliseconds kDisplayTask1Period = 1600ms; +static constexpr std::chrono::milliseconds kDisplayTask1Delay = 300ms; +static constexpr std::chrono::milliseconds kDisplayTask1ComputationTime = 200ms; +static constexpr std::chrono::milliseconds kResetTaskPeriod = 800ms; +static constexpr std::chrono::milliseconds kResetTaskDelay = 700ms; +static constexpr std::chrono::milliseconds kResetTaskComputationTime = 100ms; +static constexpr std::chrono::milliseconds kTemperatureTaskPeriod = 1600ms; +static constexpr std::chrono::milliseconds kTemperatureTaskDelay = 1100ms; +static constexpr std::chrono::milliseconds kTemperatureTaskComputationTime = 100ms; +static constexpr std::chrono::milliseconds kDisplayTask2Period = 1600ms; +static constexpr std::chrono::milliseconds kDisplayTask2Delay = 1200ms; +static constexpr std::chrono::milliseconds kDisplayTask2ComputationTime = 100ms; +static constexpr std::chrono::milliseconds kCPUTaskPeriod = 1600ms; +static constexpr std::chrono::milliseconds kCPUTaskDelay = 0ms; +static constexpr std::chrono::milliseconds kCPUTaskComputationTime = 0ms; + BikeSystem::BikeSystem() : _gearDevice(), _pedalDevice(), @@ -43,17 +65,46 @@ BikeSystem::BikeSystem() _cpuLogger(_timer) {} void BikeSystem::start() { - // new thread dedicated for ISRs with its event queue - tr_info("Starting Super-Loop with event handling"); init(); - _isrEventThread.start(callback(this, &BikeSystem::dispatch_isr_events)); - _mainEventThread.start(callback(this, &BikeSystem::dispatch_events)); + Event gearEvent(&_eventQueue, callback(this, &BikeSystem::gearTask)); + gearEvent.delay(kGearTaskDelay); + gearEvent.period(kGearTaskPeriod); + gearEvent.post(); + + Event speedDistanceEvent(&_eventQueue, + callback(this, &BikeSystem::speedDistanceTask)); + speedDistanceEvent.delay(kSpeedDistanceTaskDelay); + speedDistanceEvent.period(kSpeedDistanceTaskPeriod); + speedDistanceEvent.post(); + + Event display1Event(&_eventQueue, callback(this, &BikeSystem::displayTask1)); + display1Event.delay(kDisplayTask1Delay); + display1Event.period(kDisplayTask1Period); + display1Event.post(); + + Event temperatureEvent(&_eventQueue, + callback(this, &BikeSystem::temperatureTask)); + temperatureEvent.delay(kTemperatureTaskDelay); + temperatureEvent.period(kTemperatureTaskPeriod); + temperatureEvent.post(); + + Event display2Event(&_eventQueue, callback(this, &BikeSystem::displayTask2)); + display2Event.delay(kDisplayTask2Delay); + display2Event.period(kDisplayTask2Period); + display2Event.post(); + + osStatus status = + _isrEventThread.start(callback(this, &BikeSystem::dispatch_isr_events)); + tr_info("Thread %s started with status %d", _isrEventThread.get_name(), status); + + dispatch_events(); } void BikeSystem::onReset() { + _resetTime = _timer.elapsed_time(); Event resetEvent(&_isrEventQueue, callback(this, &BikeSystem::resetTask)); resetEvent.post(); } @@ -79,7 +130,7 @@ void BikeSystem::init() { } // enable/disable task logging - _taskLogger.enable(true); + _taskLogger.enable(false); } void BikeSystem::gearTask() { @@ -128,6 +179,7 @@ void BikeSystem::temperatureTask() { void BikeSystem::resetTask() { auto taskStartTime = _timer.elapsed_time(); + std::chrono::microseconds responseTime = _timer.elapsed_time() - _resetTime; tr_info("Reset task: response time is %" PRIu64 " usecs", responseTime.count()); _speedometer.reset(); @@ -163,8 +215,16 @@ void BikeSystem::displayTask2() { void BikeSystem::cpuTask() { _cpuLogger.printStats(); } -void BikeSystem::dispatch_isr_events() { _isrEventQueue.dispatch_forever(); } +void BikeSystem::dispatch_isr_events() { + tr_info("Start dispatching isr events"); + _isrEventQueue.dispatch_forever(); + tr_info("Stop dispatching isr events"); +} -void BikeSystem::dispatch_events() { _eventQueue.dispatch_forever(); } +void BikeSystem::dispatch_events() { + tr_info("Start dispatching main events"); + _eventQueue.dispatch_forever(); + tr_info("Stop dispatching main events"); +} } // namespace multi_tasking diff --git a/multi_tasking/bike_system.hpp b/multi_tasking/bike_system.hpp index 0cd81ee..4e11cae 100644 --- a/multi_tasking/bike_system.hpp +++ b/multi_tasking/bike_system.hpp @@ -25,7 +25,6 @@ #pragma once // from advembsof -#include "EventQueue.h" #include "cpu_logger.hpp" #include "display_device.hpp" #include "mbed.h" @@ -77,6 +76,7 @@ class BikeSystem { void cpuTask(); // timer instance used for loggint task time and used by ResetDevice + std::chrono::microseconds _resetTime = std::chrono::microseconds::zero(); Timer _timer; // data member that represents the device for manipulating the gear GearDevice _gearDevice; From f64b8bdd9a53f5e57c150f9baf5212397128beb5 Mon Sep 17 00:00:00 2001 From: fastium Date: Tue, 31 Dec 2024 13:47:36 +0100 Subject: [PATCH 09/28] ADD gear event driven --- multi_tasking/bike_system.cpp | 101 ++++++++++++++++++++++++++++------ multi_tasking/bike_system.hpp | 22 +++++++- multi_tasking/gear_device.cpp | 24 +------- multi_tasking/gear_device.hpp | 13 +---- 4 files changed, 107 insertions(+), 53 deletions(-) diff --git a/multi_tasking/bike_system.cpp b/multi_tasking/bike_system.cpp index 3bbd1b2..f466dc6 100644 --- a/multi_tasking/bike_system.cpp +++ b/multi_tasking/bike_system.cpp @@ -28,6 +28,8 @@ #include +#include "cmsis_os2.h" +#include "constants.hpp" #include "mbed_trace.h" #if MBED_CONF_MBED_TRACE_ENABLE #define TRACE_GROUP "BikeSystem" @@ -58,22 +60,19 @@ static constexpr std::chrono::milliseconds kCPUTaskDelay = 0 static constexpr std::chrono::milliseconds kCPUTaskComputationTime = 0ms; BikeSystem::BikeSystem() - : _gearDevice(), + : _gearDevice(callback(this, &BikeSystem::onGearUp), + callback(this, &BikeSystem::onGearDown)), _pedalDevice(), _resetDevice(callback(this, &BikeSystem::onReset)), _speedometer(_timer), - _cpuLogger(_timer) {} + _cpuLogger(_timer), + _isrEventThread(osPriorityNormal, OS_STACK_SIZE, nullptr, "ISR_Event") {} void BikeSystem::start() { tr_info("Starting Super-Loop with event handling"); init(); - Event gearEvent(&_eventQueue, callback(this, &BikeSystem::gearTask)); - gearEvent.delay(kGearTaskDelay); - gearEvent.period(kGearTaskPeriod); - gearEvent.post(); - Event speedDistanceEvent(&_eventQueue, callback(this, &BikeSystem::speedDistanceTask)); speedDistanceEvent.delay(kSpeedDistanceTaskDelay); @@ -98,7 +97,9 @@ void BikeSystem::start() { osStatus status = _isrEventThread.start(callback(this, &BikeSystem::dispatch_isr_events)); - tr_info("Thread %s started with status %d", _isrEventThread.get_name(), status); + if (status != osOK) { + tr_error("Thread %s started with status %d", _isrEventThread.get_name(), status); + } dispatch_events(); } @@ -109,6 +110,19 @@ void BikeSystem::onReset() { resetEvent.post(); } +void BikeSystem::onGearUp() { + _onGearUpTime = _timer.elapsed_time(); + Event gearUpEvent(&_isrEventQueue, callback(this, &BikeSystem::gearUpTask)); + gearUpEvent.post(); +} + +void BikeSystem::onGearDown() { + _onGearDownTime = _timer.elapsed_time(); + Event gearDownEvent(&_isrEventQueue, + callback(this, &BikeSystem::gearDownTask)); + gearDownEvent.post(); +} + #if defined(MBED_TEST_MODE) const advembsof::TaskLogger& BikeSystem::getTaskLogger() { return _taskLogger; } #endif // defined(MBED_TEST_MODE) @@ -120,7 +134,7 @@ void BikeSystem::init() { // initialize the lcd display disco::ReturnCode rc = _displayDevice.init(); if (rc != disco::ReturnCode::Ok) { - tr_error("Failed to initialized the lcd display: %d", static_cast(rc)); + tr_error("Ffalseailed to initialized the lcd display: %ld", static_cast(rc)); } // initialize the sensor device @@ -130,16 +144,43 @@ void BikeSystem::init() { } // enable/disable task logging - _taskLogger.enable(false); + _taskLogger.enable(true); } -void BikeSystem::gearTask() { - // gear task - auto taskStartTime = _timer.elapsed_time(); +void BikeSystem::gearUpTask() { + auto taskStartTime = _timer.elapsed_time(); + std::chrono::microseconds responseTime = _timer.elapsed_time() - _onGearUpTime; + tr_info("Gear up task: response time is %" PRIu64 " usecs", responseTime.count()); - // no need to protect access to data members (single threaded) - _currentGear = _gearDevice.getCurrentGear(); - _currentGearSize = _gearDevice.getCurrentGearSize(); + // CRITICAL SECTION + mutexGear.lock(); + if (_currentGear < bike_computer::kMaxGear) { + _currentGear++; + mutexGearSize.lock(); + _currentGearSize = bike_computer::kMaxGearSize - _currentGear; + mutexGearSize.unlock(); + } + mutexGear.unlock(); + // END CRITICAL SECTION + + _taskLogger.logPeriodAndExecutionTime( + _timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime); +} +void BikeSystem::gearDownTask() { + auto taskStartTime = _timer.elapsed_time(); + std::chrono::microseconds responseTime = _timer.elapsed_time() - _onGearDownTime; + tr_info("Gear down task: response time is %" PRIu64 " usecs", responseTime.count()); + + // CRITICAL SECTION + mutexGear.lock(); + if (_currentGear > bike_computer::kMinGear) { + _currentGear--; + mutexGearSize.lock(); + _currentGearSize = bike_computer::kMaxGearSize - _currentGear; + mutexGearSize.unlock(); + } + mutexGear.unlock(); + // END CRITICAL SECTION _taskLogger.logPeriodAndExecutionTime( _timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime); @@ -150,7 +191,7 @@ void BikeSystem::speedDistanceTask() { const auto pedalRotationTime = _pedalDevice.getCurrentRotationTime(); _speedometer.setCurrentRotationTime(pedalRotationTime); - _speedometer.setGearSize(_currentGearSize); + _speedometer.setGearSize(getCurrentGearSize()); _currentSpeed = _speedometer.getCurrentSpeed(); _traveledDistance = _speedometer.getDistance(); @@ -190,7 +231,7 @@ void BikeSystem::resetTask() { void BikeSystem::displayTask1() { auto taskStartTime = _timer.elapsed_time(); - _displayDevice.displayGear(_currentGear); + _displayDevice.displayGear(getCurrentGear()); _displayDevice.displaySpeed(_currentSpeed); _displayDevice.displayDistance(_traveledDistance); @@ -227,4 +268,28 @@ void BikeSystem::dispatch_events() { tr_info("Stop dispatching main events"); } +uint8_t BikeSystem::getCurrentGear() { + uint8_t currentGear; + + // CRITICAL SECTION + mutexGear.lock(); + currentGear = _currentGear; + mutexGear.unlock(); + // END CRITICAL SECTION + + return currentGear; +} + +uint8_t BikeSystem::getCurrentGearSize() { + uint8_t currentGearSize; + + // CRITICAL SECTION + mutexGearSize.lock(); + currentGearSize = _currentGearSize; + mutexGearSize.unlock(); + // END CRITICAL SECTION + + return currentGearSize; +} + } // namespace multi_tasking diff --git a/multi_tasking/bike_system.hpp b/multi_tasking/bike_system.hpp index 4e11cae..c9149a0 100644 --- a/multi_tasking/bike_system.hpp +++ b/multi_tasking/bike_system.hpp @@ -67,7 +67,10 @@ class BikeSystem { // private methods void init(); void onReset(); - void gearTask(); + void onGearUp(); + void onGearDown(); + void gearUpTask(); + void gearDownTask(); void speedDistanceTask(); void temperatureTask(); void resetTask(); @@ -75,13 +78,23 @@ class BikeSystem { void displayTask2(); void cpuTask(); + uint8_t getCurrentGear(); + uint8_t getCurrentGearSize(); + void setCurrentGear(uint8_t gear); + // timer instance used for loggint task time and used by ResetDevice - std::chrono::microseconds _resetTime = std::chrono::microseconds::zero(); + std::chrono::microseconds _resetTime = std::chrono::microseconds::zero(); + std::chrono::microseconds _onGearUpTime = std::chrono::microseconds::zero(); + std::chrono::microseconds _onGearDownTime = std::chrono::microseconds::zero(); + Timer _timer; // data member that represents the device for manipulating the gear GearDevice _gearDevice; + ////////////////////////////////////////////////////////////// + // shared resources between the main thread and the isr thread uint8_t _currentGear = bike_computer::kMinGear; uint8_t _currentGearSize = bike_computer::kMinGearSize; + ////////////////////////////////////////////////////////////// // data member that represents the device for manipulating the pedal rotation // speed/time PedalDevice _pedalDevice; @@ -107,9 +120,12 @@ class BikeSystem { EventQueue _isrEventQueue; EventQueue _eventQueue; + // mutex for shared resource + Mutex mutexGearSize; + Mutex mutexGear; + // Tread for isr events Thread _isrEventThread; - Thread _mainEventThread; void dispatch_isr_events(); void dispatch_events(); diff --git a/multi_tasking/gear_device.cpp b/multi_tasking/gear_device.cpp index 3377c3b..33acd54 100644 --- a/multi_tasking/gear_device.cpp +++ b/multi_tasking/gear_device.cpp @@ -38,27 +38,9 @@ namespace multi_tasking { -GearDevice::GearDevice() { - 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::getCurrentGearSize() const { - return bike_computer::kMaxGearSize - core_util_atomic_load_u8(&_currentGear); -} - -void GearDevice::onUp() { - if (_currentGear < bike_computer::kMaxGear) { - core_util_atomic_incr_u8(&_currentGear, 1); - } -} - -void GearDevice::onDown() { - if (_currentGear > bike_computer::kMinGear) { - core_util_atomic_decr_u8(&_currentGear, 1); - } +GearDevice::GearDevice(Callback cbOnUp, Callback cbOnDown) { + disco::Joystick::getInstance().setUpCallback(callback(cbOnUp)); + disco::Joystick::getInstance().setDownCallback(callback(cbOnDown)); } } // namespace multi_tasking diff --git a/multi_tasking/gear_device.hpp b/multi_tasking/gear_device.hpp index d21578f..4ff6cb1 100644 --- a/multi_tasking/gear_device.hpp +++ b/multi_tasking/gear_device.hpp @@ -26,29 +26,20 @@ #pragma once -#include "constants.hpp" #include "mbed.h" namespace multi_tasking { class GearDevice { public: - GearDevice(); // NOLINT(runtime/references) + GearDevice(Callback cbOnUp, + Callback cbOnDown); // NOLINT(runtime/references) // make the class non copyable GearDevice(GearDevice&) = delete; GearDevice& operator=(GearDevice&) = delete; // method called for updating the bike system - uint8_t getCurrentGear(); - uint8_t getCurrentGearSize() const; - - void onUp(); - void onDown(); - - private: - // data members - volatile uint8_t _currentGear = bike_computer::kMinGear; }; } // namespace multi_tasking From 957860b2ffebdb3056e178f41513d245f2d4d5ca Mon Sep 17 00:00:00 2001 From: fastium Date: Tue, 31 Dec 2024 14:41:16 +0100 Subject: [PATCH 10/28] ADD answer question 1 --- README.md | 31 +++++++++++++++++++++++-------- multi_tasking/bike_system.cpp | 4 ++-- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index f919c9e..68a50c1 100644 --- a/README.md +++ b/README.md @@ -23,25 +23,25 @@ Test sensor libraries : mbed test -m DISCO_H747I -t GCC_ARM -n advdembsof_library-tests-sensors-hdc1000 --compile --run ``` -## Run static scheduling +## Run static scheduling On `.mbedignore` put at the end of the file ``` static_scheduling_with_event/* ``` -On main.cpp include `"static_scheduling/bike_system.hpp"` and use : +On main.cpp include `"static_scheduling/bike_system.hpp"` and use : ```cpp static_scheduling::BikeSystem bikeSystem; bikeSystem.start(); ``` ## Run static scheduling with event queue -On `.mbedignore` put at the end of the file : +On `.mbedignore` put at the end of the file : ``` static_scheduling_with_event/* ``` -On main.cpp include `"static_scheduling/bike_system.hpp"` and use : +On main.cpp include `"static_scheduling/bike_system.hpp"` and use : ```cpp static_scheduling::BikeSystem bikeSystem; bikeSystem.startWithEventQueue(); @@ -53,7 +53,7 @@ On `.mbedignore` put at the end of the file static_scheduling/* ``` -On main.cpp include `"static_scheduling_with_event/bike_system.hpp"` and use : +On main.cpp include `"static_scheduling_with_event/bike_system.hpp"` and use : ```cpp static_scheduling_with_event::BikeSystem bikeSystem; bikeSystem.start(); @@ -63,7 +63,7 @@ bikeSystem.start(); ## Question 1 `If you print CPU statistics at the end of every major cycle (in the super-loop), what CPU usage do you observe? How can you explain the observed CPU uptime?` -We observe a 100% usage because on each CPU cycle it compare if time is done. +We observe a 100% usage because on each CPU cycle it compare if time is done. ## Question 2 `If you run the program after the change from busy wait to sleep calls, what CPU usage do you observe? How can you explain the observed CPU uptime?` @@ -73,7 +73,7 @@ We can observe only a usage of 75% because the CPU is more on Idle with Thread s ## Question 3 `If you run the static_scheduling_with_event program, what CPU usage do you observe? How can you explain the observed CPU uptime?` -We observe a light usage of 1% of CPU. The CPU is now sleeping all the time and doing small task only on event. +We observe a light usage of 1% of CPU. The CPU is now sleeping all the time and doing small task only on event. ## Question 4 `When you run multiple tests for computing the response time of the reset event, what do you observe? Is there an improvement as compared to the static_scheduling::BikeSystem implementation?` @@ -84,7 +84,22 @@ We observe a light usage of 1% of CPU. The CPU is now sleeping all the time and 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. +# Multi-tasking + +## Question 1 +We have computed the elapsed time between the event is sent by the interruption until it is executed : + +|Rtos priority |time | +|---|---| +|osPriorityBelowNormal |13 usecs | +|osPriorityNormal |13 usecs | +|osPriorityAboveNormal |13 usecs | + +To abtain these values, we have to consider that there is a isr thread. He dispatchs all the events from the gear device and the reset device. The rest is processed by the main thread. + +Main of the time, it meares these values. But sometimes, higher values can appear. These values doesn't change because there isn't often more than one event in the queue. + # 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 \ No newline at end of file +As the acceptable delta is 2ms and the teacher test is done with GCC, we modify the delta on the test to be 3ms diff --git a/multi_tasking/bike_system.cpp b/multi_tasking/bike_system.cpp index f466dc6..53ed6c2 100644 --- a/multi_tasking/bike_system.cpp +++ b/multi_tasking/bike_system.cpp @@ -66,7 +66,7 @@ BikeSystem::BikeSystem() _resetDevice(callback(this, &BikeSystem::onReset)), _speedometer(_timer), _cpuLogger(_timer), - _isrEventThread(osPriorityNormal, OS_STACK_SIZE, nullptr, "ISR_Event") {} + _isrEventThread(osPriorityAboveNormal, OS_STACK_SIZE, nullptr, "ISR_Event") {} void BikeSystem::start() { tr_info("Starting Super-Loop with event handling"); @@ -144,7 +144,7 @@ void BikeSystem::init() { } // enable/disable task logging - _taskLogger.enable(true); + _taskLogger.enable(false); } void BikeSystem::gearUpTask() { From 36e4a071023a77083340c588f1d0b78ad9a33983 Mon Sep 17 00:00:00 2001 From: fastium Date: Tue, 31 Dec 2024 14:47:45 +0100 Subject: [PATCH 11/28] ADD run multi-tasking in README --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 68a50c1..4d7a5f6 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ mbed test -m DISCO_H747I -t GCC_ARM -n advdembsof_library-tests-sensors-hdc1000 On `.mbedignore` put at the end of the file ``` static_scheduling_with_event/* +multi_tasking/* ``` On main.cpp include `"static_scheduling/bike_system.hpp"` and use : @@ -39,6 +40,7 @@ bikeSystem.start(); On `.mbedignore` put at the end of the file : ``` static_scheduling_with_event/* +multi_tasking/* ``` On main.cpp include `"static_scheduling/bike_system.hpp"` and use : @@ -51,6 +53,20 @@ bikeSystem.startWithEventQueue(); On `.mbedignore` put at the end of the file ``` static_scheduling/* +static_scheduling_with_event/* +``` + +On main.cpp include `"multi_tasking/bike_system.hpp"` and use : +```cpp +multi_tasking::BikeSystem bikeSystem; +bikeSystem.start(); +``` + +## Run multi-tasking +On `.mbedignore` put at the end of the file +``` +static_scheduling/* +multi_tasking/* ``` On main.cpp include `"static_scheduling_with_event/bike_system.hpp"` and use : From 946e86025c11c5a2b88a7699e42a96c807d5c0a3 Mon Sep 17 00:00:00 2001 From: fastium Date: Tue, 31 Dec 2024 16:02:42 +0100 Subject: [PATCH 12/28] ADD part of mail for pedal device --- multi_tasking/bike_system.cpp | 1 + multi_tasking/bike_system.hpp | 13 ++++++++++--- multi_tasking/pedal_device.cpp | 7 +++---- multi_tasking/pedal_device.hpp | 9 ++------- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/multi_tasking/bike_system.cpp b/multi_tasking/bike_system.cpp index 53ed6c2..a50fa00 100644 --- a/multi_tasking/bike_system.cpp +++ b/multi_tasking/bike_system.cpp @@ -191,6 +191,7 @@ void BikeSystem::speedDistanceTask() { const auto pedalRotationTime = _pedalDevice.getCurrentRotationTime(); _speedometer.setCurrentRotationTime(pedalRotationTime); + _speedometer.setGearSize(getCurrentGearSize()); _currentSpeed = _speedometer.getCurrentSpeed(); diff --git a/multi_tasking/bike_system.hpp b/multi_tasking/bike_system.hpp index c9149a0..19b449f 100644 --- a/multi_tasking/bike_system.hpp +++ b/multi_tasking/bike_system.hpp @@ -82,6 +82,9 @@ class BikeSystem { uint8_t getCurrentGearSize(); void setCurrentGear(uint8_t gear); + void dispatch_isr_events(); + void dispatch_events(); + // timer instance used for loggint task time and used by ResetDevice std::chrono::microseconds _resetTime = std::chrono::microseconds::zero(); std::chrono::microseconds _onGearUpTime = std::chrono::microseconds::zero(); @@ -90,16 +93,23 @@ class BikeSystem { Timer _timer; // data member that represents the device for manipulating the gear GearDevice _gearDevice; + ////////////////////////////////////////////////////////////// // shared resources between the main thread and the isr thread uint8_t _currentGear = bike_computer::kMinGear; uint8_t _currentGearSize = bike_computer::kMinGearSize; ////////////////////////////////////////////////////////////// + // data member that represents the device for manipulating the pedal rotation // speed/time PedalDevice _pedalDevice; + + ////////////////////////////////////////////////////////////// + // shared resources between the main thread and the isr thread float _currentSpeed = 0.0f; float _traveledDistance = 0.0f; + ////////////////////////////////////////////////////////////// + // data member that represents the device used for resetting ResetDevice _resetDevice; // data member that represents the device display @@ -126,9 +136,6 @@ class BikeSystem { // Tread for isr events Thread _isrEventThread; - - void dispatch_isr_events(); - void dispatch_events(); }; } // namespace multi_tasking diff --git a/multi_tasking/pedal_device.cpp b/multi_tasking/pedal_device.cpp index c4c5214..06ecdb5 100644 --- a/multi_tasking/pedal_device.cpp +++ b/multi_tasking/pedal_device.cpp @@ -36,10 +36,9 @@ namespace multi_tasking { -PedalDevice::PedalDevice() { - disco::Joystick::getInstance().setLeftCallback(callback(this, &PedalDevice::onLeft)); - disco::Joystick::getInstance().setRightCallback( - callback(this, &PedalDevice::onRight)); +PedalDevice::PedalDevice(Callback cbOnLeft, Callback cbOnRight) { + disco::Joystick::getInstance().setLeftCallback(callback(cbOnLeft)); + disco::Joystick::getInstance().setRightCallback(callback(cbOnRight)); } std::chrono::milliseconds PedalDevice::getCurrentRotationTime() { diff --git a/multi_tasking/pedal_device.hpp b/multi_tasking/pedal_device.hpp index 60ab832..8787548 100644 --- a/multi_tasking/pedal_device.hpp +++ b/multi_tasking/pedal_device.hpp @@ -33,7 +33,8 @@ namespace multi_tasking { class PedalDevice { public: - PedalDevice(); // NOLINT(runtime/references) + PedalDevice(Callback cbOnLeft, + Callback cbOnRight); // NOLINT(runtime/references) // make the class non copyable PedalDevice(PedalDevice&) = delete; @@ -43,12 +44,6 @@ class PedalDevice { std::chrono::milliseconds getCurrentRotationTime(); private: - // private methods - void onLeft(); - void onRight(); - void increaseRotationSpeed(); - void decreaseRotationSpeed(); - // data members volatile uint32_t _currentStep = static_cast( (bike_computer::kInitialPedalRotationTime - bike_computer::kMinPedalRotationTime) From 95e92e256436d15c21d2a8659d8629e41975e0f3 Mon Sep 17 00:00:00 2001 From: fastium Date: Fri, 3 Jan 2025 17:10:42 +0100 Subject: [PATCH 13/28] ADD mail box for pedal device --- .pre-commit-config.yaml | 2 +- multi_tasking/bike_system.cpp | 276 ++++++++++++++++++++------------- multi_tasking/bike_system.hpp | 30 ++-- multi_tasking/pedal_device.cpp | 30 +++- multi_tasking/pedal_device.hpp | 14 +- 5 files changed, 227 insertions(+), 125 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index edf10e4..d935e1f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,5 +22,5 @@ repos: - id: cppcheck name: cppcheck require_serial: true - entry: cppcheck --enable=all --suppress=missingInclude --suppress=missingIncludeSystem --suppress=unusedFunction --inline-suppr -i mbed-os --std=c++14 --error-exitcode=1 + entry: cppcheck --enable=all --suppress=missingInclude --suppress=missingIncludeSystem --suppress=unusedFunction --suppress=unusedStructMember --inline-suppr -i mbed-os --std=c++14 --error-exitcode=1 language: system diff --git a/multi_tasking/bike_system.cpp b/multi_tasking/bike_system.cpp index a50fa00..3a10e41 100644 --- a/multi_tasking/bike_system.cpp +++ b/multi_tasking/bike_system.cpp @@ -28,9 +28,11 @@ #include +#include "Callback.h" #include "cmsis_os2.h" #include "constants.hpp" #include "mbed_trace.h" +#include "pedal_device.hpp" #if MBED_CONF_MBED_TRACE_ENABLE #define TRACE_GROUP "BikeSystem" #endif // MBED_CONF_MBED_TRACE_ENABLE @@ -62,11 +64,36 @@ static constexpr std::chrono::milliseconds kCPUTaskComputationTime = 0 BikeSystem::BikeSystem() : _gearDevice(callback(this, &BikeSystem::onGearUp), callback(this, &BikeSystem::onGearDown)), - _pedalDevice(), + _pedalDevice(&_mailPedalDevice), _resetDevice(callback(this, &BikeSystem::onReset)), _speedometer(_timer), _cpuLogger(_timer), - _isrEventThread(osPriorityAboveNormal, OS_STACK_SIZE, nullptr, "ISR_Event") {} + _isrEventThread(osPriorityAboveNormal, OS_STACK_SIZE, nullptr, "ISR_Event"), + _speedDistanceThread( + osPriorityNormal, OS_STACK_SIZE, nullptr, "Speed_distance_Task") {} +#if defined(MBED_TEST_MODE) +const advembsof::TaskLogger& BikeSystem::getTaskLogger() { return _taskLogger; } +#endif // defined(MBED_TEST_MODE) + +void BikeSystem::init() { + // start the timer + _timer.start(); + + // initialize the lcd display + disco::ReturnCode rc = _displayDevice.init(); + if (rc != disco::ReturnCode::Ok) { + tr_error("Ffalseailed to initialized the lcd display: %ld", static_cast(rc)); + } + + // initialize the sensor device + bool present = _sensorDevice.init(); + if (!present) { + tr_error("Sensor not present or initialization failed"); + } + + // enable/disable task logging + _taskLogger.enable(false); +} void BikeSystem::start() { tr_info("Starting Super-Loop with event handling"); @@ -101,9 +128,18 @@ void BikeSystem::start() { tr_error("Thread %s started with status %d", _isrEventThread.get_name(), status); } + status = + _speedDistanceThread.start(callback(this, &BikeSystem::loop_speed_distance_task)); + if (status != osOK) { + tr_error("Thread %s started with status %d", _isrEventThread.get_name(), status); + } + + // dispathc the main queue in the main thread dispatch_events(); } +/* Callback from isr */ + void BikeSystem::onReset() { _resetTime = _timer.elapsed_time(); Event resetEvent(&_isrEventQueue, callback(this, &BikeSystem::resetTask)); @@ -123,100 +159,7 @@ void BikeSystem::onGearDown() { gearDownEvent.post(); } -#if defined(MBED_TEST_MODE) -const advembsof::TaskLogger& BikeSystem::getTaskLogger() { return _taskLogger; } -#endif // defined(MBED_TEST_MODE) - -void BikeSystem::init() { - // start the timer - _timer.start(); - - // initialize the lcd display - disco::ReturnCode rc = _displayDevice.init(); - if (rc != disco::ReturnCode::Ok) { - tr_error("Ffalseailed to initialized the lcd display: %ld", static_cast(rc)); - } - - // initialize the sensor device - bool present = _sensorDevice.init(); - if (!present) { - tr_error("Sensor not present or initialization failed"); - } - - // enable/disable task logging - _taskLogger.enable(false); -} - -void BikeSystem::gearUpTask() { - auto taskStartTime = _timer.elapsed_time(); - std::chrono::microseconds responseTime = _timer.elapsed_time() - _onGearUpTime; - tr_info("Gear up task: response time is %" PRIu64 " usecs", responseTime.count()); - - // CRITICAL SECTION - mutexGear.lock(); - if (_currentGear < bike_computer::kMaxGear) { - _currentGear++; - mutexGearSize.lock(); - _currentGearSize = bike_computer::kMaxGearSize - _currentGear; - mutexGearSize.unlock(); - } - mutexGear.unlock(); - // END CRITICAL SECTION - - _taskLogger.logPeriodAndExecutionTime( - _timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime); -} -void BikeSystem::gearDownTask() { - auto taskStartTime = _timer.elapsed_time(); - std::chrono::microseconds responseTime = _timer.elapsed_time() - _onGearDownTime; - tr_info("Gear down task: response time is %" PRIu64 " usecs", responseTime.count()); - - // CRITICAL SECTION - mutexGear.lock(); - if (_currentGear > bike_computer::kMinGear) { - _currentGear--; - mutexGearSize.lock(); - _currentGearSize = bike_computer::kMaxGearSize - _currentGear; - mutexGearSize.unlock(); - } - mutexGear.unlock(); - // END CRITICAL SECTION - - _taskLogger.logPeriodAndExecutionTime( - _timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime); -} - -void BikeSystem::speedDistanceTask() { - auto taskStartTime = _timer.elapsed_time(); - - const auto pedalRotationTime = _pedalDevice.getCurrentRotationTime(); - _speedometer.setCurrentRotationTime(pedalRotationTime); - - _speedometer.setGearSize(getCurrentGearSize()); - - _currentSpeed = _speedometer.getCurrentSpeed(); - _traveledDistance = _speedometer.getDistance(); - - _taskLogger.logPeriodAndExecutionTime( - _timer, advembsof::TaskLogger::kSpeedTaskIndex, taskStartTime); -} - -void BikeSystem::temperatureTask() { - auto taskStartTime = _timer.elapsed_time(); - - // tr_warn("Tick1 %" PRIu64, _timer.elapsed_time().count()); - - // no need to protect access to data members (single threaded) - _currentTemperature = _sensorDevice.readTemperature(); - - // tr_warn("Tick2 %" PRIu64, _timer.elapsed_time().count()); - - ThisThread::sleep_for(std::chrono::duration_cast( - kTemperatureTaskComputationTime - (_timer.elapsed_time() - taskStartTime))); - - _taskLogger.logPeriodAndExecutionTime( - _timer, advembsof::TaskLogger::kTemperatureTaskIndex, taskStartTime); -} +// ISR thread functions void BikeSystem::resetTask() { auto taskStartTime = _timer.elapsed_time(); @@ -229,12 +172,106 @@ void BikeSystem::resetTask() { _timer, advembsof::TaskLogger::kResetTaskIndex, taskStartTime); } +// Speed distance thread functions + +void BikeSystem::speedDistanceTask() { + auto taskStartTime = _timer.elapsed_time(); + + uint32_t* currentStep = _mailPedalDevice.try_get(); + + if (currentStep != nullptr) { + const auto pedalRotationTime = PedalDevice::getCurrentRotationTime(*currentStep); + + osStatus status = _mailPedalDevice.free(currentStep); + if (status != osOK) { + tr_error("free current step in the speed distance tasks doesn't work !"); + } + + // ENTER CRITICAL SECTION + _mutexSpeedometer.lock(); + _speedometer.setCurrentRotationTime(pedalRotationTime); + _mutexSpeedometer.unlock(); + // END CRITICAL SECTION + } + + // ENTER CRITICAL SECTION + _mutexSpeedometer.lock(); + _speedometer.setGearSize(getCurrentGearSize()); + _mutexSpeed.lock(); + _currentSpeed = _speedometer.getCurrentSpeed(); + _mutexSpeed.unlock(); + _mutexDistance.lock(); + _traveledDistance = _speedometer.getDistance(); + _mutexDistance.unlock(); + _mutexSpeedometer.unlock(); + // END CRITICAL SECTION + + _taskLogger.logPeriodAndExecutionTime( + _timer, advembsof::TaskLogger::kSpeedTaskIndex, taskStartTime); +} + +/* Main thread functions */ + +void BikeSystem::gearUpTask() { + auto taskStartTime = _timer.elapsed_time(); + std::chrono::microseconds responseTime = _timer.elapsed_time() - _onGearUpTime; + tr_info("Gear up task: response time is %" PRIu64 " usecs", responseTime.count()); + + // ENTER CRITICAL SECTION + _mutexGear.lock(); + if (_currentGear < bike_computer::kMaxGear) { + _currentGear++; + _mutexGearSize.lock(); + _currentGearSize = bike_computer::kMaxGearSize - _currentGear; + _mutexGearSize.unlock(); + } + _mutexGear.unlock(); + // END CRITICAL SECTION + + _taskLogger.logPeriodAndExecutionTime( + _timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime); +} +void BikeSystem::gearDownTask() { + auto taskStartTime = _timer.elapsed_time(); + std::chrono::microseconds responseTime = _timer.elapsed_time() - _onGearDownTime; + tr_info("Gear down task: response time is %" PRIu64 " usecs", responseTime.count()); + + // ENTER CRITICAL SECTION + _mutexGear.lock(); + if (_currentGear > bike_computer::kMinGear) { + _currentGear--; + _mutexGearSize.lock(); + _currentGearSize = bike_computer::kMaxGearSize - _currentGear; + _mutexGearSize.unlock(); + } + _mutexGear.unlock(); + // END CRITICAL SECTION + + _taskLogger.logPeriodAndExecutionTime( + _timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime); +} + +void BikeSystem::temperatureTask() { + auto taskStartTime = _timer.elapsed_time(); + + // no need to protect access to data members (single threaded) + _currentTemperature = _sensorDevice.readTemperature(); + + ThisThread::sleep_for(std::chrono::duration_cast( + kTemperatureTaskComputationTime - (_timer.elapsed_time() - taskStartTime))); + + _taskLogger.logPeriodAndExecutionTime( + _timer, advembsof::TaskLogger::kTemperatureTaskIndex, taskStartTime); +} + void BikeSystem::displayTask1() { auto taskStartTime = _timer.elapsed_time(); + // ENTER CRITICAL SECTION _displayDevice.displayGear(getCurrentGear()); - _displayDevice.displaySpeed(_currentSpeed); - _displayDevice.displayDistance(_traveledDistance); + _displayDevice.displaySpeed(getCurrentSpeed()); + _displayDevice.displayDistance(getCurrentDistance()); + // END CRITICAL SECTION ThisThread::sleep_for(std::chrono::duration_cast( kDisplayTask1ComputationTime - (_timer.elapsed_time() - taskStartTime))); @@ -269,13 +306,20 @@ void BikeSystem::dispatch_events() { tr_info("Stop dispatching main events"); } +void BikeSystem::loop_speed_distance_task() { + tr_info("Start loop speed-distance calculation"); + while (true) { + speedDistanceTask(); + } +} + uint8_t BikeSystem::getCurrentGear() { uint8_t currentGear; - // CRITICAL SECTION - mutexGear.lock(); + // ENTER CRITICAL SECTION + _mutexGear.lock(); currentGear = _currentGear; - mutexGear.unlock(); + _mutexGear.unlock(); // END CRITICAL SECTION return currentGear; @@ -284,13 +328,37 @@ uint8_t BikeSystem::getCurrentGear() { uint8_t BikeSystem::getCurrentGearSize() { uint8_t currentGearSize; - // CRITICAL SECTION - mutexGearSize.lock(); + // ENTER CRITICAL SECTION + _mutexGearSize.lock(); currentGearSize = _currentGearSize; - mutexGearSize.unlock(); + _mutexGearSize.unlock(); // END CRITICAL SECTION return currentGearSize; } +uint32_t BikeSystem::getCurrentSpeed() { + uint32_t currentSpeed; + + // ENTER CRITICAL SECTION + _mutexSpeed.lock(); + currentSpeed = _currentSpeed; + _mutexSpeed.unlock(); + // END CRITICAL SECTION + + return currentSpeed; +} + +uint32_t BikeSystem::getCurrentDistance() { + uint32_t currentDistance; + + // ENTER CRITICAL SECTION + _mutexDistance.lock(); + currentDistance = _traveledDistance; + _mutexDistance.unlock(); + // END CRITICAL SECTION + + return currentDistance; +} + } // namespace multi_tasking diff --git a/multi_tasking/bike_system.hpp b/multi_tasking/bike_system.hpp index 19b449f..7031b10 100644 --- a/multi_tasking/bike_system.hpp +++ b/multi_tasking/bike_system.hpp @@ -53,9 +53,6 @@ class BikeSystem { // method called in main() for starting the system void start(); - // method called in main() for starting the sysytem with the event queue - void startWithEventQueue(); - // method called for stopping the system void stop(); @@ -66,24 +63,32 @@ class BikeSystem { private: // private methods void init(); + // Main Thread + void temperatureTask(); + void displayTask1(); + void displayTask2(); + void cpuTask(); + + // ISR Thread void onReset(); void onGearUp(); void onGearDown(); void gearUpTask(); void gearDownTask(); void speedDistanceTask(); - void temperatureTask(); void resetTask(); - void displayTask1(); - void displayTask2(); - void cpuTask(); + // uint8_t getCurrentGear(); uint8_t getCurrentGearSize(); + uint32_t getCurrentSpeed(); + uint32_t getCurrentDistance(); + void setCurrentGear(uint8_t gear); void dispatch_isr_events(); void dispatch_events(); + void loop_speed_distance_task(); // timer instance used for loggint task time and used by ResetDevice std::chrono::microseconds _resetTime = std::chrono::microseconds::zero(); @@ -130,12 +135,19 @@ class BikeSystem { EventQueue _isrEventQueue; EventQueue _eventQueue; + // Mail + Mail _mailPedalDevice; + // mutex for shared resource - Mutex mutexGearSize; - Mutex mutexGear; + Mutex _mutexGearSize; + Mutex _mutexGear; + Mutex _mutexSpeed; + Mutex _mutexDistance; + Mutex _mutexSpeedometer; // Tread for isr events Thread _isrEventThread; + Thread _speedDistanceThread; }; } // namespace multi_tasking diff --git a/multi_tasking/pedal_device.cpp b/multi_tasking/pedal_device.cpp index 06ecdb5..02e3133 100644 --- a/multi_tasking/pedal_device.cpp +++ b/multi_tasking/pedal_device.cpp @@ -36,21 +36,19 @@ namespace multi_tasking { -PedalDevice::PedalDevice(Callback cbOnLeft, Callback cbOnRight) { - disco::Joystick::getInstance().setLeftCallback(callback(cbOnLeft)); - disco::Joystick::getInstance().setRightCallback(callback(cbOnRight)); -} +PedalDevice::PedalDevice(Mail* mailBox) { + disco::Joystick::getInstance().setLeftCallback(callback(this, &PedalDevice::onLeft)); + disco::Joystick::getInstance().setRightCallback( + 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; + _mailBox = mailBox; } void PedalDevice::increaseRotationSpeed() { uint32_t currentStep = core_util_atomic_load_u32(&_currentStep); if (currentStep > 0) { core_util_atomic_decr_u32(&_currentStep, 1); + sendMail(--currentStep); } } @@ -58,6 +56,7 @@ void PedalDevice::decreaseRotationSpeed() { uint32_t currentStep = core_util_atomic_load_u32(&_currentStep); if (currentStep < bike_computer::kNbrOfSteps) { core_util_atomic_incr_u32(&_currentStep, 1); + sendMail(++currentStep); } } @@ -65,4 +64,19 @@ void PedalDevice::onLeft() { decreaseRotationSpeed(); } void PedalDevice::onRight() { increaseRotationSpeed(); } +void PedalDevice::sendMail(uint32_t data) { + uint32_t* currentStep = _mailBox->try_alloc(); + if (currentStep != nullptr) { + *currentStep = data; + (*_mailBox).put(currentStep); + } +} + +// mbed_build_and_runstatic methods + +std::chrono::milliseconds PedalDevice::getCurrentRotationTime(uint32_t step) { + return bike_computer::kMinPedalRotationTime + + step * bike_computer::kDeltaPedalRotationTime; +} + } // namespace multi_tasking diff --git a/multi_tasking/pedal_device.hpp b/multi_tasking/pedal_device.hpp index 8787548..19cb3fb 100644 --- a/multi_tasking/pedal_device.hpp +++ b/multi_tasking/pedal_device.hpp @@ -33,22 +33,30 @@ namespace multi_tasking { class PedalDevice { public: - PedalDevice(Callback cbOnLeft, - Callback cbOnRight); // NOLINT(runtime/references) + explicit PedalDevice(Mail* mailBox); // NOLINT(runtime/references) // make the class non copyable PedalDevice(PedalDevice&) = delete; PedalDevice& operator=(PedalDevice&) = delete; // method called for updating the bike system - std::chrono::milliseconds getCurrentRotationTime(); + static std::chrono::milliseconds getCurrentRotationTime(uint32_t step); private: + // private methods + void onLeft(); + void onRight(); + void increaseRotationSpeed(); + void decreaseRotationSpeed(); + + void sendMail(uint32_t data); // data members volatile uint32_t _currentStep = static_cast( (bike_computer::kInitialPedalRotationTime - bike_computer::kMinPedalRotationTime) .count() / bike_computer::kDeltaPedalRotationTime.count()); + + Mail* _mailBox; }; } // namespace multi_tasking From 62fd302d84251745871a7fbf586fa29df5cb9b2c Mon Sep 17 00:00:00 2001 From: fastium Date: Fri, 3 Jan 2025 20:20:44 +0100 Subject: [PATCH 14/28] FIX kMinGearSize value --- common/constants.hpp | 11 +++++------ common/speedometer.hpp | 6 ++---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/common/constants.hpp b/common/constants.hpp index 859a210..850af8e 100644 --- a/common/constants.hpp +++ b/common/constants.hpp @@ -36,7 +36,7 @@ static constexpr uint8_t kMaxGear = 9; // smallest gear (= 1) corresponds to a gear size of 20 // when the gear increases, the gear size descreases static constexpr uint8_t kMaxGearSize = 20; -static constexpr uint8_t kMinGearSize = kMaxGearSize - kMaxGear; +static constexpr uint8_t kMinGearSize = kMaxGearSize - kMinGear; // pedal related constants // When compiling and linking with gcc, we get a link error when using static @@ -52,9 +52,8 @@ static constexpr std::chrono::milliseconds kMaxPedalRotationTime = 1500ms; static constexpr std::chrono::milliseconds kDeltaPedalRotationTime = 25ms; static constexpr uint32_t kNbrOfSteps = static_cast( - ( - bike_computer::kMaxPedalRotationTime - bike_computer::kMinPedalRotationTime - ).count() / bike_computer::kDeltaPedalRotationTime.count() -); + (bike_computer::kMaxPedalRotationTime - bike_computer::kMinPedalRotationTime) + .count() / + bike_computer::kDeltaPedalRotationTime.count()); -} // namespace bike_computer \ No newline at end of file +} // namespace bike_computer diff --git a/common/speedometer.hpp b/common/speedometer.hpp index bbc1e6b..d821093 100644 --- a/common/speedometer.hpp +++ b/common/speedometer.hpp @@ -79,13 +79,11 @@ class Speedometer { float _currentSpeed = 0.0f; Mutex _totalDistanceMutex; float _totalDistance = 0.0f; - uint8_t _gearSize = 1; - - Thread _thread; + uint8_t _gearSize = bike_computer::kMinGearSize; #if defined(MBED_TEST_MODE) mbed::Callback _cb; #endif }; -} // namespace bike_computer \ No newline at end of file +} // namespace bike_computer From 4fb09c690c32a6e55fefda17c9fbcd175f101efa Mon Sep 17 00:00:00 2001 From: fastium Date: Fri, 3 Jan 2025 20:22:23 +0100 Subject: [PATCH 15/28] ADD mail box for gear device --- multi_tasking/bike_system.cpp | 112 +++++++++++++++------------------- multi_tasking/bike_system.hpp | 19 +++--- multi_tasking/gear_device.cpp | 31 +++++++++- multi_tasking/gear_device.hpp | 13 +++- 4 files changed, 99 insertions(+), 76 deletions(-) diff --git a/multi_tasking/bike_system.cpp b/multi_tasking/bike_system.cpp index 3a10e41..078e4dc 100644 --- a/multi_tasking/bike_system.cpp +++ b/multi_tasking/bike_system.cpp @@ -62,15 +62,16 @@ static constexpr std::chrono::milliseconds kCPUTaskDelay = 0 static constexpr std::chrono::milliseconds kCPUTaskComputationTime = 0ms; BikeSystem::BikeSystem() - : _gearDevice(callback(this, &BikeSystem::onGearUp), - callback(this, &BikeSystem::onGearDown)), + : _gearDevice(&_mailGearDevice), _pedalDevice(&_mailPedalDevice), _resetDevice(callback(this, &BikeSystem::onReset)), _speedometer(_timer), _cpuLogger(_timer), _isrEventThread(osPriorityAboveNormal, OS_STACK_SIZE, nullptr, "ISR_Event"), _speedDistanceThread( - osPriorityNormal, OS_STACK_SIZE, nullptr, "Speed_distance_Task") {} + osPriorityNormal, OS_STACK_SIZE, nullptr, "Speed_distance_Task"), + _gearTaskThread(osPriorityNormal, OS_STACK_SIZE, nullptr, "Gear_Task") {} + #if defined(MBED_TEST_MODE) const advembsof::TaskLogger& BikeSystem::getTaskLogger() { return _taskLogger; } #endif // defined(MBED_TEST_MODE) @@ -96,16 +97,8 @@ void BikeSystem::init() { } void BikeSystem::start() { - tr_info("Starting Super-Loop with event handling"); - init(); - Event speedDistanceEvent(&_eventQueue, - callback(this, &BikeSystem::speedDistanceTask)); - speedDistanceEvent.delay(kSpeedDistanceTaskDelay); - speedDistanceEvent.period(kSpeedDistanceTaskPeriod); - speedDistanceEvent.post(); - Event display1Event(&_eventQueue, callback(this, &BikeSystem::displayTask1)); display1Event.delay(kDisplayTask1Delay); display1Event.period(kDisplayTask1Period); @@ -134,7 +127,12 @@ void BikeSystem::start() { tr_error("Thread %s started with status %d", _isrEventThread.get_name(), status); } - // dispathc the main queue in the main thread + status = _gearTaskThread.start(callback(this, &BikeSystem::loop_gear_task)); + if (status != osOK) { + tr_error("Thread %s started with status %d", _gearTaskThread.get_name(), status); + } + + // dispatch the main queue in the main thread dispatch_events(); } @@ -146,19 +144,6 @@ void BikeSystem::onReset() { resetEvent.post(); } -void BikeSystem::onGearUp() { - _onGearUpTime = _timer.elapsed_time(); - Event gearUpEvent(&_isrEventQueue, callback(this, &BikeSystem::gearUpTask)); - gearUpEvent.post(); -} - -void BikeSystem::onGearDown() { - _onGearDownTime = _timer.elapsed_time(); - Event gearDownEvent(&_isrEventQueue, - callback(this, &BikeSystem::gearDownTask)); - gearDownEvent.post(); -} - // ISR thread functions void BikeSystem::resetTask() { @@ -166,7 +151,12 @@ void BikeSystem::resetTask() { std::chrono::microseconds responseTime = _timer.elapsed_time() - _resetTime; tr_info("Reset task: response time is %" PRIu64 " usecs", responseTime.count()); + + // ENTER CRITICAL SECTION + _mutexSpeedometer.lock(); _speedometer.reset(); + _mutexSpeedometer.unlock(); + // END CRITICAL SECTION _taskLogger.logPeriodAndExecutionTime( _timer, advembsof::TaskLogger::kResetTaskIndex, taskStartTime); @@ -196,6 +186,7 @@ void BikeSystem::speedDistanceTask() { // ENTER CRITICAL SECTION _mutexSpeedometer.lock(); + tr_info("%d", getCurrentGearSize()); _speedometer.setGearSize(getCurrentGearSize()); _mutexSpeed.lock(); _currentSpeed = _speedometer.getCurrentSpeed(); @@ -210,47 +201,33 @@ void BikeSystem::speedDistanceTask() { _timer, advembsof::TaskLogger::kSpeedTaskIndex, taskStartTime); } +/* Gear thread functions */ +void BikeSystem::gearTask() { + auto taskStartTime = _timer.elapsed_time(); + + uint8_t* currentGear = _mailGearDevice.try_get(); + + if (currentGear != nullptr) { + // ENTER CRITICAL SECTION + _mutexGear.lock(); + _currentGear = *currentGear; + _mutexGear.unlock(); + _mutexGearSize.lock(); + _currentGearSize = bike_computer::kMaxGearSize - *currentGear; + _mutexGearSize.unlock(); + // END CRITICAL SECTION + + osStatus status = _mailGearDevice.free(currentGear); + if (status != osOK) { + tr_error("free current step in the speed distance tasks doesn't work !"); + } + } + _taskLogger.logPeriodAndExecutionTime( + _timer, advembsof::TaskLogger::kSpeedTaskIndex, taskStartTime); +} + /* Main thread functions */ -void BikeSystem::gearUpTask() { - auto taskStartTime = _timer.elapsed_time(); - std::chrono::microseconds responseTime = _timer.elapsed_time() - _onGearUpTime; - tr_info("Gear up task: response time is %" PRIu64 " usecs", responseTime.count()); - - // ENTER CRITICAL SECTION - _mutexGear.lock(); - if (_currentGear < bike_computer::kMaxGear) { - _currentGear++; - _mutexGearSize.lock(); - _currentGearSize = bike_computer::kMaxGearSize - _currentGear; - _mutexGearSize.unlock(); - } - _mutexGear.unlock(); - // END CRITICAL SECTION - - _taskLogger.logPeriodAndExecutionTime( - _timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime); -} -void BikeSystem::gearDownTask() { - auto taskStartTime = _timer.elapsed_time(); - std::chrono::microseconds responseTime = _timer.elapsed_time() - _onGearDownTime; - tr_info("Gear down task: response time is %" PRIu64 " usecs", responseTime.count()); - - // ENTER CRITICAL SECTION - _mutexGear.lock(); - if (_currentGear > bike_computer::kMinGear) { - _currentGear--; - _mutexGearSize.lock(); - _currentGearSize = bike_computer::kMaxGearSize - _currentGear; - _mutexGearSize.unlock(); - } - _mutexGear.unlock(); - // END CRITICAL SECTION - - _taskLogger.logPeriodAndExecutionTime( - _timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime); -} - void BikeSystem::temperatureTask() { auto taskStartTime = _timer.elapsed_time(); @@ -313,6 +290,13 @@ void BikeSystem::loop_speed_distance_task() { } } +void BikeSystem::loop_gear_task() { + tr_info("Start loop gear calculation"); + while (true) { + gearTask(); + } +} + uint8_t BikeSystem::getCurrentGear() { uint8_t currentGear; diff --git a/multi_tasking/bike_system.hpp b/multi_tasking/bike_system.hpp index 7031b10..507f1ba 100644 --- a/multi_tasking/bike_system.hpp +++ b/multi_tasking/bike_system.hpp @@ -63,6 +63,7 @@ class BikeSystem { private: // private methods void init(); + // Main Thread void temperatureTask(); void displayTask1(); @@ -71,24 +72,26 @@ class BikeSystem { // ISR Thread void onReset(); - void onGearUp(); - void onGearDown(); - void gearUpTask(); - void gearDownTask(); - void speedDistanceTask(); void resetTask(); - // + // gear Thread + void gearTask(); + + // Speed / Distance Thread + void speedDistanceTask(); + + // GETTER - SETTER uint8_t getCurrentGear(); uint8_t getCurrentGearSize(); uint32_t getCurrentSpeed(); uint32_t getCurrentDistance(); - void setCurrentGear(uint8_t gear); + // Thread functions void dispatch_isr_events(); void dispatch_events(); void loop_speed_distance_task(); + void loop_gear_task(); // timer instance used for loggint task time and used by ResetDevice std::chrono::microseconds _resetTime = std::chrono::microseconds::zero(); @@ -137,6 +140,7 @@ class BikeSystem { // Mail Mail _mailPedalDevice; + Mail _mailGearDevice; // mutex for shared resource Mutex _mutexGearSize; @@ -148,6 +152,7 @@ class BikeSystem { // Tread for isr events Thread _isrEventThread; Thread _speedDistanceThread; + Thread _gearTaskThread; }; } // namespace multi_tasking diff --git a/multi_tasking/gear_device.cpp b/multi_tasking/gear_device.cpp index 33acd54..c106e30 100644 --- a/multi_tasking/gear_device.cpp +++ b/multi_tasking/gear_device.cpp @@ -30,6 +30,7 @@ #include #include "joystick.hpp" +#include "mbed_atomic.h" #include "mbed_trace.h" #if MBED_CONF_MBED_TRACE_ENABLE @@ -38,9 +39,33 @@ namespace multi_tasking { -GearDevice::GearDevice(Callback cbOnUp, Callback cbOnDown) { - disco::Joystick::getInstance().setUpCallback(callback(cbOnUp)); - disco::Joystick::getInstance().setDownCallback(callback(cbOnDown)); +GearDevice::GearDevice(Mail* mailBox) { + disco::Joystick::getInstance().setUpCallback(callback(this, &GearDevice::onUp)); + disco::Joystick::getInstance().setDownCallback(callback(this, &GearDevice::onDown)); + + _mailBox = mailBox; +} + +void GearDevice::onUp() { + if (_currentGear < bike_computer::kMaxGear) { + core_util_atomic_incr_u8(&_currentGear, 1); + sendMail(core_util_atomic_load_u8(&_currentGear)); + } +} + +void GearDevice::onDown() { + if (_currentGear > bike_computer::kMinGear) { + core_util_atomic_decr_u8(&_currentGear, 1); + sendMail(core_util_atomic_load_u8(&_currentGear)); + } +} + +void GearDevice::sendMail(uint32_t data) { + uint8_t* currentGear = _mailBox->try_alloc(); + if (currentGear != nullptr) { + *currentGear = data; + _mailBox->put(currentGear); + } } } // namespace multi_tasking diff --git a/multi_tasking/gear_device.hpp b/multi_tasking/gear_device.hpp index 4ff6cb1..334be15 100644 --- a/multi_tasking/gear_device.hpp +++ b/multi_tasking/gear_device.hpp @@ -26,20 +26,29 @@ #pragma once +#include "common/constants.hpp" #include "mbed.h" namespace multi_tasking { class GearDevice { public: - GearDevice(Callback cbOnUp, - Callback cbOnDown); // NOLINT(runtime/references) + explicit GearDevice(Mail* mailBox); // NOLINT(runtime/references) // make the class non copyable GearDevice(GearDevice&) = delete; GearDevice& operator=(GearDevice&) = delete; // method called for updating the bike system + void onUp(); + void onDown(); + + void sendMail(uint32_t data); + + private: + // data members + volatile uint8_t _currentGear = bike_computer::kMinGear; + Mail* _mailBox; }; } // namespace multi_tasking From b9c129e8723e90145494fcd2a7273843e91e2998 Mon Sep 17 00:00:00 2001 From: fastium Date: Sat, 4 Jan 2025 15:51:51 +0100 Subject: [PATCH 16/28] ADD measure time call --- multi_tasking/bike_system.cpp | 105 ++++++++++++++++++--------------- multi_tasking/bike_system.hpp | 48 +++++++-------- multi_tasking/gear_device.cpp | 19 +++--- multi_tasking/gear_device.hpp | 11 +++- multi_tasking/pedal_device.cpp | 23 ++++---- multi_tasking/pedal_device.hpp | 11 +++- 6 files changed, 125 insertions(+), 92 deletions(-) diff --git a/multi_tasking/bike_system.cpp b/multi_tasking/bike_system.cpp index 078e4dc..037b0b7 100644 --- a/multi_tasking/bike_system.cpp +++ b/multi_tasking/bike_system.cpp @@ -62,15 +62,28 @@ static constexpr std::chrono::milliseconds kCPUTaskDelay = 0 static constexpr std::chrono::milliseconds kCPUTaskComputationTime = 0ms; BikeSystem::BikeSystem() - : _gearDevice(&_mailGearDevice), - _pedalDevice(&_mailPedalDevice), - _resetDevice(callback(this, &BikeSystem::onReset)), - _speedometer(_timer), - _cpuLogger(_timer), + : _timer(), + _isrEventQueue(), + _eventQueue(), + _mailPedalDevice(), + _mailGearDevice(), + _mutexGearSize(), + _mutexGear(), + _mutexSpeed(), + _mutexDistance(), + _mutexSpeedometer(), _isrEventThread(osPriorityAboveNormal, OS_STACK_SIZE, nullptr, "ISR_Event"), _speedDistanceThread( osPriorityNormal, OS_STACK_SIZE, nullptr, "Speed_distance_Task"), - _gearTaskThread(osPriorityNormal, OS_STACK_SIZE, nullptr, "Gear_Task") {} + _gearTaskThread(osPriorityNormal, OS_STACK_SIZE, nullptr, "Gear_Task"), + _gearDevice(&_mailGearDevice, _timer), + _pedalDevice(&_mailPedalDevice, _timer), + _resetDevice(callback(this, &BikeSystem::onReset)), + _displayDevice(), + _speedometer(_timer), + _sensorDevice(), + _taskLogger(), + _cpuLogger(_timer) {} #if defined(MBED_TEST_MODE) const advembsof::TaskLogger& BikeSystem::getTaskLogger() { return _taskLogger; } @@ -99,21 +112,16 @@ void BikeSystem::init() { void BikeSystem::start() { init(); - Event display1Event(&_eventQueue, callback(this, &BikeSystem::displayTask1)); - display1Event.delay(kDisplayTask1Delay); - display1Event.period(kDisplayTask1Period); - display1Event.post(); - Event temperatureEvent(&_eventQueue, callback(this, &BikeSystem::temperatureTask)); temperatureEvent.delay(kTemperatureTaskDelay); temperatureEvent.period(kTemperatureTaskPeriod); temperatureEvent.post(); - Event display2Event(&_eventQueue, callback(this, &BikeSystem::displayTask2)); - display2Event.delay(kDisplayTask2Delay); - display2Event.period(kDisplayTask2Period); - display2Event.post(); + Event displayEvent(&_eventQueue, callback(this, &BikeSystem::displayTask)); + displayEvent.delay(kDisplayTask1Delay); + displayEvent.period(kDisplayTask1Period); + displayEvent.post(); osStatus status = _isrEventThread.start(callback(this, &BikeSystem::dispatch_isr_events)); @@ -132,6 +140,13 @@ void BikeSystem::start() { tr_error("Thread %s started with status %d", _gearTaskThread.get_name(), status); } +#if !defined(MBED_TEST_MODE) + Event cpuEvent(&_eventQueue, callback(this, &BikeSystem::cpuTask)); + cpuEvent.delay(kCPUTaskDelay); + cpuEvent.period(kCPUTaskPeriod); + cpuEvent.post(); +#endif + // dispatch the main queue in the main thread dispatch_events(); } @@ -167,26 +182,30 @@ void BikeSystem::resetTask() { void BikeSystem::speedDistanceTask() { auto taskStartTime = _timer.elapsed_time(); - uint32_t* currentStep = _mailPedalDevice.try_get(); + pedalMail_t* currentStep = _mailPedalDevice.try_get(); if (currentStep != nullptr) { - const auto pedalRotationTime = PedalDevice::getCurrentRotationTime(*currentStep); - - osStatus status = _mailPedalDevice.free(currentStep); - if (status != osOK) { - tr_error("free current step in the speed distance tasks doesn't work !"); - } + const auto pedalRotationTime = + PedalDevice::getCurrentRotationTime(currentStep->step); // ENTER CRITICAL SECTION _mutexSpeedometer.lock(); _speedometer.setCurrentRotationTime(pedalRotationTime); _mutexSpeedometer.unlock(); // END CRITICAL SECTION + + std::chrono::microseconds responseTime = + _timer.elapsed_time() - currentStep->callTime; + tr_info("Reset task: response time is %" PRIu64 " usecs", responseTime.count()); + + osStatus status = _mailPedalDevice.free(currentStep); + if (status != osOK) { + tr_error("free current step in the speed distance tasks doesn't work !"); + } } // ENTER CRITICAL SECTION _mutexSpeedometer.lock(); - tr_info("%d", getCurrentGearSize()); _speedometer.setGearSize(getCurrentGearSize()); _mutexSpeed.lock(); _currentSpeed = _speedometer.getCurrentSpeed(); @@ -205,21 +224,25 @@ void BikeSystem::speedDistanceTask() { void BikeSystem::gearTask() { auto taskStartTime = _timer.elapsed_time(); - uint8_t* currentGear = _mailGearDevice.try_get(); + gearMail_t* currentGear = _mailGearDevice.try_get(); if (currentGear != nullptr) { // ENTER CRITICAL SECTION _mutexGear.lock(); - _currentGear = *currentGear; + _currentGear = currentGear->gear; _mutexGear.unlock(); _mutexGearSize.lock(); - _currentGearSize = bike_computer::kMaxGearSize - *currentGear; + _currentGearSize = bike_computer::kMaxGearSize - currentGear->gear; _mutexGearSize.unlock(); // END CRITICAL SECTION + std::chrono::microseconds responseTime = + _timer.elapsed_time() - currentGear->callTime; + tr_info("Reset task: response time is %" PRIu64 " usecs", responseTime.count()); + osStatus status = _mailGearDevice.free(currentGear); if (status != osOK) { - tr_error("free current step in the speed distance tasks doesn't work !"); + tr_error("free current gear in the gear tasks doesn't work !"); } } _taskLogger.logPeriodAndExecutionTime( @@ -241,7 +264,7 @@ void BikeSystem::temperatureTask() { _timer, advembsof::TaskLogger::kTemperatureTaskIndex, taskStartTime); } -void BikeSystem::displayTask1() { +void BikeSystem::displayTask() { auto taskStartTime = _timer.elapsed_time(); // ENTER CRITICAL SECTION @@ -250,25 +273,15 @@ void BikeSystem::displayTask1() { _displayDevice.displayDistance(getCurrentDistance()); // END CRITICAL SECTION - ThisThread::sleep_for(std::chrono::duration_cast( - kDisplayTask1ComputationTime - (_timer.elapsed_time() - taskStartTime))); + _displayDevice.displayTemperature(_currentTemperature); + + // ThisThread::sleep_for(std::chrono::duration_cast(kDisplayTask1ComputationTime + // - (_timer.elapsed_time() - taskStartTime))); _taskLogger.logPeriodAndExecutionTime( _timer, advembsof::TaskLogger::kDisplayTask1Index, taskStartTime); } -void BikeSystem::displayTask2() { - auto taskStartTime = _timer.elapsed_time(); - - _displayDevice.displayTemperature(_currentTemperature); - - ThisThread::sleep_for(std::chrono::duration_cast( - kDisplayTask2ComputationTime - (_timer.elapsed_time() - taskStartTime))); - - _taskLogger.logPeriodAndExecutionTime( - _timer, advembsof::TaskLogger::kDisplayTask2Index, taskStartTime); -} - void BikeSystem::cpuTask() { _cpuLogger.printStats(); } void BikeSystem::dispatch_isr_events() { @@ -321,8 +334,8 @@ uint8_t BikeSystem::getCurrentGearSize() { return currentGearSize; } -uint32_t BikeSystem::getCurrentSpeed() { - uint32_t currentSpeed; +float BikeSystem::getCurrentSpeed() { + float currentSpeed; // ENTER CRITICAL SECTION _mutexSpeed.lock(); @@ -333,8 +346,8 @@ uint32_t BikeSystem::getCurrentSpeed() { return currentSpeed; } -uint32_t BikeSystem::getCurrentDistance() { - uint32_t currentDistance; +float BikeSystem::getCurrentDistance() { + float currentDistance; // ENTER CRITICAL SECTION _mutexDistance.lock(); diff --git a/multi_tasking/bike_system.hpp b/multi_tasking/bike_system.hpp index 507f1ba..001a224 100644 --- a/multi_tasking/bike_system.hpp +++ b/multi_tasking/bike_system.hpp @@ -66,8 +66,7 @@ class BikeSystem { // Main Thread void temperatureTask(); - void displayTask1(); - void displayTask2(); + void displayTask(); void cpuTask(); // ISR Thread @@ -83,8 +82,8 @@ class BikeSystem { // GETTER - SETTER uint8_t getCurrentGear(); uint8_t getCurrentGearSize(); - uint32_t getCurrentSpeed(); - uint32_t getCurrentDistance(); + float getCurrentSpeed(); + float getCurrentDistance(); void setCurrentGear(uint8_t gear); // Thread functions @@ -99,6 +98,27 @@ class BikeSystem { std::chrono::microseconds _onGearDownTime = std::chrono::microseconds::zero(); Timer _timer; + + // Event queues + EventQueue _isrEventQueue; + EventQueue _eventQueue; + + // Mail + Mail _mailPedalDevice; + Mail _mailGearDevice; + + // mutex for shared resource + Mutex _mutexGearSize; + Mutex _mutexGear; + Mutex _mutexSpeed; + Mutex _mutexDistance; + Mutex _mutexSpeedometer; + + // Tread for isr events + Thread _isrEventThread; + Thread _speedDistanceThread; + Thread _gearTaskThread; + // data member that represents the device for manipulating the gear GearDevice _gearDevice; @@ -133,26 +153,6 @@ class BikeSystem { // cpu logger to measure cpu usage advembsof::CPULogger _cpuLogger; - - // Event queues - EventQueue _isrEventQueue; - EventQueue _eventQueue; - - // Mail - Mail _mailPedalDevice; - Mail _mailGearDevice; - - // mutex for shared resource - Mutex _mutexGearSize; - Mutex _mutexGear; - Mutex _mutexSpeed; - Mutex _mutexDistance; - Mutex _mutexSpeedometer; - - // Tread for isr events - Thread _isrEventThread; - Thread _speedDistanceThread; - Thread _gearTaskThread; }; } // namespace multi_tasking diff --git a/multi_tasking/gear_device.cpp b/multi_tasking/gear_device.cpp index c106e30..e45a69c 100644 --- a/multi_tasking/gear_device.cpp +++ b/multi_tasking/gear_device.cpp @@ -26,8 +26,9 @@ #include "gear_device.hpp" +#include "bike_system.hpp" + // from disco_h747i/wrappers -#include #include "joystick.hpp" #include "mbed_atomic.h" @@ -39,11 +40,10 @@ namespace multi_tasking { -GearDevice::GearDevice(Mail* mailBox) { +GearDevice::GearDevice(Mail* mailBox, Timer& timer) + : _mailBox(mailBox), _timer(timer) { disco::Joystick::getInstance().setUpCallback(callback(this, &GearDevice::onUp)); disco::Joystick::getInstance().setDownCallback(callback(this, &GearDevice::onDown)); - - _mailBox = mailBox; } void GearDevice::onUp() { @@ -61,10 +61,13 @@ void GearDevice::onDown() { } void GearDevice::sendMail(uint32_t data) { - uint8_t* currentGear = _mailBox->try_alloc(); - if (currentGear != nullptr) { - *currentGear = data; - _mailBox->put(currentGear); + if (_mailBox != nullptr) { + gearMail_t* currentGear = _mailBox->try_alloc(); + if (currentGear != nullptr) { + currentGear->gear = data; + currentGear->callTime = _timer.elapsed_time(); + _mailBox->put(currentGear); + } } } diff --git a/multi_tasking/gear_device.hpp b/multi_tasking/gear_device.hpp index 334be15..5ec23c5 100644 --- a/multi_tasking/gear_device.hpp +++ b/multi_tasking/gear_device.hpp @@ -31,9 +31,15 @@ namespace multi_tasking { +typedef struct gearMail { + uint8_t gear; + std::chrono::microseconds callTime; +} gearMail_t; + class GearDevice { public: - explicit GearDevice(Mail* mailBox); // NOLINT(runtime/references) + explicit GearDevice(Mail* mailBox, + Timer& timer); // NOLINT(runtime/references) // make the class non copyable GearDevice(GearDevice&) = delete; @@ -48,7 +54,8 @@ class GearDevice { private: // data members volatile uint8_t _currentGear = bike_computer::kMinGear; - Mail* _mailBox; + Mail* _mailBox; + Timer& _timer; }; } // namespace multi_tasking diff --git a/multi_tasking/pedal_device.cpp b/multi_tasking/pedal_device.cpp index 02e3133..29d600f 100644 --- a/multi_tasking/pedal_device.cpp +++ b/multi_tasking/pedal_device.cpp @@ -27,6 +27,7 @@ // from disco_h747i/wrappers #include +#include "bike_system.hpp" #include "joystick.hpp" #include "mbed_trace.h" @@ -36,19 +37,18 @@ namespace multi_tasking { -PedalDevice::PedalDevice(Mail* mailBox) { +PedalDevice::PedalDevice(Mail* mailBox, Timer& timer) + : _mailBox(mailBox), _timer(timer) { disco::Joystick::getInstance().setLeftCallback(callback(this, &PedalDevice::onLeft)); disco::Joystick::getInstance().setRightCallback( callback(this, &PedalDevice::onRight)); - - _mailBox = mailBox; } void PedalDevice::increaseRotationSpeed() { uint32_t currentStep = core_util_atomic_load_u32(&_currentStep); if (currentStep > 0) { core_util_atomic_decr_u32(&_currentStep, 1); - sendMail(--currentStep); + sendMail(core_util_atomic_load_u32(&_currentStep)); } } @@ -56,7 +56,7 @@ void PedalDevice::decreaseRotationSpeed() { uint32_t currentStep = core_util_atomic_load_u32(&_currentStep); if (currentStep < bike_computer::kNbrOfSteps) { core_util_atomic_incr_u32(&_currentStep, 1); - sendMail(++currentStep); + sendMail(core_util_atomic_load_u32(&_currentStep)); } } @@ -65,14 +65,17 @@ void PedalDevice::onLeft() { decreaseRotationSpeed(); } void PedalDevice::onRight() { increaseRotationSpeed(); } void PedalDevice::sendMail(uint32_t data) { - uint32_t* currentStep = _mailBox->try_alloc(); - if (currentStep != nullptr) { - *currentStep = data; - (*_mailBox).put(currentStep); + if (_mailBox != nullptr) { + pedalMail_t* currentStep = _mailBox->try_alloc(); + if (currentStep != nullptr) { + currentStep->step = data; + currentStep->callTime = _timer.elapsed_time(); + _mailBox->put(currentStep); + } } } -// mbed_build_and_runstatic methods +// static methods std::chrono::milliseconds PedalDevice::getCurrentRotationTime(uint32_t step) { return bike_computer::kMinPedalRotationTime + diff --git a/multi_tasking/pedal_device.hpp b/multi_tasking/pedal_device.hpp index 19cb3fb..c6e014d 100644 --- a/multi_tasking/pedal_device.hpp +++ b/multi_tasking/pedal_device.hpp @@ -31,9 +31,15 @@ namespace multi_tasking { +typedef struct pedalMail { + uint8_t step; + std::chrono::microseconds callTime; +} pedalMail_t; + class PedalDevice { public: - explicit PedalDevice(Mail* mailBox); // NOLINT(runtime/references) + explicit PedalDevice(Mail* mailBox, // NOLINT (runtime/references) + Timer& timer); // NOLINT (runtime/references) // make the class non copyable PedalDevice(PedalDevice&) = delete; @@ -56,7 +62,8 @@ class PedalDevice { .count() / bike_computer::kDeltaPedalRotationTime.count()); - Mail* _mailBox; + Mail* _mailBox; + Timer& _timer; }; } // namespace multi_tasking From afa1fb8aef9c3cda3a6a4371cfd9d53c3a31db47 Mon Sep 17 00:00:00 2001 From: fastium Date: Sat, 4 Jan 2025 15:53:13 +0100 Subject: [PATCH 17/28] FIX clang format --- common/speedometer.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/common/speedometer.cpp b/common/speedometer.cpp index a24d685..4296b10 100644 --- a/common/speedometer.cpp +++ b/common/speedometer.cpp @@ -24,11 +24,11 @@ #include "speedometer.hpp" -#include "static_scheduling/gear_device.hpp" - #include #include +#include "static_scheduling/gear_device.hpp" + // from disco_h747i/wrappers #include "joystick.hpp" #include "mbed_trace.h" @@ -108,10 +108,14 @@ void Speedometer::computeSpeed() { // ~= 560 m / min = 33.6 km/h // TODO : done - //Distance run with one pedal turn = tray size / rear gear size * circumference of the wheel + // Distance run with one pedal turn = tray size / rear gear size * circumference of + // the wheel constexpr float ms_in_hour = static_cast(3600 * 1000); - float pedal_rotation_per_hour = ms_in_hour / std::chrono::duration_cast(_pedalRotationTime).count(); - float gear_ratio = static_cast(kTraySize) / static_cast(this->_gearSize); + float pedal_rotation_per_hour = + ms_in_hour / + std::chrono::duration_cast(_pedalRotationTime).count(); + float gear_ratio = + static_cast(kTraySize) / static_cast(this->_gearSize); float wheel_dist_km = static_cast(this->kWheelCircumference) / 1000.0; this->_currentSpeed = gear_ratio * wheel_dist_km * pedal_rotation_per_hour; } @@ -129,10 +133,10 @@ void Speedometer::computeDistance() { Speedometer::computeSpeed(); // compute distance - const std::chrono::microseconds timeNow = _timer.elapsed_time(); + const std::chrono::microseconds timeNow = _timer.elapsed_time(); const std::chrono::microseconds timeDiff = timeNow - _lastTime; - constexpr float ms_in_hour = static_cast(3600 * 1000); - float traveled_dist = _currentSpeed * timeDiff.count() / (ms_in_hour*1000.0/*μs*/); + constexpr float ms_in_hour = static_cast(3600 * 1000); + float traveled_dist = _currentSpeed * timeDiff.count() / (ms_in_hour * 1000.0 /*μs*/); this->_totalDistanceMutex.lock(); this->_totalDistance += traveled_dist; From 3a3d27f93eac77b94791786edc6f70a9d0a1cbc8 Mon Sep 17 00:00:00 2001 From: fastium Date: Sat, 4 Jan 2025 15:54:43 +0100 Subject: [PATCH 18/28] ADD common/ in pre-commit action file --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d935e1f..50916f5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -files: ^main.cpp|^static_scheduling|^static_scheduling_with_event|^TESTS|^multi_tasking +files: ^main.cpp|^static_scheduling|^static_scheduling_with_event|^TESTS|^multi_tasking|^common repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.3.0 From 55a65946466c1448e9754aa34276e661d75f3648 Mon Sep 17 00:00:00 2001 From: fastium Date: Sat, 4 Jan 2025 16:41:02 +0100 Subject: [PATCH 19/28] ADD preparation for tests --- common/sensor_device.cpp | 42 ++++++++++++++++++++++++----------- common/sensor_device.hpp | 2 +- common/speedometer.cpp | 4 +--- common/speedometer.hpp | 1 + multi_tasking/bike_system.cpp | 12 ++++++++++ multi_tasking/bike_system.hpp | 12 +++++++++- 6 files changed, 55 insertions(+), 18 deletions(-) diff --git a/common/sensor_device.cpp b/common/sensor_device.cpp index 4aa7ef2..69d3344 100644 --- a/common/sensor_device.cpp +++ b/common/sensor_device.cpp @@ -1,21 +1,37 @@ +// 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 speedometer_device.cpp + * @author Serge Ayer + * + * @brief WheelCounterDevice implementation (static scheduling) + * + * @date 2023-08-20 + * @version 1.0.0 + ***************************************************************************/ + #include "sensor_device.hpp" namespace bike_computer { -SensorDevice::SensorDevice() : _hdc1000(I2C_SDA, I2C_SCL, STMOD_11) -{} +SensorDevice::SensorDevice() : _hdc1000(I2C_SDA, I2C_SCL, STMOD_11) {} -bool SensorDevice::init() { - return this->_hdc1000.probe(); -} +bool SensorDevice::init() { return this->_hdc1000.probe(); } -float SensorDevice::readTemperature(void) { - return this->_hdc1000.getTemperature(); -} +float SensorDevice::readTemperature(void) { return this->_hdc1000.getTemperature(); } -float SensorDevice::readHumidity(void) { - return this->_hdc1000.getHumidity(); -} - -} // bike_computer +float SensorDevice::readHumidity(void) { return this->_hdc1000.getHumidity(); } +} // namespace bike_computer diff --git a/common/sensor_device.hpp b/common/sensor_device.hpp index d6ead2c..37bc1f1 100644 --- a/common/sensor_device.hpp +++ b/common/sensor_device.hpp @@ -46,4 +46,4 @@ class SensorDevice { advembsof::HDC1000 _hdc1000; }; -} // namespace bike_computer \ No newline at end of file +} // namespace bike_computer diff --git a/common/speedometer.cpp b/common/speedometer.cpp index 4296b10..7d05312 100644 --- a/common/speedometer.cpp +++ b/common/speedometer.cpp @@ -80,7 +80,6 @@ float Speedometer::getDistance() { } void Speedometer::reset() { - // TODO : done this->_totalDistanceMutex.lock(); this->_totalDistance = 0.0f; this->_totalDistanceMutex.unlock(); @@ -96,6 +95,7 @@ float Speedometer::getTraySize() const { return kTraySize; } std::chrono::milliseconds Speedometer::getCurrentPedalRotationTime() const { return _pedalRotationTime; } +void Speedometer::setOnResetCallback(mbed::Callback cb) { _cbOnReset = cb; } #endif // defined(MBED_TEST_MODE) @@ -107,7 +107,6 @@ void Speedometer::computeSpeed() { // = 6.99m If you ride at 80 pedal turns / min, you run a distance of 6.99 * 80 / min // ~= 560 m / min = 33.6 km/h - // TODO : done // Distance run with one pedal turn = tray size / rear gear size * circumference of // the wheel constexpr float ms_in_hour = static_cast(3600 * 1000); @@ -129,7 +128,6 @@ void Speedometer::computeDistance() { // ~= 560 m / min = 33.6 km/h. We then multiply the speed by the time for getting the // distance traveled. - // TODO : done Speedometer::computeSpeed(); // compute distance diff --git a/common/speedometer.hpp b/common/speedometer.hpp index d821093..559eafc 100644 --- a/common/speedometer.hpp +++ b/common/speedometer.hpp @@ -55,6 +55,7 @@ class Speedometer { float getTraySize() const; std::chrono::milliseconds getCurrentPedalRotationTime() const; void setOnResetCallback(mbed::Callback cb); + mbed::Callback _cbOnReset; #endif // defined(MBED_TEST_MODE) private: diff --git a/multi_tasking/bike_system.cpp b/multi_tasking/bike_system.cpp index 037b0b7..01ba9f5 100644 --- a/multi_tasking/bike_system.cpp +++ b/multi_tasking/bike_system.cpp @@ -87,6 +87,14 @@ BikeSystem::BikeSystem() #if defined(MBED_TEST_MODE) const advembsof::TaskLogger& BikeSystem::getTaskLogger() { return _taskLogger; } + +bike_computer::Speedometer& Bike_system::getSpeedometer() { + _mutexSpeedometer.lock(); + bike_computer::Speedometer& speedometer = _speedometer; + _mutexSpeedometer.unlock(); + return speedometer; +} + #endif // defined(MBED_TEST_MODE) void BikeSystem::init() { @@ -162,10 +170,12 @@ void BikeSystem::onReset() { // ISR thread functions void BikeSystem::resetTask() { +#ifndef(MBED_TEST_MODE) auto taskStartTime = _timer.elapsed_time(); std::chrono::microseconds responseTime = _timer.elapsed_time() - _resetTime; tr_info("Reset task: response time is %" PRIu64 " usecs", responseTime.count()); +#endif // ENTER CRITICAL SECTION _mutexSpeedometer.lock(); @@ -173,8 +183,10 @@ void BikeSystem::resetTask() { _mutexSpeedometer.unlock(); // END CRITICAL SECTION +#ifndef(MBED_TEST_MODE) _taskLogger.logPeriodAndExecutionTime( _timer, advembsof::TaskLogger::kResetTaskIndex, taskStartTime); +#endif } // Speed distance thread functions diff --git a/multi_tasking/bike_system.hpp b/multi_tasking/bike_system.hpp index 001a224..68d2789 100644 --- a/multi_tasking/bike_system.hpp +++ b/multi_tasking/bike_system.hpp @@ -58,6 +58,7 @@ class BikeSystem { #if defined(MBED_TEST_MODE) const advembsof::TaskLogger& getTaskLogger(); + bike_computer::Speedometer& getSpeedometer(); #endif // defined(MBED_TEST_MODE) private: @@ -69,8 +70,17 @@ class BikeSystem { void displayTask(); void cpuTask(); - // ISR Thread +// ISR Thread +#if defined(MBED_TEST_MODE) + + public: +#endif void onReset(); +#if defined(MBED_TEST_MODE) + + private: +#endif + void resetTask(); // gear Thread From 618ddaaa1b19e1aa19e45e3ee5fe6010c71d8b6d Mon Sep 17 00:00:00 2001 From: fastium Date: Mon, 6 Jan 2025 00:14:43 +0100 Subject: [PATCH 20/28] ADD test for multi-tasking --- .pre-commit-config.yaml | 2 +- TESTS/bike-computer/bike-system/main.cpp | 249 ++++++++++++++++++++++- common/speedometer.cpp | 4 + mbed_app.json | 48 +++-- multi_tasking/bike_system.cpp | 84 ++++++-- multi_tasking/bike_system.hpp | 3 + 6 files changed, 342 insertions(+), 48 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 50916f5..830e48c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,5 +22,5 @@ repos: - id: cppcheck name: cppcheck require_serial: true - entry: cppcheck --enable=all --suppress=missingInclude --suppress=missingIncludeSystem --suppress=unusedFunction --suppress=unusedStructMember --inline-suppr -i mbed-os --std=c++14 --error-exitcode=1 + entry: cppcheck --enable=all --suppress=missingInclude --suppress=missingIncludeSystem --suppress=unusedFunction --inline-suppr -i mbed-os --std=c++14 --error-exitcode=1 language: system diff --git a/TESTS/bike-computer/bike-system/main.cpp b/TESTS/bike-computer/bike-system/main.cpp index 605f74c..f566562 100644 --- a/TESTS/bike-computer/bike-system/main.cpp +++ b/TESTS/bike-computer/bike-system/main.cpp @@ -23,15 +23,23 @@ ***************************************************************************/ #include +#include +#include "gear_device.hpp" #include "greentea-client/test_env.h" #include "mbed.h" +#include "mbed_trace.h" // NOLINT +#include "multi_tasking/bike_system.hpp" #include "static_scheduling/bike_system.hpp" #include "static_scheduling_with_event/bike_system.hpp" #include "task_logger.hpp" #include "unity/unity.h" #include "utest/utest.h" +#if defined(MBED_CONF_MBED_TRACE_ENABLE) +#define TRACE_GROUP "TEST_BIKE_SYSTEM" +#endif // MBED_CONF_MBED_TRACE_ENAB + namespace utest { namespace v1 { @@ -140,6 +148,235 @@ static void test_bike_system_with_event() { } } +// test_multi_tasking_bike_system handler function +static void test_multi_tasking_bike_system() { + tr_info("test multi tasking bike system"); + + // create the BikeSystem instance + multi_tasking::BikeSystem bikeSystem; + + // run the bike system in a separate thread + Thread thread; + osStatus status = + thread.start(callback(&bikeSystem, &multi_tasking::BikeSystem::start)); + + if (status != osOK) { + tr_error("Thread bike system is not OK !"); + } + + tr_info("bike system has started"); + + // let the bike system run for 20 secs + ThisThread::sleep_for(20s); + + // check whether scheduling was correct + // Order is kGearTaskIndex, kSpeedTaskIndex, kTemperatureTaskIndex, + // kResetTaskIndex, kDisplayTask1Index, kDisplayTask2Index + // When we use event handling, we do not check the computation time + constexpr std::chrono::microseconds taskPeriods[] = { + 800000us, 400000us, 1600000us, 800000us, 1600000us, 1600000us}; + + // allow for 2 msecs offset (with EventQueue) + constexpr uint64_t kDeltaUs = 2000; + + // stop the bike system + bikeSystem.stop(); + thread.terminate(); + + tr_info("Threads have stopped"); + + TEST_ASSERT_UINT64_WITHIN( + kDeltaUs, + taskPeriods[advembsof::TaskLogger::kTemperatureTaskIndex].count(), + bikeSystem.getTaskLogger() + .getPeriod(advembsof::TaskLogger::kTemperatureTaskIndex) + .count()); + TEST_ASSERT_UINT64_WITHIN( + kDeltaUs, + taskPeriods[advembsof::TaskLogger::kDisplayTask1Index].count(), + bikeSystem.getTaskLogger() + .getPeriod(advembsof::TaskLogger::kDisplayTask1Index) + .count()); +} + +// test_reset_multi_tasking_bike_system handler function +Timer timer; +static std::chrono::microseconds resetTime = std::chrono::microseconds::zero(); +static EventFlags eventFlags; +static constexpr uint32_t kResetEventFlag = (1UL << 0); +static void resetCallback() { + resetTime = timer.elapsed_time(); + eventFlags.set(kResetEventFlag); +} + +static void test_reset_multi_tasking_bike_system() { + tr_info("test reset multi tasking bike system"); + // create the BikeSystem instance + multi_tasking::BikeSystem bikeSystem; + + // run the bike system in a separate thread + Thread thread; + osStatus status = + thread.start(callback(&bikeSystem, &multi_tasking::BikeSystem::start)); + + if (status != osOK) { + tr_error("Thread bike system is not OK !"); + } + + tr_info("Bike system has started"); + + // let the bike system run for 2 secs + ThisThread::sleep_for(2s); + + // test reset on BikeSystem + bikeSystem.getSpeedometer().setOnResetCallback(resetCallback); + + // start the timer instance + timer.start(); + + // check for reset response time + constexpr uint8_t kNbrOfResets = 10; + std::chrono::microseconds lastResponseTime = std::chrono::microseconds::zero(); + for (uint8_t i = 0; i < kNbrOfResets; i++) { + tr_info("Reset test N°%d", i); + // take time before reset + auto startTime = timer.elapsed_time(); + + // reset the BikeSystem + bikeSystem.onReset(); + + // wait for resetCallback to be called + eventFlags.wait_all(kResetEventFlag); + + // get the response time and check it + auto responseTime = resetTime - startTime; + + // cppcheck generates an internal error with 20us + constexpr std::chrono::microseconds kMaxExpectedResponseTime(20); + + tr_info("Reset task: response time is %lld usecs\n, expected : %lld", + responseTime.count(), + kMaxExpectedResponseTime.count()); + + TEST_ASSERT_TRUE(responseTime.count() <= kMaxExpectedResponseTime.count()); + + // jitter of 20us is accepted + constexpr uint64_t kDeltaUs = 3; + constexpr std::chrono::microseconds kMaxExpectedJitter(2); + if (i > 0) { + auto jitter = responseTime - lastResponseTime; + tr_info("Reset task: jitter is %lld usecs\n", std::abs(jitter.count())); + TEST_ASSERT_UINT64_WITHIN( + kDeltaUs, kMaxExpectedJitter.count(), std::abs(jitter.count())); + } + lastResponseTime = responseTime; + + // let the bike system run for 2 secs + ThisThread::sleep_for(2s); + } + + // stop the bike system + bikeSystem.stop(); + thread.terminate(); + tr_info("Threads have stopped"); + timer.stop(); +} + +Timer timerGear; +static std::chrono::microseconds gearTime = std::chrono::microseconds::zero(); +static EventFlags eventGearFlags; +static constexpr uint32_t kGearEventFlag = (1UL << 0); +constexpr uint8_t kNbrOfGear = 9; +static void onGearChange() { + gearTime = timerGear.elapsed_time(); + eventGearFlags.set(kGearEventFlag); + tr_info("Gear changed"); +} + +static void gearTest(Callback gearChange) { + // std::chrono::microseconds lastResponseTime = std::chrono::microseconds::zero(); + + for (uint8_t i = 1; i < kNbrOfGear; i++) { + tr_info("Gear test N°%d", i); + // take time before increase the gear + auto startTime = timerGear.elapsed_time(); + + // change the gear with the callback + tr_info("Change gear"); + gearChange(); + + // wait flag + eventGearFlags.wait_all(kGearEventFlag); + + // get the response time and check it + auto responseTime = gearTime - startTime; + constexpr std::chrono::microseconds kMaxExpectedResponseTime(100000); + + tr_info("Change gear task: response time is %lld usecs\n, expected : %lld", + responseTime.count(), + kMaxExpectedResponseTime.count()); + + TEST_ASSERT_TRUE(responseTime.count() <= kMaxExpectedResponseTime.count()); + + // jitter of 20us is accepted + // constexpr uint64_t kDeltaUs = 2000; + // constexpr std::chrono::microseconds kMaxExpectedJitter(4000); + // if (i > 1) { + // auto jitter = responseTime - lastResponseTime; + // tr_info("Gear task: jitter is %lld usecs\n", std::abs(jitter.count())); + // TEST_ASSERT_UINT64_WITHIN( + // kDeltaUs, kMaxExpectedJitter.count(), std::abs(jitter.count())); + // } + // lastResponseTime = responseTime; + + // let the bike system run for 2 secs + ThisThread::sleep_for(2s); + } +} + +static void test_gear_multi_tasking_bike_system() { + tr_info("test reset multi tasking bike system"); + // create the BikeSystem instance + multi_tasking::BikeSystem bikeSystem; + + // run the bike system in a separate thread + Thread thread; + osStatus status = + thread.start(callback(&bikeSystem, &multi_tasking::BikeSystem::start)); + + if (status != osOK) { + tr_error("Thread bike system is not OK !"); + } + + tr_info("Bike system has started"); + + // let the bike system run for 2 secs + ThisThread::sleep_for(2s); + + // get the gear device to call onUp and onDown functions + multi_tasking::GearDevice& gearDevice = bikeSystem.getGearDevice(); + + // set callback for response time measuring + bikeSystem.setCallbackGearChage(onGearChange); + + // start the timer instance + timerGear.start(); + + // test timing incresing the gear + tr_info("Test incresing gear"); + gearTest(callback(&gearDevice, &multi_tasking::GearDevice::onUp)); + + // test timing decreasing the gear + tr_info("Test decreasing gear"); + gearTest(callback(&gearDevice, &multi_tasking::GearDevice::onDown)); + + // stop the bike system + bikeSystem.stop(); + thread.terminate(); + tr_info("Threads have stopped"); + timerGear.stop(); +} + 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) @@ -152,7 +389,10 @@ static status_t greentea_setup(const size_t number_of_cases) { static Case cases[] = { Case("test bike system", test_bike_system), Case("test bike system with event queue", test_bike_system_event_queue), - Case("test bike system with event handling", test_bike_system_with_event), + Case("test bike system with event", test_bike_system_with_event), + Case("test multi-tasking bike system", test_multi_tasking_bike_system), + Case("test reset multi-tasking bike system", test_reset_multi_tasking_bike_system), + Case("test gear multi-tasking bike system", test_gear_multi_tasking_bike_system), }; static Specification specification(greentea_setup, cases); @@ -160,4 +400,9 @@ static Specification specification(greentea_setup, cases); }; // namespace v1 }; // namespace utest -int main() { return !utest::v1::Harness::run(utest::v1::specification); } +int main() { +#if defined(MBED_CONF_MBED_TRACE_ENABLE) + mbed_trace_init(); +#endif + return !utest::v1::Harness::run(utest::v1::specification); +} diff --git a/common/speedometer.cpp b/common/speedometer.cpp index 7d05312..0f1b413 100644 --- a/common/speedometer.cpp +++ b/common/speedometer.cpp @@ -80,6 +80,10 @@ float Speedometer::getDistance() { } void Speedometer::reset() { +#if defined(MBED_TEST_MODE) + _cbOnReset(); +#endif + this->_totalDistanceMutex.lock(); this->_totalDistance = 0.0f; this->_totalDistanceMutex.unlock(); diff --git a/mbed_app.json b/mbed_app.json index c42f542..2e6efc6 100644 --- a/mbed_app.json +++ b/mbed_app.json @@ -1,27 +1,25 @@ { - "macros": [ - "MBED_CONF_MBED_TRACE_FEA_IPV6=0" - ], - "config": { - "main-stack-size": { - "value": 4096 - } - }, - "target_overrides": { - "*": { - "mbed-trace.enable": false, - "platform.stdio-convert-newlines": true, - "platform.stdio-baud-rate": 115200, - "platform.default-serial-baud-rate": 115200, - "platform.stdio-buffered-serial": true, - "platform.all-stats-enabled": true, - "target.printf_lib":"minimal-printf", - "platform.minimal-printf-enable-floating-point": true, - "platform.minimal-printf-set-floating-point-max-decimals": 2 - }, - "DISCO_H747I": { - "mbed-trace.enable": true, - "mbed-trace.max-level": "TRACE_LEVEL_DEBUG" - } + "macros": ["MBED_CONF_MBED_TRACE_FEA_IPV6=0"], + "config": { + "main-stack-size": { + "value": 6144 } - } \ No newline at end of file + }, + "target_overrides": { + "*": { + "mbed-trace.enable": false, + "platform.stdio-convert-newlines": true, + "platform.stdio-baud-rate": 115200, + "platform.default-serial-baud-rate": 115200, + "platform.stdio-buffered-serial": true, + "platform.all-stats-enabled": true, + "target.printf_lib": "minimal-printf", + "platform.minimal-printf-enable-floating-point": true, + "platform.minimal-printf-set-floating-point-max-decimals": 2 + }, + "DISCO_H747I": { + "mbed-trace.enable": true, + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG" + } + } +} diff --git a/multi_tasking/bike_system.cpp b/multi_tasking/bike_system.cpp index 01ba9f5..98d84ee 100644 --- a/multi_tasking/bike_system.cpp +++ b/multi_tasking/bike_system.cpp @@ -27,12 +27,12 @@ #include "bike_system.hpp" #include +#include -#include "Callback.h" -#include "cmsis_os2.h" -#include "constants.hpp" +#include "cmsis_os.h" +#include "common/constants.hpp" #include "mbed_trace.h" -#include "pedal_device.hpp" + #if MBED_CONF_MBED_TRACE_ENABLE #define TRACE_GROUP "BikeSystem" #endif // MBED_CONF_MBED_TRACE_ENABLE @@ -75,7 +75,7 @@ BikeSystem::BikeSystem() _isrEventThread(osPriorityAboveNormal, OS_STACK_SIZE, nullptr, "ISR_Event"), _speedDistanceThread( osPriorityNormal, OS_STACK_SIZE, nullptr, "Speed_distance_Task"), - _gearTaskThread(osPriorityNormal, OS_STACK_SIZE, nullptr, "Gear_Task"), + _gearTaskThread(osPriorityAboveNormal, OS_STACK_SIZE, nullptr, "Gear_Task"), _gearDevice(&_mailGearDevice, _timer), _pedalDevice(&_mailPedalDevice, _timer), _resetDevice(callback(this, &BikeSystem::onReset)), @@ -88,13 +88,22 @@ BikeSystem::BikeSystem() #if defined(MBED_TEST_MODE) const advembsof::TaskLogger& BikeSystem::getTaskLogger() { return _taskLogger; } -bike_computer::Speedometer& Bike_system::getSpeedometer() { +bike_computer::Speedometer& BikeSystem::getSpeedometer() { + // ENTER CRITICAL SECTION _mutexSpeedometer.lock(); bike_computer::Speedometer& speedometer = _speedometer; _mutexSpeedometer.unlock(); + // END CRITICAL SECTION + return speedometer; } +GearDevice& BikeSystem::getGearDevice() { return _gearDevice; } + +void BikeSystem::setCallbackGearChage(Callback cbGearChange) { + _cbGearChange = cbGearChange; +} + #endif // defined(MBED_TEST_MODE) void BikeSystem::init() { @@ -104,7 +113,7 @@ void BikeSystem::init() { // initialize the lcd display disco::ReturnCode rc = _displayDevice.init(); if (rc != disco::ReturnCode::Ok) { - tr_error("Ffalseailed to initialized the lcd display: %ld", static_cast(rc)); + tr_error("Ffalseailed to initialized the lcd display: %d", static_cast(rc)); } // initialize the sensor device @@ -114,7 +123,13 @@ void BikeSystem::init() { } // enable/disable task logging - _taskLogger.enable(false); + bool runTaskLogger = false; + +#if defined(MBED_TEST_MODE) + runTaskLogger = true; +#endif + + _taskLogger.enable(runTaskLogger); } void BikeSystem::start() { @@ -134,18 +149,24 @@ void BikeSystem::start() { osStatus status = _isrEventThread.start(callback(this, &BikeSystem::dispatch_isr_events)); if (status != osOK) { - tr_error("Thread %s started with status %d", _isrEventThread.get_name(), status); + tr_error("Thread %s started with status %ld", + _isrEventThread.get_name(), + static_cast(status)); } status = _speedDistanceThread.start(callback(this, &BikeSystem::loop_speed_distance_task)); if (status != osOK) { - tr_error("Thread %s started with status %d", _isrEventThread.get_name(), status); + tr_error("Thread %s started with status %ld", + _isrEventThread.get_name(), + static_cast(status)); } status = _gearTaskThread.start(callback(this, &BikeSystem::loop_gear_task)); if (status != osOK) { - tr_error("Thread %s started with status %d", _gearTaskThread.get_name(), status); + tr_error("Thread %s started with status %ld", + _gearTaskThread.get_name(), + static_cast(status)); } #if !defined(MBED_TEST_MODE) @@ -159,6 +180,16 @@ void BikeSystem::start() { dispatch_events(); } +void BikeSystem::stop() { + osStatus status = _isrEventThread.terminate(); + status += _speedDistanceThread.terminate(); + status += _gearTaskThread.terminate(); + if (status != 0) { + tr_error("Stop thread error"); + } + tr_info("Bike system has stopped !"); +} + /* Callback from isr */ void BikeSystem::onReset() { @@ -170,20 +201,19 @@ void BikeSystem::onReset() { // ISR thread functions void BikeSystem::resetTask() { -#ifndef(MBED_TEST_MODE) +#if !defined(MBED_TEST_MODE) auto taskStartTime = _timer.elapsed_time(); std::chrono::microseconds responseTime = _timer.elapsed_time() - _resetTime; tr_info("Reset task: response time is %" PRIu64 " usecs", responseTime.count()); #endif - // ENTER CRITICAL SECTION _mutexSpeedometer.lock(); _speedometer.reset(); _mutexSpeedometer.unlock(); // END CRITICAL SECTION -#ifndef(MBED_TEST_MODE) +#if !defined(MBED_TEST_MODE) _taskLogger.logPeriodAndExecutionTime( _timer, advembsof::TaskLogger::kResetTaskIndex, taskStartTime); #endif @@ -208,7 +238,8 @@ void BikeSystem::speedDistanceTask() { std::chrono::microseconds responseTime = _timer.elapsed_time() - currentStep->callTime; - tr_info("Reset task: response time is %" PRIu64 " usecs", responseTime.count()); + tr_info("Speed distance task: response time is %" PRIu64 " usecs", + responseTime.count()); osStatus status = _mailPedalDevice.free(currentStep); if (status != osOK) { @@ -228,6 +259,9 @@ void BikeSystem::speedDistanceTask() { _mutexSpeedometer.unlock(); // END CRITICAL SECTION + ThisThread::sleep_for(std::chrono::duration_cast( + kSpeedDistanceTaskComputationTime - (_timer.elapsed_time() - taskStartTime))); + _taskLogger.logPeriodAndExecutionTime( _timer, advembsof::TaskLogger::kSpeedTaskIndex, taskStartTime); } @@ -239,6 +273,16 @@ void BikeSystem::gearTask() { gearMail_t* currentGear = _mailGearDevice.try_get(); if (currentGear != nullptr) { +#if !defined(MBED_TEST_MODE) + std::chrono::microseconds responseTime = + _timer.elapsed_time() - currentGear->callTime; + tr_info("Gear task: response time is %" PRIu64 " usecs", responseTime.count()); +#endif + +#if defined(MBED_TEST_MODE) + _cbGearChange(); +#endif + // ENTER CRITICAL SECTION _mutexGear.lock(); _currentGear = currentGear->gear; @@ -248,17 +292,17 @@ void BikeSystem::gearTask() { _mutexGearSize.unlock(); // END CRITICAL SECTION - std::chrono::microseconds responseTime = - _timer.elapsed_time() - currentGear->callTime; - tr_info("Reset task: response time is %" PRIu64 " usecs", responseTime.count()); - osStatus status = _mailGearDevice.free(currentGear); if (status != osOK) { tr_error("free current gear in the gear tasks doesn't work !"); } } + + ThisThread::sleep_for(std::chrono::duration_cast( + kGearTaskComputationTime - (_timer.elapsed_time() - taskStartTime))); + _taskLogger.logPeriodAndExecutionTime( - _timer, advembsof::TaskLogger::kSpeedTaskIndex, taskStartTime); + _timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime); } /* Main thread functions */ diff --git a/multi_tasking/bike_system.hpp b/multi_tasking/bike_system.hpp index 68d2789..377a084 100644 --- a/multi_tasking/bike_system.hpp +++ b/multi_tasking/bike_system.hpp @@ -59,6 +59,9 @@ class BikeSystem { #if defined(MBED_TEST_MODE) const advembsof::TaskLogger& getTaskLogger(); bike_computer::Speedometer& getSpeedometer(); + GearDevice& getGearDevice(); + void setCallbackGearChage(Callback cbGearChange); + Callback _cbGearChange; #endif // defined(MBED_TEST_MODE) private: From 0ec735adde6f667d79daf37b7ef61f356050fa3c Mon Sep 17 00:00:00 2001 From: fastium Date: Mon, 6 Jan 2025 11:05:23 +0100 Subject: [PATCH 21/28] FIX unused variables --- multi_tasking/bike_system.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/multi_tasking/bike_system.cpp b/multi_tasking/bike_system.cpp index 98d84ee..112455d 100644 --- a/multi_tasking/bike_system.cpp +++ b/multi_tasking/bike_system.cpp @@ -39,27 +39,16 @@ namespace multi_tasking { -static constexpr std::chrono::milliseconds kGearTaskPeriod = 800ms; -static constexpr std::chrono::milliseconds kGearTaskDelay = 0ms; -static constexpr std::chrono::milliseconds kGearTaskComputationTime = 100ms; -static constexpr std::chrono::milliseconds kSpeedDistanceTaskPeriod = 400ms; -static constexpr std::chrono::milliseconds kSpeedDistanceTaskDelay = 0ms; // 0 or 100ms +static constexpr std::chrono::milliseconds kGearTaskComputationTime = 100ms; static constexpr std::chrono::milliseconds kSpeedDistanceTaskComputationTime = 200ms; static constexpr std::chrono::milliseconds kDisplayTask1Period = 1600ms; static constexpr std::chrono::milliseconds kDisplayTask1Delay = 300ms; static constexpr std::chrono::milliseconds kDisplayTask1ComputationTime = 200ms; -static constexpr std::chrono::milliseconds kResetTaskPeriod = 800ms; -static constexpr std::chrono::milliseconds kResetTaskDelay = 700ms; -static constexpr std::chrono::milliseconds kResetTaskComputationTime = 100ms; static constexpr std::chrono::milliseconds kTemperatureTaskPeriod = 1600ms; static constexpr std::chrono::milliseconds kTemperatureTaskDelay = 1100ms; static constexpr std::chrono::milliseconds kTemperatureTaskComputationTime = 100ms; -static constexpr std::chrono::milliseconds kDisplayTask2Period = 1600ms; -static constexpr std::chrono::milliseconds kDisplayTask2Delay = 1200ms; -static constexpr std::chrono::milliseconds kDisplayTask2ComputationTime = 100ms; static constexpr std::chrono::milliseconds kCPUTaskPeriod = 1600ms; static constexpr std::chrono::milliseconds kCPUTaskDelay = 0ms; -static constexpr std::chrono::milliseconds kCPUTaskComputationTime = 0ms; BikeSystem::BikeSystem() : _timer(), From 6d42dd2ba1ba2cd05b44783ceb85329636b0d543 Mon Sep 17 00:00:00 2001 From: fastium Date: Mon, 6 Jan 2025 11:18:14 +0100 Subject: [PATCH 22/28] ADD real timing test for reset task --- .pre-commit-config.yaml | 2 +- TESTS/bike-computer/bike-system/main.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 830e48c..f568f65 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,5 +22,5 @@ repos: - id: cppcheck name: cppcheck require_serial: true - entry: cppcheck --enable=all --suppress=missingInclude --suppress=missingIncludeSystem --suppress=unusedFunction --inline-suppr -i mbed-os --std=c++14 --error-exitcode=1 + entry: cppcheck --enable=all --suppress=missingInclude --suppress=missingIncludeSystem --inline-suppr -i mbed-os --std=c++14 --error-exitcode=1 language: system diff --git a/TESTS/bike-computer/bike-system/main.cpp b/TESTS/bike-computer/bike-system/main.cpp index f566562..f1c819f 100644 --- a/TESTS/bike-computer/bike-system/main.cpp +++ b/TESTS/bike-computer/bike-system/main.cpp @@ -261,8 +261,8 @@ static void test_reset_multi_tasking_bike_system() { TEST_ASSERT_TRUE(responseTime.count() <= kMaxExpectedResponseTime.count()); // jitter of 20us is accepted - constexpr uint64_t kDeltaUs = 3; - constexpr std::chrono::microseconds kMaxExpectedJitter(2); + constexpr uint64_t kDeltaUs = 4; + constexpr std::chrono::microseconds kMaxExpectedJitter(3); if (i > 0) { auto jitter = responseTime - lastResponseTime; tr_info("Reset task: jitter is %lld usecs\n", std::abs(jitter.count())); From 7d228d67ccad0042c6d8cd25935da0db4c948fdc Mon Sep 17 00:00:00 2001 From: Fastium <79766552+Fastium@users.noreply.github.com> Date: Mon, 6 Jan 2025 18:18:49 +0100 Subject: [PATCH 23/28] FIX mbed_app.json --- mbed_app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mbed_app.json b/mbed_app.json index 5fb202c..364fd93 100644 --- a/mbed_app.json +++ b/mbed_app.json @@ -16,7 +16,7 @@ "target.printf_lib": "minimal-printf", "platform.minimal-printf-enable-floating-point": true, "platform.minimal-printf-set-floating-point-max-decimals": 2 - } + }, "DISCO_H747I": { "mbed-trace.enable": true, "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", From d0ff3defa1f531c8e90f3379c964a18bf14f877b Mon Sep 17 00:00:00 2001 From: fastium Date: Mon, 6 Jan 2025 18:27:12 +0100 Subject: [PATCH 24/28] FIX mbed_app.json --- mbed_app.json | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/mbed_app.json b/mbed_app.json index 364fd93..5d66112 100644 --- a/mbed_app.json +++ b/mbed_app.json @@ -17,12 +17,11 @@ "platform.minimal-printf-enable-floating-point": true, "platform.minimal-printf-set-floating-point-max-decimals": 2 }, - "DISCO_H747I": { - "mbed-trace.enable": true, - "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", - "target.bootloader_img":"./mbed-os-bootloader/BUILD/DISCO_H747I/GCC_ARM/mbed-os-bootloader.bin", - "target.app_offset": "0x20000" - } + "DISCO_H747I": { + "mbed-trace.enable": true, + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", + "target.bootloader_img": "./mbed-os-bootloader/BUILD/DISCO_H747I/GCC_ARM/mbed-os-bootloader.bin", + "target.app_offset": "0x20000" } } } From dfd94b647c32bf7b553433fde256e53b4f697282 Mon Sep 17 00:00:00 2001 From: fastium Date: Mon, 6 Jan 2025 23:00:53 +0100 Subject: [PATCH 25/28] FIX kMaxGearSize value --- .pre-commit-config.yaml | 2 +- common/constants.hpp | 2 +- common/speedometer.hpp | 2 +- multi_tasking/bike_system.hpp | 2 +- static_scheduling/bike_system.hpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f568f65..64c5c5a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,5 +22,5 @@ repos: - 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 --suppress=missingIncludeSystem --suppress=unusedStructMember --inline-suppr -i mbed-os --std=c++14 --error-exitcode=1 language: system diff --git a/common/constants.hpp b/common/constants.hpp index 850af8e..8ba92e1 100644 --- a/common/constants.hpp +++ b/common/constants.hpp @@ -36,7 +36,7 @@ static constexpr uint8_t kMaxGear = 9; // smallest gear (= 1) corresponds to a gear size of 20 // when the gear increases, the gear size descreases static constexpr uint8_t kMaxGearSize = 20; -static constexpr uint8_t kMinGearSize = kMaxGearSize - kMinGear; +static constexpr uint8_t kMinGearSize = kMaxGearSize - kMaxGear; // pedal related constants // When compiling and linking with gcc, we get a link error when using static diff --git a/common/speedometer.hpp b/common/speedometer.hpp index 559eafc..6326d77 100644 --- a/common/speedometer.hpp +++ b/common/speedometer.hpp @@ -80,7 +80,7 @@ class Speedometer { float _currentSpeed = 0.0f; Mutex _totalDistanceMutex; float _totalDistance = 0.0f; - uint8_t _gearSize = bike_computer::kMinGearSize; + uint8_t _gearSize = bike_computer::kMaxGearSize; #if defined(MBED_TEST_MODE) mbed::Callback _cb; diff --git a/multi_tasking/bike_system.hpp b/multi_tasking/bike_system.hpp index 377a084..41a1935 100644 --- a/multi_tasking/bike_system.hpp +++ b/multi_tasking/bike_system.hpp @@ -138,7 +138,7 @@ class BikeSystem { ////////////////////////////////////////////////////////////// // shared resources between the main thread and the isr thread uint8_t _currentGear = bike_computer::kMinGear; - uint8_t _currentGearSize = bike_computer::kMinGearSize; + uint8_t _currentGearSize = bike_computer::kMaxGearSize; ////////////////////////////////////////////////////////////// // data member that represents the device for manipulating the pedal rotation diff --git a/static_scheduling/bike_system.hpp b/static_scheduling/bike_system.hpp index 67fefd5..5e8ccf2 100644 --- a/static_scheduling/bike_system.hpp +++ b/static_scheduling/bike_system.hpp @@ -80,7 +80,7 @@ class BikeSystem { // data member that represents the device for manipulating the gear GearDevice _gearDevice; uint8_t _currentGear = bike_computer::kMinGear; - uint8_t _currentGearSize = bike_computer::kMinGearSize; + uint8_t _currentGearSize = bike_computer::kMaxGearSize; // data member that represents the device for manipulating the pedal rotation // speed/time PedalDevice _pedalDevice; From a183ad4858ac9fbdbde679663be0d7c7a1e70d44 Mon Sep 17 00:00:00 2001 From: fastium Date: Mon, 6 Jan 2025 23:07:46 +0100 Subject: [PATCH 26/28] FIX kMaxGearSize value static scheduling with event --- .pre-commit-config.yaml | 2 +- static_scheduling_with_event/bike_system.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 64c5c5a..f568f65 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,5 +22,5 @@ repos: - id: cppcheck name: cppcheck require_serial: true - entry: cppcheck --enable=all --suppress=missingInclude --suppress=missingIncludeSystem --suppress=unusedStructMember --inline-suppr -i mbed-os --std=c++14 --error-exitcode=1 + entry: cppcheck --enable=all --suppress=missingInclude --suppress=missingIncludeSystem --inline-suppr -i mbed-os --std=c++14 --error-exitcode=1 language: system diff --git a/static_scheduling_with_event/bike_system.hpp b/static_scheduling_with_event/bike_system.hpp index 8254f22..c51de14 100644 --- a/static_scheduling_with_event/bike_system.hpp +++ b/static_scheduling_with_event/bike_system.hpp @@ -85,7 +85,7 @@ class BikeSystem { // data member that represents the device for manipulating the gear GearDevice _gearDevice; uint8_t _currentGear = bike_computer::kMinGear; - uint8_t _currentGearSize = bike_computer::kMinGearSize; + uint8_t _currentGearSize = bike_computer::kMaxGearSize; // data member that represents the device for manipulating the pedal rotation // speed/time PedalDevice _pedalDevice; From e460a4f695d4484b5141c129614b4a0d84222d7e Mon Sep 17 00:00:00 2001 From: fastium Date: Tue, 7 Jan 2025 00:35:20 +0100 Subject: [PATCH 27/28] FIX kMaxGearSize and reset callback --- common/speedometer.cpp | 5 ++++- common/speedometer.hpp | 2 +- main.cpp | 12 +++++++----- mbed-bootloader-advembsof.bin | Bin 57472 -> 0 bytes mbed_app.json | 6 ++---- static_scheduling_with_event/bike_system.cpp | 4 ++-- 6 files changed, 16 insertions(+), 13 deletions(-) delete mode 100644 mbed-bootloader-advembsof.bin diff --git a/common/speedometer.cpp b/common/speedometer.cpp index 0f1b413..4ed68be 100644 --- a/common/speedometer.cpp +++ b/common/speedometer.cpp @@ -25,6 +25,7 @@ #include "speedometer.hpp" #include +#include #include #include "static_scheduling/gear_device.hpp" @@ -81,7 +82,9 @@ float Speedometer::getDistance() { void Speedometer::reset() { #if defined(MBED_TEST_MODE) - _cbOnReset(); + if (_cbOnReset != NULL) { + _cbOnReset(); + } #endif this->_totalDistanceMutex.lock(); diff --git a/common/speedometer.hpp b/common/speedometer.hpp index 6326d77..e831cb2 100644 --- a/common/speedometer.hpp +++ b/common/speedometer.hpp @@ -55,7 +55,7 @@ class Speedometer { float getTraySize() const; std::chrono::milliseconds getCurrentPedalRotationTime() const; void setOnResetCallback(mbed::Callback cb); - mbed::Callback _cbOnReset; + mbed::Callback _cbOnReset = NULL; #endif // defined(MBED_TEST_MODE) private: diff --git a/main.cpp b/main.cpp index 17a3e63..45253da 100644 --- a/main.cpp +++ b/main.cpp @@ -7,8 +7,9 @@ #include "mbed.h" // NOLINT #include "mbed_trace.h" // NOLINT -// #include "static_scheduling_with_event/bike_system.hpp" -#include "multi_tasking/bike_system.hpp" +// #include "static_scheduling/bike_system.hpp" +#include "static_scheduling_with_event/bike_system.hpp" +// #include "multi_tasking/bike_system.hpp" #if defined(MBED_CONF_MBED_TRACE_ENABLE) #define TRACE_GROUP "MAIN" @@ -21,11 +22,12 @@ int main() { // static_scheduling::BikeSystem bikeSystem; // bikeSystem.start(); - // static_scheduling_with_event::BikeSystem bikeSystem; - // bikeSystem.start(); - multi_tasking::BikeSystem bikeSystem; + static_scheduling_with_event::BikeSystem bikeSystem; bikeSystem.start(); + + // multi_tasking::BikeSystem bikeSystem; + // bikeSystem.start(); } #endif // MBED_TEST_MODE diff --git a/mbed-bootloader-advembsof.bin b/mbed-bootloader-advembsof.bin deleted file mode 100644 index 5a505d091c8e456dd1fa1349656596efbbdeaf47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57472 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 diff --git a/mbed_app.json b/mbed_app.json index 5d66112..45b383a 100644 --- a/mbed_app.json +++ b/mbed_app.json @@ -2,7 +2,7 @@ "macros": ["MBED_CONF_MBED_TRACE_FEA_IPV6=0"], "config": { "main-stack-size": { - "value": 6144 + "value": 8192 } }, "target_overrides": { @@ -19,9 +19,7 @@ }, "DISCO_H747I": { "mbed-trace.enable": true, - "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", - "target.bootloader_img": "./mbed-os-bootloader/BUILD/DISCO_H747I/GCC_ARM/mbed-os-bootloader.bin", - "target.app_offset": "0x20000" + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG" } } } diff --git a/static_scheduling_with_event/bike_system.cpp b/static_scheduling_with_event/bike_system.cpp index e9416d5..ce87c29 100644 --- a/static_scheduling_with_event/bike_system.cpp +++ b/static_scheduling_with_event/bike_system.cpp @@ -62,7 +62,7 @@ static constexpr std::chrono::milliseconds kDisplayTask2ComputationTime = 100ms; static constexpr std::chrono::milliseconds kCPUTaskPeriod = 1600ms; static constexpr std::chrono::milliseconds kCPUTaskDelay = 1200ms; static constexpr std::chrono::milliseconds kCPUTaskComputationTime = 100ms; - + BikeSystem::BikeSystem() : _gearDevice(), _pedalDevice(), @@ -178,7 +178,7 @@ void BikeSystem::speedDistanceTask() { _taskLogger.logPeriodAndExecutionTime( _timer, advembsof::TaskLogger::kSpeedTaskIndex, taskStartTime); } - + void BikeSystem::displayTask1() { auto taskStartTime = _timer.elapsed_time(); From 787fa94e91f5b4e7d6e6b32a4bc45b7655095c2a Mon Sep 17 00:00:00 2001 From: fastium Date: Tue, 7 Jan 2025 10:22:55 +0100 Subject: [PATCH 28/28] FIX speedometer include and mbed_app.json --- common/speedometer.cpp | 2 -- mbed_app.json | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/speedometer.cpp b/common/speedometer.cpp index 4ed68be..2fbf212 100644 --- a/common/speedometer.cpp +++ b/common/speedometer.cpp @@ -28,8 +28,6 @@ #include #include -#include "static_scheduling/gear_device.hpp" - // from disco_h747i/wrappers #include "joystick.hpp" #include "mbed_trace.h" diff --git a/mbed_app.json b/mbed_app.json index 45b383a..44c1335 100644 --- a/mbed_app.json +++ b/mbed_app.json @@ -19,7 +19,9 @@ }, "DISCO_H747I": { "mbed-trace.enable": true, - "mbed-trace.max-level": "TRACE_LEVEL_DEBUG" + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", + "target.bootloader_img": "./mbed-os-bootloader/BUILD/DISCO_H747I/GCC_ARM/mbed-os-bootloader.bin", + "target.app_offset": "0x20000" } } }