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