ADD gear event driven
This commit is contained in:
		| @@ -28,6 +28,8 @@ | |||||||
|  |  | ||||||
| #include <chrono> | #include <chrono> | ||||||
|  |  | ||||||
|  | #include "cmsis_os2.h" | ||||||
|  | #include "constants.hpp" | ||||||
| #include "mbed_trace.h" | #include "mbed_trace.h" | ||||||
| #if MBED_CONF_MBED_TRACE_ENABLE | #if MBED_CONF_MBED_TRACE_ENABLE | ||||||
| #define TRACE_GROUP "BikeSystem" | #define TRACE_GROUP "BikeSystem" | ||||||
| @@ -58,22 +60,19 @@ static constexpr std::chrono::milliseconds kCPUTaskDelay                     = 0 | |||||||
| static constexpr std::chrono::milliseconds kCPUTaskComputationTime           = 0ms; | static constexpr std::chrono::milliseconds kCPUTaskComputationTime           = 0ms; | ||||||
|  |  | ||||||
| BikeSystem::BikeSystem() | BikeSystem::BikeSystem() | ||||||
|     : _gearDevice(), |     : _gearDevice(callback(this, &BikeSystem::onGearUp), | ||||||
|  |                   callback(this, &BikeSystem::onGearDown)), | ||||||
|       _pedalDevice(), |       _pedalDevice(), | ||||||
|       _resetDevice(callback(this, &BikeSystem::onReset)), |       _resetDevice(callback(this, &BikeSystem::onReset)), | ||||||
|       _speedometer(_timer), |       _speedometer(_timer), | ||||||
|       _cpuLogger(_timer) {} |       _cpuLogger(_timer), | ||||||
|  |       _isrEventThread(osPriorityNormal, OS_STACK_SIZE, nullptr, "ISR_Event") {} | ||||||
|  |  | ||||||
| void BikeSystem::start() { | void BikeSystem::start() { | ||||||
|     tr_info("Starting Super-Loop with event handling"); |     tr_info("Starting Super-Loop with event handling"); | ||||||
|  |  | ||||||
|     init(); |     init(); | ||||||
|  |  | ||||||
|     Event<void()> gearEvent(&_eventQueue, callback(this, &BikeSystem::gearTask)); |  | ||||||
|     gearEvent.delay(kGearTaskDelay); |  | ||||||
|     gearEvent.period(kGearTaskPeriod); |  | ||||||
|     gearEvent.post(); |  | ||||||
|  |  | ||||||
|     Event<void()> speedDistanceEvent(&_eventQueue, |     Event<void()> speedDistanceEvent(&_eventQueue, | ||||||
|                                      callback(this, &BikeSystem::speedDistanceTask)); |                                      callback(this, &BikeSystem::speedDistanceTask)); | ||||||
|     speedDistanceEvent.delay(kSpeedDistanceTaskDelay); |     speedDistanceEvent.delay(kSpeedDistanceTaskDelay); | ||||||
| @@ -98,7 +97,9 @@ void BikeSystem::start() { | |||||||
|  |  | ||||||
|     osStatus status = |     osStatus status = | ||||||
|         _isrEventThread.start(callback(this, &BikeSystem::dispatch_isr_events)); |         _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(); |     dispatch_events(); | ||||||
| } | } | ||||||
| @@ -109,6 +110,19 @@ void BikeSystem::onReset() { | |||||||
|     resetEvent.post(); |     resetEvent.post(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void BikeSystem::onGearUp() { | ||||||
|  |     _onGearUpTime = _timer.elapsed_time(); | ||||||
|  |     Event<void()> gearUpEvent(&_isrEventQueue, callback(this, &BikeSystem::gearUpTask)); | ||||||
|  |     gearUpEvent.post(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void BikeSystem::onGearDown() { | ||||||
|  |     _onGearDownTime = _timer.elapsed_time(); | ||||||
|  |     Event<void()> gearDownEvent(&_isrEventQueue, | ||||||
|  |                                 callback(this, &BikeSystem::gearDownTask)); | ||||||
|  |     gearDownEvent.post(); | ||||||
|  | } | ||||||
|  |  | ||||||
| #if defined(MBED_TEST_MODE) | #if defined(MBED_TEST_MODE) | ||||||
| const advembsof::TaskLogger& BikeSystem::getTaskLogger() { return _taskLogger; } | const advembsof::TaskLogger& BikeSystem::getTaskLogger() { return _taskLogger; } | ||||||
| #endif  // defined(MBED_TEST_MODE) | #endif  // defined(MBED_TEST_MODE) | ||||||
| @@ -120,7 +134,7 @@ void BikeSystem::init() { | |||||||
|     // initialize the lcd display |     // initialize the lcd display | ||||||
|     disco::ReturnCode rc = _displayDevice.init(); |     disco::ReturnCode rc = _displayDevice.init(); | ||||||
|     if (rc != disco::ReturnCode::Ok) { |     if (rc != disco::ReturnCode::Ok) { | ||||||
|         tr_error("Failed to initialized the lcd display: %d", static_cast<int>(rc)); |         tr_error("Ffalseailed to initialized the lcd display: %ld", static_cast<int>(rc)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // initialize the sensor device |     // initialize the sensor device | ||||||
| @@ -130,16 +144,43 @@ void BikeSystem::init() { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // enable/disable task logging |     // enable/disable task logging | ||||||
|     _taskLogger.enable(false); |     _taskLogger.enable(true); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BikeSystem::gearTask() { | void BikeSystem::gearUpTask() { | ||||||
|     // gear task |  | ||||||
|     auto taskStartTime                     = _timer.elapsed_time(); |     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) |     // CRITICAL SECTION | ||||||
|     _currentGear     = _gearDevice.getCurrentGear(); |     mutexGear.lock(); | ||||||
|     _currentGearSize = _gearDevice.getCurrentGearSize(); |     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( |     _taskLogger.logPeriodAndExecutionTime( | ||||||
|         _timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime); |         _timer, advembsof::TaskLogger::kGearTaskIndex, taskStartTime); | ||||||
| @@ -150,7 +191,7 @@ void BikeSystem::speedDistanceTask() { | |||||||
|  |  | ||||||
|     const auto pedalRotationTime = _pedalDevice.getCurrentRotationTime(); |     const auto pedalRotationTime = _pedalDevice.getCurrentRotationTime(); | ||||||
|     _speedometer.setCurrentRotationTime(pedalRotationTime); |     _speedometer.setCurrentRotationTime(pedalRotationTime); | ||||||
|     _speedometer.setGearSize(_currentGearSize); |     _speedometer.setGearSize(getCurrentGearSize()); | ||||||
|  |  | ||||||
|     _currentSpeed     = _speedometer.getCurrentSpeed(); |     _currentSpeed     = _speedometer.getCurrentSpeed(); | ||||||
|     _traveledDistance = _speedometer.getDistance(); |     _traveledDistance = _speedometer.getDistance(); | ||||||
| @@ -190,7 +231,7 @@ void BikeSystem::resetTask() { | |||||||
| void BikeSystem::displayTask1() { | void BikeSystem::displayTask1() { | ||||||
|     auto taskStartTime = _timer.elapsed_time(); |     auto taskStartTime = _timer.elapsed_time(); | ||||||
|  |  | ||||||
|     _displayDevice.displayGear(_currentGear); |     _displayDevice.displayGear(getCurrentGear()); | ||||||
|     _displayDevice.displaySpeed(_currentSpeed); |     _displayDevice.displaySpeed(_currentSpeed); | ||||||
|     _displayDevice.displayDistance(_traveledDistance); |     _displayDevice.displayDistance(_traveledDistance); | ||||||
|  |  | ||||||
| @@ -227,4 +268,28 @@ void BikeSystem::dispatch_events() { | |||||||
|     tr_info("Stop dispatching main 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 | }  // namespace multi_tasking | ||||||
|   | |||||||
| @@ -67,7 +67,10 @@ class BikeSystem { | |||||||
|     // private methods |     // private methods | ||||||
|     void init(); |     void init(); | ||||||
|     void onReset(); |     void onReset(); | ||||||
|     void gearTask(); |     void onGearUp(); | ||||||
|  |     void onGearDown(); | ||||||
|  |     void gearUpTask(); | ||||||
|  |     void gearDownTask(); | ||||||
|     void speedDistanceTask(); |     void speedDistanceTask(); | ||||||
|     void temperatureTask(); |     void temperatureTask(); | ||||||
|     void resetTask(); |     void resetTask(); | ||||||
| @@ -75,13 +78,23 @@ class BikeSystem { | |||||||
|     void displayTask2(); |     void displayTask2(); | ||||||
|     void cpuTask(); |     void cpuTask(); | ||||||
|  |  | ||||||
|  |     uint8_t getCurrentGear(); | ||||||
|  |     uint8_t getCurrentGearSize(); | ||||||
|  |     void setCurrentGear(uint8_t gear); | ||||||
|  |  | ||||||
|     // timer instance used for loggint task time and used by ResetDevice |     // 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; |     Timer _timer; | ||||||
|     // data member that represents the device for manipulating the gear |     // data member that represents the device for manipulating the gear | ||||||
|     GearDevice _gearDevice; |     GearDevice _gearDevice; | ||||||
|  |     ////////////////////////////////////////////////////////////// | ||||||
|  |     // shared resources between the main thread and the isr thread | ||||||
|     uint8_t _currentGear     = bike_computer::kMinGear; |     uint8_t _currentGear     = bike_computer::kMinGear; | ||||||
|     uint8_t _currentGearSize = bike_computer::kMinGearSize; |     uint8_t _currentGearSize = bike_computer::kMinGearSize; | ||||||
|  |     ////////////////////////////////////////////////////////////// | ||||||
|     // data member that represents the device for manipulating the pedal rotation |     // data member that represents the device for manipulating the pedal rotation | ||||||
|     // speed/time |     // speed/time | ||||||
|     PedalDevice _pedalDevice; |     PedalDevice _pedalDevice; | ||||||
| @@ -107,9 +120,12 @@ class BikeSystem { | |||||||
|     EventQueue _isrEventQueue; |     EventQueue _isrEventQueue; | ||||||
|     EventQueue _eventQueue; |     EventQueue _eventQueue; | ||||||
|  |  | ||||||
|  |     // mutex for shared resource | ||||||
|  |     Mutex mutexGearSize; | ||||||
|  |     Mutex mutexGear; | ||||||
|  |  | ||||||
|     // Tread for isr events |     // Tread for isr events | ||||||
|     Thread _isrEventThread; |     Thread _isrEventThread; | ||||||
|     Thread _mainEventThread; |  | ||||||
|  |  | ||||||
|     void dispatch_isr_events(); |     void dispatch_isr_events(); | ||||||
|     void dispatch_events(); |     void dispatch_events(); | ||||||
|   | |||||||
| @@ -38,27 +38,9 @@ | |||||||
|  |  | ||||||
| namespace multi_tasking { | namespace multi_tasking { | ||||||
|  |  | ||||||
| GearDevice::GearDevice() { | GearDevice::GearDevice(Callback<void()> cbOnUp, Callback<void()> cbOnDown) { | ||||||
|     disco::Joystick::getInstance().setUpCallback(callback(this, &GearDevice::onUp)); |     disco::Joystick::getInstance().setUpCallback(callback(cbOnUp)); | ||||||
|     disco::Joystick::getInstance().setDownCallback(callback(this, &GearDevice::onDown)); |     disco::Joystick::getInstance().setDownCallback(callback(cbOnDown)); | ||||||
| } |  | ||||||
|  |  | ||||||
| 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 multi_tasking | }  // namespace multi_tasking | ||||||
|   | |||||||
| @@ -26,29 +26,20 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "constants.hpp" |  | ||||||
| #include "mbed.h" | #include "mbed.h" | ||||||
|  |  | ||||||
| namespace multi_tasking { | namespace multi_tasking { | ||||||
|  |  | ||||||
| class GearDevice { | class GearDevice { | ||||||
|    public: |    public: | ||||||
|     GearDevice();  // NOLINT(runtime/references) |     GearDevice(Callback<void()> cbOnUp, | ||||||
|  |                Callback<void()> cbOnDown);  // NOLINT(runtime/references) | ||||||
|  |  | ||||||
|     // make the class non copyable |     // make the class non copyable | ||||||
|     GearDevice(GearDevice&)            = delete; |     GearDevice(GearDevice&)            = delete; | ||||||
|     GearDevice& operator=(GearDevice&) = delete; |     GearDevice& operator=(GearDevice&) = delete; | ||||||
|  |  | ||||||
|     // method called for updating the bike system |     // 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 | }  // namespace multi_tasking | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user