From f64b8bdd9a53f5e57c150f9baf5212397128beb5 Mon Sep 17 00:00:00 2001 From: fastium Date: Tue, 31 Dec 2024 13:47:36 +0100 Subject: [PATCH] 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