ADD measure time call

This commit is contained in:
fastium 2025-01-04 15:51:51 +01:00
parent 4fb09c690c
commit b9c129e872
6 changed files with 125 additions and 92 deletions

View File

@ -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<void()> display1Event(&_eventQueue, callback(this, &BikeSystem::displayTask1));
display1Event.delay(kDisplayTask1Delay);
display1Event.period(kDisplayTask1Period);
display1Event.post();
Event<void()> temperatureEvent(&_eventQueue,
callback(this, &BikeSystem::temperatureTask));
temperatureEvent.delay(kTemperatureTaskDelay);
temperatureEvent.period(kTemperatureTaskPeriod);
temperatureEvent.post();
Event<void()> display2Event(&_eventQueue, callback(this, &BikeSystem::displayTask2));
display2Event.delay(kDisplayTask2Delay);
display2Event.period(kDisplayTask2Period);
display2Event.post();
Event<void()> 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<void()> 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<std::chrono::milliseconds>(
kDisplayTask1ComputationTime - (_timer.elapsed_time() - taskStartTime)));
_displayDevice.displayTemperature(_currentTemperature);
// ThisThread::sleep_for(std::chrono::duration_cast<std::chrono::milliseconds>(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<std::chrono::milliseconds>(
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();

View File

@ -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<pedalMail_t, 16> _mailPedalDevice;
Mail<gearMail_t, 16> _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<uint32_t, 16> _mailPedalDevice;
Mail<uint8_t, 16> _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

View File

@ -26,8 +26,9 @@
#include "gear_device.hpp"
#include "bike_system.hpp"
// from disco_h747i/wrappers
#include <chrono>
#include "joystick.hpp"
#include "mbed_atomic.h"
@ -39,11 +40,10 @@
namespace multi_tasking {
GearDevice::GearDevice(Mail<uint8_t, 16>* mailBox) {
GearDevice::GearDevice(Mail<gearMail_t, 16>* 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,11 +61,14 @@ void GearDevice::onDown() {
}
void GearDevice::sendMail(uint32_t data) {
uint8_t* currentGear = _mailBox->try_alloc();
if (_mailBox != nullptr) {
gearMail_t* currentGear = _mailBox->try_alloc();
if (currentGear != nullptr) {
*currentGear = data;
currentGear->gear = data;
currentGear->callTime = _timer.elapsed_time();
_mailBox->put(currentGear);
}
}
}
} // namespace multi_tasking

View File

@ -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<uint8_t, 16>* mailBox); // NOLINT(runtime/references)
explicit GearDevice(Mail<gearMail_t, 16>* 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<uint8_t, 16>* _mailBox;
Mail<gearMail_t, 16>* _mailBox;
Timer& _timer;
};
} // namespace multi_tasking

View File

@ -27,6 +27,7 @@
// from disco_h747i/wrappers
#include <chrono>
#include "bike_system.hpp"
#include "joystick.hpp"
#include "mbed_trace.h"
@ -36,19 +37,18 @@
namespace multi_tasking {
PedalDevice::PedalDevice(Mail<uint32_t, 16>* mailBox) {
PedalDevice::PedalDevice(Mail<pedalMail_t, 16>* 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 (_mailBox != nullptr) {
pedalMail_t* currentStep = _mailBox->try_alloc();
if (currentStep != nullptr) {
*currentStep = data;
(*_mailBox).put(currentStep);
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 +

View File

@ -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<uint32_t, 16>* mailBox); // NOLINT(runtime/references)
explicit PedalDevice(Mail<pedalMail_t, 16>* 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<uint32_t, 16>* _mailBox;
Mail<pedalMail_t, 16>* _mailBox;
Timer& _timer;
};
} // namespace multi_tasking