Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve marker functionality and related dumpfile issues #179

Merged
merged 9 commits into from
Nov 18, 2024
Merged
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ lib/
obj/
*.so*

build/
build*/
testing/

# documentation output
Expand Down
2 changes: 1 addition & 1 deletion device/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ BOARD = DISCO_F407VG
DEVICE = STMicroelectronics:stm32:Disco
FQBN = $(DEVICE):pnum=$(BOARD),usb=CDCgen,upload_method=dfuMethod,xusb=FS,opt=o3std
else
$(error Unknown device $(DEV), allowed devices are F401 (default), F411, and F407)
$(error Unknown device $(DEV), allowed devices are F401, F411 (default), and F407)
endif


Expand Down
14 changes: 12 additions & 2 deletions device/PowerSensor/PowerSensor.ino
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ uint8_t serialData[(SENSORS + 1) * 2]; // 16b per sensor and 16b for timestamp
bool sendData = false;
bool streamValues = false;
bool sendSingleValue = false;
bool sendMarkerNext = false;
uint32_t sendMarkers = 0;
bool allSensorsInactive = false;

// include device-specific code for setting up the ADC and DMA
Expand Down Expand Up @@ -233,7 +233,7 @@ void serialEvent() {
break;
case 'M':
// marker character, places a marker in the output file
sendMarkerNext = true;
sendMarkers++;
break;
case 'I':
// Send single set of sensor values. does nothing if streaming is enabled
Expand All @@ -251,6 +251,11 @@ void serialEvent() {
case 'T':
// Disable streaming of data and unpause display
// in demo mode the display is always enabled so no need to reinitialize it here
// if streaming was enabled, first wait until all markers are sent
if (streamValues) {
while (sendMarkers > 0) delay(1);
while (!sendData) delay(1);
}
streamValues = false;
#if !defined NODISPLAY && !defined DEMO
displayPaused = false;
Expand All @@ -259,6 +264,11 @@ void serialEvent() {
break;
case 'X':
// Shutdown and unpause display, shuts off IO thread on host
// if streaming was enabled, first wait until all markers are sent
if (streamValues) {
while (sendMarkers > 0) delay(1);
while (!sendData) delay(1);
}
#ifndef NODISPLAY
displayPaused = false;
displayInitialValues();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ extern "C" void DMA2_Stream0_IRQHandler() {
// store in sensorValues for display purposes
sensorLevels[i] = level;
#endif
// determine whether or not to send marker
// marker is always sent with sensor 0
bool sendMarkerNext = (i == 0) && (sendMarkers > 0);
if (sendMarkerNext) {
sendMarkers--;
}
// add metadata to remaining bits: 2 bytes available with 10b sensor value
// First byte: 1 iii aaaa
// where iii is the sensor id, a are the upper 4 bits of the level
Expand Down
6 changes: 6 additions & 0 deletions device/PowerSensor/device_specific/DISCO_F407VG.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ extern "C" void DMA2_Stream0_IRQHandler() {
// store in sensorValues for display purposes
sensorLevels[i] = level;
#endif
// determine whether or not to send marker
// marker is always sent with sensor 0
bool sendMarkerNext = (i == 0) && (sendMarkers > 0);
if (sendMarkerNext) {
sendMarkers--;
}
// add metadata to remaining bits: 2 bytes available with 10b sensor value
// First byte: 1 iii aaaa
// where iii is the sensor id, a are the upper 4 bits of the level
Expand Down
2 changes: 1 addition & 1 deletion host/include/PowerSensor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ class PowerSensor {

void dump(const std::string dumpFileName); // dumpFileName == 0 --> stop dumping
void mark(char name);
void mark(const State &startState, const State &stopState, const std::string name = 0, unsigned int tag = 0) const;
void reset(bool dfuMode);

void writeSensorsToEEPROM();
Expand Down Expand Up @@ -83,6 +82,7 @@ class PowerSensor {
int openDevice(std::string device);
std::queue<char> markers;
void writeMarker();
void waitForMarkers(int timeout=500);

void initializeSensorPairs();
void updateSensorPairs();
Expand Down
39 changes: 25 additions & 14 deletions host/src/PowerSensor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -348,25 +348,26 @@ void PowerSensor::mark(char name) {
*
*/
void PowerSensor::writeMarker() {
std::unique_lock<std::mutex> lock(dumpFileMutex);
*dumpFile << "M " << markers.front() << std::endl;
markers.pop();
if (dumpFile != nullptr) {
std::unique_lock<std::mutex> lock(dumpFileMutex);
*dumpFile << "M " << markers.front() << std::endl;
markers.pop();
}
}

/**
* @brief Write custom marker to dump file
* @brief Wait for all markers to be written to the dump file
*
* @param startState State used to get start time
* @param stopState State used to get end time
* @param name name of the marker (string)
* @param tag id of the marker (int)
* @param timeout maximum waiting time in milliseconds
*/
void PowerSensor::mark(const State &startState, const State &stopState, std::string name, unsigned int tag) const {
if (dumpFile != nullptr) {
std::unique_lock<std::mutex> lock(dumpFileMutex);
*dumpFile << "M " << elapsedSeconds(startTime, startState.timeAtRead) << ' ' \
<< elapsedSeconds(startTime, stopState.timeAtRead) << ' ' \
<< tag << " \"" << name << '"' << std::endl;
void PowerSensor::waitForMarkers(int timeout) {
auto tstart = std::chrono::high_resolution_clock::now();
while (markers.size() != 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
auto elapsed = std::chrono::high_resolution_clock::now() - tstart;
if (elapsed.count() > timeout) {
break;
}
}
}

Expand Down Expand Up @@ -431,6 +432,8 @@ void PowerSensor::startIOThread() {
*
*/
void PowerSensor::stopIOThread() {
// first ensure there are no markers still to be sent from the device
waitForMarkers();
if (thread != nullptr) {
writeCharToDevice('X');
thread->join();
Expand All @@ -445,6 +448,11 @@ void PowerSensor::stopIOThread() {
* @param dumpFileName
*/
void PowerSensor::dump(std::string dumpFileName) {
// if dumping should be stopped, first wait until all markers are written
if (dumpFileName.empty()) {
waitForMarkers();
}

std::unique_lock<std::mutex> lock(dumpFileMutex);
dumpFile = std::unique_ptr<std::ofstream>(dumpFileName.empty() ? nullptr: new std::ofstream(dumpFileName));
if (!dumpFileName.empty()) {
Expand All @@ -462,6 +470,9 @@ void PowerSensor::dump(std::string dumpFileName) {
*
*/
void PowerSensor::dumpCurrentWattToFile() {
if (dumpFile == nullptr) {
return;
}
std::unique_lock<std::mutex> lock(dumpFileMutex);
double totalWatt = 0;
auto time = std::chrono::high_resolution_clock::now();
Expand Down