ADD gear event driven
This commit is contained in:
		| @@ -28,6 +28,8 @@ | ||||
|  | ||||
| #include <chrono> | ||||
|  | ||||
| #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<void()> gearEvent(&_eventQueue, callback(this, &BikeSystem::gearTask)); | ||||
|     gearEvent.delay(kGearTaskDelay); | ||||
|     gearEvent.period(kGearTaskPeriod); | ||||
|     gearEvent.post(); | ||||
|  | ||||
|     Event<void()> 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<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) | ||||
| 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<int>(rc)); | ||||
|         tr_error("Ffalseailed to initialized the lcd display: %ld", static_cast<int>(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 | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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<void()> cbOnUp, Callback<void()> cbOnDown) { | ||||
|     disco::Joystick::getInstance().setUpCallback(callback(cbOnUp)); | ||||
|     disco::Joystick::getInstance().setDownCallback(callback(cbOnDown)); | ||||
| } | ||||
|  | ||||
| }  // namespace multi_tasking | ||||
|   | ||||
| @@ -26,29 +26,20 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "constants.hpp" | ||||
| #include "mbed.h" | ||||
|  | ||||
| namespace multi_tasking { | ||||
|  | ||||
| class GearDevice { | ||||
|    public: | ||||
|     GearDevice();  // NOLINT(runtime/references) | ||||
|     GearDevice(Callback<void()> cbOnUp, | ||||
|                Callback<void()> 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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user