1
0
Fork 0
mirror of https://github.com/EdgeTX/edgetx.git synced 2025-07-21 15:25:12 +03:00

[simulation] Fix some potential crashes & 26 memory leaks, improve LCD redraws. (#4634)

* [simulation] Hardening: Fix some potential crashes & 26 memory leaks, improve LCD performance.
  * [simpgmspace] Init trims; Make sure `REa` is really defined (to match board files).
  * [simpgmspace][opentxsimulator] Verify current running state before start/stop; Move rotary enc. init.
  * [simpgmspace][LcdWidget] Improve performance by moving LCD content change check to lcdRefresh() & limiting LcdWidget refresh time to 60 fps max.
  * [simueeprom] Ensure thread could be started, set default running state to false.
  * [simufatfs] Fix paths report trace.
  * [eepromimportexport] Fix memory leaks resulting from import debugging scheme being used.
  * [customdebug] Introduce new scheme for custom debug output in compliance with Qt recommendations (see docs for QLoggingCategory).
  * [opentxeeprom] Fix extra conversion table cache elements being created and also not properly deleted (and hence leaking).
  * [opentxinterface] Unregister EEpromInterfaces in unregisterOpenTxFirmwares();
  * [storage] Unregister storage factories on exit (fixes leak); create virtual StorageFormat/StorageFactory destructors (prevents warnings).
  * [helpers] GVarGroup now emits own signal, no need to pass ModelPanel pointer (removes dependency on modeledit.h)
  * [DebugOutput] Clear simulator trace hook before exiting (prevent possible issues); Fix leak and possible bad QString allocations when reading from buffer; Fix leak with combo box event filter.
  * [TelemetrySimulator] Fix leak by deleting LogPlaybackController object on exit; Only set up data fields once; convert timers to static.
  * [build] Consolidate all Companion/Simulator shared items in `common` library to reduce build time/etc (node & edge still remain awkward).

* [simulatorwidget] Delete removed spacer object (previously-forgotten "26th" leak).

* [DebugOutput] Fix stray trailing characters issue with new text buffer allocation (from previous commit); Increase maximum buffer sizes to better accommodate slower systems.

* Cosmetics.
This commit is contained in:
Max Paperno 2017-03-21 02:43:40 -04:00 committed by Bertrand Songis
parent 52e65179a8
commit 4aa0c1bbe4
28 changed files with 290 additions and 210 deletions

View file

@ -124,7 +124,9 @@ add_subdirectory(thirdparty/qxtcommandoptions)
set(common_SRCS
appdebugmessagehandler.cpp
boards.cpp
customdebug.cpp
eeprominterface.cpp
helpers.cpp
radiodata.cpp
firmwares/er9x/er9xeeprom.cpp
firmwares/er9x/er9xinterface.cpp
@ -132,21 +134,25 @@ set(common_SRCS
firmwares/ersky9x/ersky9xinterface.cpp
firmwares/opentx/opentxeeprom.cpp
firmwares/opentx/opentxinterface.cpp
modeledit/node.cpp # used in simulator
modeledit/edge.cpp # used by node
)
set(common_MOC_HDRS
appdebugmessagehandler.h
helpers.h
modeledit/node.h
)
qt5_wrap_cpp(common_SRCS ${common_MOC_HDRS})
add_library(common ${common_SRCS})
qt5_use_modules(common Core Xml Widgets)
target_link_libraries(common simulation)
############# Companion ###############
set(companion_SRCS
helpers.cpp
helpers_html.cpp
mdichild.cpp
modelslist.cpp
@ -206,7 +212,6 @@ set(companion_MOC_HDRS
mdichild.h
mainwindow.h
radionotfound.h
helpers.h
wizarddialog.h
modelprinter.h
multimodelprinter.h
@ -259,9 +264,9 @@ qt5_wrap_ui(companion_SRCS ${companion_UIS})
qt5_wrap_cpp(companion_SRCS ${companion_MOC_HDRS})
qt5_add_translation(companion_QM ${companion_TS})
qt5_add_resources(companion_RCC ${companion_RESOURCES})
add_custom_target(gen_qrc DEPENDS ${companion_RCC})
add_custom_target(gen_qrc DEPENDS ${companion_RCC} ${companion_QM})
add_executable(${COMPANION_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${companion_SRCS} ${companion_RCC} ${companion_QM})
add_executable(${COMPANION_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${companion_SRCS} ${companion_RCC})
add_dependencies(${COMPANION_NAME} gen_qrc)
qt5_use_modules(${COMPANION_NAME} Core Widgets Network)
@ -272,19 +277,7 @@ PrintTargetReport("${COMPANION_NAME}")
############# Standalone simulator ###############
set(simu_SRCS
modeledit/node.cpp
modeledit/edge.cpp
helpers.cpp
simulator.cpp
)
set(simu_MOC_HDRS
modeledit/node.h
helpers.h
)
qt5_wrap_cpp(simu_SRCS ${simu_MOC_HDRS} )
set(simu_SRCS simulator.cpp )
if(WIN32)
list(APPEND simu_SRCS icon.rc)
@ -293,7 +286,7 @@ endif()
add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${simu_SRCS} ${companion_RCC})
add_dependencies(${SIMULATOR_NAME} gen_qrc)
target_link_libraries(${SIMULATOR_NAME} PRIVATE simulation common shared storage qxtcommandoptions ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${WIN_LINK_LIBRARIES})
target_link_libraries(${SIMULATOR_NAME} PRIVATE simulation common storage qxtcommandoptions ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${WIN_LINK_LIBRARIES})
############# Translations ####################

View file

@ -28,6 +28,7 @@
#endif
#include "appdebugmessagehandler.h"
#include "customdebug.h"
#include "mainwindow.h"
#include "version.h"
#include "appdata.h"
@ -65,6 +66,8 @@ int main(int argc, char *argv[])
if (AppDebugMessageHandler::instance())
AppDebugMessageHandler::instance()->installAppMessageHandler();
CustomDebug::setFilterRules();
g.init();
QStringList strl = QApplication::arguments();
@ -134,7 +137,7 @@ int main(int argc, char *argv[])
unregisterSimulators();
unregisterOpenTxFirmwares();
unregisterEEpromInterfaces();
unregisterStorageFactories();
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
SDL_Quit();

View file

@ -0,0 +1,36 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "customdebug.h"
Q_LOGGING_CATEGORY(eepromImport, "eeprom.import")
void CustomDebug::setFilterRules()
{
QString rules;
rules.append("eeprom.import=");
#if defined(DEBUG_STORAGE_IMPORT)
rules.append("true");
#else
rules.append("false");
#endif
QLoggingCategory::setFilterRules(rules);
}

View file

@ -21,15 +21,15 @@
#ifndef _CUSTOMDEBUG_H_
#define _CUSTOMDEBUG_H_
#include <QDebug>
#include <QLoggingCategory>
// Controls the generation of debug output for EEPROM import
#if defined(DEBUG_STORAGE_IMPORT)
inline QDebug eepromImportDebug() { return QDebug(QtDebugMsg); }
#else
#undef eepromImportDebug
inline QNoDebug eepromImportDebug() { return QNoDebug(); }
#endif
Q_DECLARE_LOGGING_CATEGORY(eepromImport)
class CustomDebug
{
public:
static void setFilterRules();
};
#endif // _CUSTOMDEBUG_H_

View file

@ -181,7 +181,7 @@ class BaseUnsignedField: public DataField {
if (input[i])
field |= ((container)1<<i);
}
eepromImportDebug() << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
qCDebug(eepromImport) << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
}
virtual unsigned int size()
@ -238,7 +238,7 @@ class BoolField: public DataField {
virtual void ImportBits(const QBitArray & input)
{
field = input[0] ? true : false;
eepromImportDebug() << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
qCDebug(eepromImport) << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
}
virtual unsigned int size()
@ -308,7 +308,7 @@ class SignedField: public DataField {
}
field = (int)value;
eepromImportDebug() << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
qCDebug(eepromImport) << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field);
}
virtual unsigned int size()
@ -369,7 +369,7 @@ class CharField: public DataField {
}
field[i] = idx;
}
eepromImportDebug() << QString("\timported %1<%2>: '%3'").arg(name).arg(N).arg(field);
qCDebug(eepromImport) << QString("\timported %1<%2>: '%3'").arg(name).arg(N).arg(field);
}
virtual unsigned int size()
@ -427,7 +427,7 @@ class ZCharField: public DataField {
else
break;
}
eepromImportDebug() << QString("\timported %1<%2>: '%3'").arg(name).arg(N).arg(field);
qCDebug(eepromImport) << QString("\timported %1<%2>: '%3'").arg(name).arg(N).arg(field);
}
virtual unsigned int size()
@ -453,7 +453,7 @@ class StructField: public DataField {
}
inline void Append(DataField * field) {
//eepromImportDebug() << QString("StructField(%1) appending field: %2").arg(name).arg(field->getName());
//qCDebug(eepromImport) << QString("StructField(%1) appending field: %2").arg(name).arg(field->getName());
fields.append(field);
}
@ -471,7 +471,7 @@ class StructField: public DataField {
virtual void ImportBits(const QBitArray & input)
{
eepromImportDebug() << QString("\timporting %1[%2]:").arg(name).arg(fields.size());
qCDebug(eepromImport) << QString("\timporting %1[%2]:").arg(name).arg(fields.size());
int offset = 0;
foreach(DataField *field, fields) {
unsigned int size = field->size();
@ -526,7 +526,7 @@ class TransformedField: public DataField {
virtual void ImportBits(const QBitArray & input)
{
eepromImportDebug() << QString("\timporting TransformedField %1:").arg(field.getName());
qCDebug(eepromImport) << QString("\timporting TransformedField %1:").arg(field.getName());
field.ImportBits(input);
afterImport();
}
@ -564,7 +564,7 @@ class ConversionTable {
after = 0;
for (std::list<ConversionTuple>::iterator it=exportTable.begin(); it!=exportTable.end(); it++) {
ConversionTuple tuple = *it;
ConversionTuple & tuple = *it;
if (before == tuple.a) {
after = tuple.b;
return true;
@ -579,7 +579,7 @@ class ConversionTable {
after = 0;
for (std::list<ConversionTuple>::iterator it=importTable.begin(); it!=importTable.end(); it++) {
ConversionTuple tuple = *it;
ConversionTuple & tuple = *it;
if (before == tuple.b) {
after = tuple.a;
return true;
@ -756,7 +756,7 @@ class ConversionField: public TransformedField {
if (scale) {
field *= scale;
}
eepromImportDebug() << QString("\timported ConversionField<%1>:").arg(internalField.getName()) << QString(" before: %1, after: %2").arg(_field).arg(field);
qCDebug(eepromImport) << QString("\timported ConversionField<%1>:").arg(internalField.getName()) << QString(" before: %1, after: %2").arg(_field).arg(field);
}
protected:

View file

@ -160,6 +160,7 @@ class SwitchesConversionTable: public ConversionTable {
}
}
protected:
void addConversion(const RawSwitch & sw, const int b)
@ -199,7 +200,7 @@ class SwitchesConversionTable: public ConversionTable {
static SwitchesConversionTable * getInstance(Board::Type board, unsigned int version, unsigned long flags=0)
{
for (std::list<Cache>::iterator it=internalCache.begin(); it!=internalCache.end(); it++) {
Cache element = *it;
Cache & element = *it;
if (element.board == board && element.version == version && element.flags == flags)
return element.table;
}
@ -211,7 +212,8 @@ class SwitchesConversionTable: public ConversionTable {
static void Cleanup()
{
for (std::list<Cache>::iterator it=internalCache.begin(); it!=internalCache.end(); it++) {
Cache element = *it;
Cache & element = *it;
if (element.table)
delete element.table;
}
internalCache.clear();
@ -386,7 +388,7 @@ class SourcesConversionTable: public ConversionTable {
static SourcesConversionTable * getInstance(Board::Type board, unsigned int version, unsigned int variant, unsigned long flags=0)
{
for (std::list<Cache>::iterator it=internalCache.begin(); it!=internalCache.end(); it++) {
Cache element = *it;
Cache & element = *it;
if (element.board == board && element.version == version && element.variant == variant && element.flags == flags)
return element.table;
}
@ -398,7 +400,8 @@ class SourcesConversionTable: public ConversionTable {
static void Cleanup()
{
for (std::list<Cache>::iterator it=internalCache.begin(); it!=internalCache.end(); it++) {
Cache element = *it;
Cache & element = *it;
if (element.table)
delete element.table;
}
internalCache.clear();
@ -439,7 +442,7 @@ class SwitchField: public ConversionField< SignedField<N> > {
{
ConversionField< SignedField<N> >::afterImport();
sw = RawSwitch(_switch);
eepromImportDebug() << QString("imported %1: %2").arg(ConversionField< SignedField<N> >::internalField.getName()).arg(sw.toString(board));
qCDebug(eepromImport) << QString("imported %1: %2").arg(ConversionField< SignedField<N> >::internalField.getName()).arg(sw.toString(board));
}
protected:
@ -565,7 +568,7 @@ class TelemetrySourceField: public ConversionField< UnsignedField<N> > {
{
ConversionField< UnsignedField<N> >::afterImport();
source = (_source == 0 ? RawSource(0) : RawSource(SOURCE_TYPE_TELEMETRY, _source-1));
eepromImportDebug() << QString("imported %1: %2").arg(ConversionField< UnsignedField<N> >::internalField.getName()).arg(source.toString());
qCDebug(eepromImport) << QString("imported %1: %2").arg(ConversionField< UnsignedField<N> >::internalField.getName()).arg(source.toString());
}
protected:
@ -601,7 +604,7 @@ class SourceField: public ConversionField< UnsignedField<N> > {
{
ConversionField< UnsignedField<N> >::afterImport();
source = RawSource(_source);
eepromImportDebug() << QString("imported %1: %2").arg(ConversionField< UnsignedField<N> >::internalField.getName()).arg(source.toString());
qCDebug(eepromImport) << QString("imported %1: %2").arg(ConversionField< UnsignedField<N> >::internalField.getName()).arg(source.toString());
}
protected:
@ -760,7 +763,7 @@ class CurveReferenceField: public TransformedField {
{
curve.type = (CurveReference::CurveRefType)_curve_type;
curve.value = smallGvarToC9x(_curve_value);
eepromImportDebug() << QString("imported CurveReference(%1)").arg(curve.toString());
qCDebug(eepromImport) << QString("imported CurveReference(%1)").arg(curve.toString());
}
protected:
@ -942,7 +945,7 @@ class FlightModeField: public TransformedField {
}
}
}
eepromImportDebug() << QString("imported %1: '%2'").arg(internalField.getName()).arg(phase.name);
qCDebug(eepromImport) << QString("imported %1: '%2'").arg(internalField.getName()).arg(phase.name);
}
protected:
@ -1231,7 +1234,7 @@ class MixField: public TransformedField {
}
if (mix.carryTrim < 0) mix.carryTrim = 0;
}
eepromImportDebug() << QString("imported %1: ch %2, name '%3'").arg(internalField.getName()).arg(mix.destCh).arg(mix.name);
qCDebug(eepromImport) << QString("imported %1: ch %2, name '%3'").arg(internalField.getName()).arg(mix.destCh).arg(mix.name);
}
protected:
@ -1412,7 +1415,7 @@ class InputField: public TransformedField {
else
expo.curve = CurveReference(CurveReference::CURVE_REF_FUNC, _curveParam);
}
eepromImportDebug() << QString("imported %1: ch %2 name '%3'").arg(internalField.getName()).arg(expo.chn).arg(expo.name);
qCDebug(eepromImport) << QString("imported %1: ch %2 name '%3'").arg(internalField.getName()).arg(expo.chn).arg(expo.name);
}
protected:
@ -1626,7 +1629,7 @@ class CurvesField: public TransformedField {
for (int j=0; j<curve->count; j++)
curve->points[j].x = -100 + (200*i) / (curve->count-1);
}
eepromImportDebug() << QString("imported curve: %3 points").arg(curve->count);
qCDebug(eepromImport) << QString("imported curve: %3 points").arg(curve->count);
}
}
@ -1955,7 +1958,7 @@ class LogicalSwitchField: public TransformedField {
}
}
}
eepromImportDebug() << QString("imported %1: %2").arg(internalField.getName()).arg(csw.funcToString());
qCDebug(eepromImport) << QString("imported %1: %2").arg(internalField.getName()).arg(csw.funcToString());
}
protected:
@ -2115,7 +2118,7 @@ class SwitchesWarningField: public TransformedField {
else {
sw = _sw;
}
eepromImportDebug() << QString("imported %1").arg(internalField.getName());
qCDebug(eepromImport) << QString("imported %1").arg(internalField.getName());
}
protected:
@ -2350,7 +2353,7 @@ class ArmCustomFunctionField: public TransformedField {
else {
fn.param = value;
}
eepromImportDebug() << QString("imported %1").arg(internalField.getName());
qCDebug(eepromImport) << QString("imported %1").arg(internalField.getName());
}
protected:
@ -2539,7 +2542,7 @@ class AvrCustomFunctionField: public TransformedField {
else if (version >= 213)
fn.repeatParam = _active * 10;
}
eepromImportDebug() << QString("imported %1").arg(internalField.getName());
qCDebug(eepromImport) << QString("imported %1").arg(internalField.getName());
}
protected:
@ -2634,7 +2637,7 @@ class FrskyScreenField: public DataField {
virtual void ImportBits(const QBitArray & input)
{
eepromImportDebug() << QString("importing %1: type: %2").arg(name).arg(screen.type);
qCDebug(eepromImport) << QString("importing %1: type: %2").arg(name).arg(screen.type);
// NOTA: screen.type should have been imported first!
if (IS_ARM(board) && version >= 217) {
@ -3007,7 +3010,7 @@ class SensorField: public TransformedField {
sensor.unit++;
}
eepromImportDebug() << QString("imported %1").arg(internalField.getName());
qCDebug(eepromImport) << QString("imported %1").arg(internalField.getName());
}
protected:
@ -3041,7 +3044,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
{
sprintf(name, "Model %s", modelData.name);
eepromImportDebug() << QString("OpenTxModelData::OpenTxModelData(name: %1, board: %2, ver: %3, var: %4)").arg(name).arg(board).arg(version).arg(variant);
qCDebug(eepromImport) << QString("OpenTxModelData::OpenTxModelData(name: %1, board: %2, ver: %3, var: %4)").arg(name).arg(board).arg(version).arg(variant);
if (IS_HORUS(board))
internalField.Append(new ZCharField<15>(this, modelData.name, "Model name"));
@ -3452,7 +3455,7 @@ void OpenTxModelData::beforeExport()
void OpenTxModelData::afterImport()
{
eepromImportDebug() << QString("OpenTxModelData::afterImport()") << modelData.name;
qCDebug(eepromImport) << QString("OpenTxModelData::afterImport()") << modelData.name;
if (IS_TARANIS(board) && version < 216) {
for (unsigned int i=0; i<CPN_MAX_STICKS; i++) {
@ -3520,7 +3523,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
version(version),
inputsCount(CPN_MAX_STICKS+MAX_POTS(board, version)+MAX_SLIDERS(board)+MAX_MOUSE_ANALOGS(board))
{
eepromImportDebug() << QString("OpenTxGeneralData::OpenTxGeneralData(board: %1, version:%2, variant:%3)").arg(board).arg(version).arg(variant);
qCDebug(eepromImport) << QString("OpenTxGeneralData::OpenTxGeneralData(board: %1, version:%2, variant:%3)").arg(board).arg(version).arg(variant);
generalData.version = version;
generalData.variant = variant;

View file

@ -1514,6 +1514,7 @@ void unregisterOpenTxFirmwares()
foreach (Firmware * f, firmwares) {
delete f;
}
unregisterEEpromInterfaces();
}
template <class T, class M>

View file

@ -31,10 +31,12 @@
#include "appdata.h"
#include "helpers.h"
#include "modeledit/modeledit.h"
#include "simulatormainwindow.h"
#include "storage/sdcard.h"
#include <QLabel>
#include <QMessageBox>
Stopwatch gStopwatch("global");
const QColor colors[CPN_MAX_CURVES] = {
@ -126,7 +128,11 @@ void populatePhasesCB(QComboBox *b, int value)
b->setCurrentIndex(value + getCurrentFirmware()->getCapability(FlightModes));
}
GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step, bool allowGvars, ModelPanel * panel):
/*
* GVarGroup
*/
GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step, bool allowGvars):
QObject(),
weightGV(weightGV),
weightSB(weightSB),
@ -135,8 +141,7 @@ GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBo
weightCB(weightCB),
weight(weight),
step(step),
lock(true),
panel(panel)
lock(true)
{
if (allowGvars && getCurrentFirmware()->getCapability(Gvars)) {
populateGVCB(*weightCB, weight, model);
@ -200,12 +205,15 @@ void GVarGroup::valuesChanged()
weight = sb->value();
else
weight = round(dsb->value()/step);
if (panel)
emit panel->modified();
emit valueChanged();
}
}
/*
* CurveGroup
*/
CurveGroup::CurveGroup(QComboBox * curveTypeCB, QCheckBox * curveGVarCB, QComboBox * curveValueCB, QSpinBox * curveValueSB, CurveReference & curve, const ModelData & model, unsigned int flags):
QObject(),
curveTypeCB(curveTypeCB),
@ -364,6 +372,10 @@ void CurveGroup::valuesChanged()
}
}
/*
* Helpers
*/
void populateGvarUseCB(QComboBox *b, unsigned int phase)
{
b->addItem(QObject::tr("Own value"));

View file

@ -22,7 +22,6 @@
#define _HELPERS_H_
#include "eeprominterface.h"
#include "modeledit/modeledit.h"
#include <QCheckBox>
#include <QSpinBox>
#include <QTableWidget>
@ -69,7 +68,10 @@ class GVarGroup: public QObject {
Q_OBJECT
public:
GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step=1.0, bool allowGVars=true, ModelPanel * panel=NULL);
GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step=1.0, bool allowGVars=true);
signals:
void valueChanged();
protected slots:
void gvarCBChanged(int);
@ -84,7 +86,6 @@ class GVarGroup: public QObject {
int & weight;
double step;
bool lock;
ModelPanel * panel;
};
#define HIDE_DIFF 0x01
@ -157,26 +158,6 @@ QString getFrSkySrc(int index);
void startSimulation(QWidget * parent, RadioData & radioData, int modelIdx);
template <class T>
QVector<T> findWidgets(QObject * object, const QString & name)
{
QVector<T> result;
QRegExp rx(name.arg("([0-9]+)"));
QList<T> children = object->findChildren<T>();
foreach(T child, children) {
int pos = rx.indexIn(child->objectName());
if (pos >= 0) {
QStringList list = rx.capturedTexts();
int index = list[1].toInt();
if (result.size() <= index) {
result.resize(index+1);
}
result[index] = child;
}
}
return result;
}
// Format a pixmap to fit on the current firmware
QPixmap makePixMap(const QImage & image);

View file

@ -21,6 +21,10 @@
#ifndef _MACROS_H_
#define _MACROS_H_
#define DIM(arr) (sizeof((arr))/sizeof((arr)[0]))
#include <iterator>
// #define DIM(arr) (sizeof((arr))/sizeof((arr)[0]))
// new way for c++11
#define DIM(arr__) ((size_t)(std::end((arr__)) - std::begin((arr__))))
#endif // _MACROS_H_

View file

@ -23,8 +23,8 @@ set(modeledit_SRCS
customfunctions.cpp
# templates.cpp
mixerslistwidget.cpp
node.cpp
edge.cpp
# node.cpp ## node and edge are built in common lib because also used by simulator
# edge.cpp ## commenting them here avoids a "duplicate target" warning eg. from ninja
)
set(modeledit_HDRS
@ -36,7 +36,7 @@ set(modeledit_HDRS
customfunctions.h
# templates.h
mixerslistwidget.h
node.h
# node.h
)
set(modeledit_UIS

View file

@ -64,7 +64,8 @@ LimitsGroup::LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row
horizontalLayout->addWidget(cb);
horizontalLayout->addWidget(spinbox);
tableLayout->addLayout(row, col, horizontalLayout);
gvarGroup = new GVarGroup(gv, spinbox, cb, value, model, deflt, min, max, displayStep, allowGVars, panel);
gvarGroup = new GVarGroup(gv, spinbox, cb, value, model, deflt, min, max, displayStep, allowGVars);
QObject::connect(gvarGroup, &GVarGroup::valueChanged, panel, &ModelPanel::modified);
}
LimitsGroup::~LimitsGroup()

View file

@ -71,7 +71,7 @@ DebugOutput::DebugOutput(QWidget * parent, SimulatorInterface *simulator):
ui->filterText->addItem(fltr, "no_delete");
ui->filterText->setValidator(new DebugOutputFilterValidator(ui->filterText));
ui->filterText->installEventFilter(new DeleteComboBoxItemEventFilter());
ui->filterText->installEventFilter(new DeleteComboBoxItemEventFilter(this));
ui->actionShowFilterHelp->setIcon(SimulatorIcon("info"));
ui->actionWordWrap->setIcon(SimulatorIcon("word_wrap"));
@ -115,6 +115,7 @@ DebugOutput::DebugOutput(QWidget * parent, SimulatorInterface *simulator):
DebugOutput::~DebugOutput()
{
m_simulator->installTraceHook(NULL);
saveState();
if (AppDebugMessageHandler::instance())
@ -173,15 +174,18 @@ void DebugOutput::restoreState()
void DebugOutput::processBytesReceived()
{
static char buf[512];
const QTextCursor savedCursor(ui->console->textCursor());
const int sbValue = ui->console->verticalScrollBar()->value();
const bool sbAtBottom = (sbValue == ui->console->verticalScrollBar()->maximum());
qint64 len;
QString text;
while ((len = m_dataBufferDevice->bytesAvailable()) > 0) {
QString text(m_dataBufferDevice->read(qMin(len, qint64(512))));
if (text.isEmpty())
while (m_dataBufferDevice && m_dataBufferDevice->bytesAvailable() > 0) {
len = m_dataBufferDevice->read(buf, sizeof(buf));
if (len <= 0)
break;
text = QString::fromLocal8Bit(buf, len);
ui->console->moveCursor(QTextCursor::End);
ui->console->textCursor().insertText(text);
if (sbAtBottom) {

View file

@ -29,14 +29,15 @@
#include <QValidator>
#include <QWidget>
// NOTE : The buffer sizes need to be large enough to handle the flood of data when X12/X10 simulator starts up (almost 40K!).
// NOTE : The buffer sizes need to be large enough to handle the flood of data when X12/X10 simulator starts up with TRACE_SIMPGMSPACE=1 (> 40K!).
// These are maximum sizes, not necessarily allocated sizes.
#ifndef DEBUG_OUTPUT_WIDGET_OUT_BUFF_SIZE
// This buffer holds received and processed data until it can be printed to our console.
#define DEBUG_OUTPUT_WIDGET_OUT_BUFF_SIZE (40 * 1024) // [bytes]
#define DEBUG_OUTPUT_WIDGET_OUT_BUFF_SIZE (50 * 1024) // [bytes]
#endif
#ifndef DEBUG_OUTPUT_WIDGET_INP_BUFF_SIZE
// This buffer is active if line filter is enabled and holds received data until it can be filtered and placed in output buffer.
#define DEBUG_OUTPUT_WIDGET_INP_BUFF_SIZE (30 * 1024) // [bytes]
#define DEBUG_OUTPUT_WIDGET_INP_BUFF_SIZE (50 * 1024) // [bytes]
#endif
namespace Ui {
@ -101,6 +102,8 @@ class DebugOutputFilterValidator : public QValidator
class DeleteComboBoxItemEventFilter : public QObject
{
Q_OBJECT
public:
DeleteComboBoxItemEventFilter(QObject *parent = Q_NULLPTR) : QObject(parent) { }
protected:
bool eventFilter(QObject *obj, QEvent *event);
};

View file

@ -33,6 +33,8 @@
#endif
#include <QDebug>
#include <QLabel>
#include <QMessageBox>
extern AppData g; // ensure what "g" means

View file

@ -38,6 +38,7 @@
#endif
#include <QFile>
#include <QMessageBox>
#include <iostream>
SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface *simulator, quint8 flags):
@ -99,6 +100,7 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface *simulator
keymapHelp.append(item);
ui->radioUiWidget->layout()->removeItem(ui->radioUiTempSpacer);
delete ui->radioUiTempSpacer;
ui->radioUiWidget->layout()->addWidget(radioUiWidget);
radioUiWidget->setFocusPolicy(Qt::WheelFocus);
radioUiWidget->setFocus();

View file

@ -26,6 +26,7 @@
#include "radiodata.h"
#include "simulator.h"
#include <QTimer>
#include <QWidget>
#include <QVector>

View file

@ -31,12 +31,12 @@ TelemetrySimulator::TelemetrySimulator(QWidget * parent, SimulatorInterface * si
{
ui->setupUi(this);
timer = new QTimer(this);
timer->setInterval(10);
connect(timer, SIGNAL(timeout()), this, SLOT(onTimerEvent()));
setupDataFields();
logTimer = new QTimer(this);
connect(logTimer, SIGNAL(timeout()), this, SLOT(onLogTimerEvent()));
timer.setInterval(10);
connect(&timer, &QTimer::timeout, this, &TelemetrySimulator::generateTelemetryFrame);
connect(&logTimer, &QTimer::timeout, this, &TelemetrySimulator::onLogTimerEvent);
connect(ui->Simulate, SIGNAL(toggled(bool)), this, SLOT(onSimulateToggled(bool)));
connect(ui->loadLogFile, SIGNAL(released()), this, SLOT(onLoadLogFile()));
@ -64,33 +64,27 @@ TelemetrySimulator::TelemetrySimulator(QWidget * parent, SimulatorInterface * si
TelemetrySimulator::~TelemetrySimulator()
{
timer->stop();
logTimer->stop();
timer.stop();
logTimer.stop();
delete logPlayback;
delete ui;
}
void TelemetrySimulator::onSimulateToggled(bool isChecked)
{
if (isChecked) {
timer->start();
timer.start();
}
else {
timer->stop();
timer.stop();
}
}
void TelemetrySimulator::onLogTimerEvent()
{
logPlayback->stepForward(false);
}
void TelemetrySimulator::onTimerEvent()
{
generateTelemetryFrame();
}
void TelemetrySimulator::onLoadLogFile()
{
onStop(); // in case we are in playback mode
@ -100,7 +94,7 @@ void TelemetrySimulator::onLoadLogFile()
void TelemetrySimulator::onPlay()
{
if (logPlayback->isReady()) {
logTimer->start(logPlayback->logFrequency * 1000 / SPEEDS[ui->replayRate->value()]);
logTimer.start(logPlayback->logFrequency * 1000 / SPEEDS[ui->replayRate->value()]);
logPlayback->play();
}
}
@ -108,7 +102,7 @@ void TelemetrySimulator::onPlay()
void TelemetrySimulator::onRewind()
{
if (logPlayback->isReady()) {
logTimer->stop();
logTimer.stop();
logPlayback->rewind();
}
}
@ -116,7 +110,7 @@ void TelemetrySimulator::onRewind()
void TelemetrySimulator::onStepForward()
{
if (logPlayback->isReady()) {
logTimer->stop();
logTimer.stop();
logPlayback->stepForward(true);
}
}
@ -124,7 +118,7 @@ void TelemetrySimulator::onStepForward()
void TelemetrySimulator::onStepBack()
{
if (logPlayback->isReady()) {
logTimer->stop();
logTimer.stop();
logPlayback->stepBack();
}
}
@ -132,7 +126,7 @@ void TelemetrySimulator::onStepBack()
void TelemetrySimulator::onStop()
{
if (logPlayback->isReady()) {
logTimer->stop();
logTimer.stop();
logPlayback->stop();
}
}
@ -147,21 +141,21 @@ void TelemetrySimulator::onPositionIndicatorChanged(int value)
void TelemetrySimulator::onReplayRateChanged(int value)
{
if (logTimer->isActive()) {
logTimer->setInterval(logPlayback->logFrequency * 1000 / SPEEDS[ui->replayRate->value()]);
if (logTimer.isActive()) {
logTimer.setInterval(logPlayback->logFrequency * 1000 / SPEEDS[ui->replayRate->value()]);
}
}
void TelemetrySimulator::closeEvent(QCloseEvent *event)
{
timer->stop();
logTimer->stop();
timer.stop();
logTimer.stop();
event->accept();
}
#define SET_INSTANCE(control, id, def) ui->control->setText(QString::number(simulator->getSensorInstance(id, ((def) & 0x1F) + 1)))
void TelemetrySimulator::showEvent(QShowEvent *event)
void TelemetrySimulator::setupDataFields()
{
SET_INSTANCE(rxbt_inst, BATT_ID, 0);
SET_INSTANCE(rssi_inst, RSSI_ID, 24);
@ -410,7 +404,7 @@ void TelemetrySimulator::generateTelemetryFrame()
if (ok && (buffer[2] || buffer[3]))
simulator->sendTelemetry(buffer, FRSKY_SPORT_PACKET_SIZE);
else
onTimerEvent();
generateTelemetryFrame();
}
uint32_t TelemetrySimulator::FlvssEmulator::encodeCellPair(uint8_t cellNum, uint8_t firstCellNo, double cell1, double cell2)

View file

@ -49,9 +49,9 @@ class TelemetrySimulator : public QWidget
protected slots:
virtual void closeEvent(QCloseEvent *event);
virtual void showEvent(QShowEvent *event);
void setupDataFields();
void onSimulateToggled(bool isChecked);
void onTimerEvent();
void generateTelemetryFrame();
void onLogTimerEvent();
void onLoadLogFile();
void onPlay();
@ -65,10 +65,9 @@ class TelemetrySimulator : public QWidget
protected:
Ui::TelemetrySimulator * ui;
QTimer * timer;
QTimer * logTimer;
QTimer timer;
QTimer logTimer;
SimulatorInterface *simulator;
void generateTelemetryFrame();
// protected classes follow

View file

@ -26,10 +26,15 @@
#include <QPainter>
#include <QClipboard>
#include <QDir>
#include <QElapsedTimer>
#include <QMutex>
#include <QMutexLocker>
#include "appdata.h"
#include "appdebugmessagehandler.h"
#define LCD_WIDGET_REFRESH_PERIOD 16 // [ms] 16 = 62.5fps
class LcdWidget : public QWidget
{
Q_OBJECT
@ -39,7 +44,7 @@ class LcdWidget : public QWidget
LcdWidget(QWidget * parent = 0):
QWidget(parent),
lcdBuf(NULL),
previousBuf(NULL),
localBuf(NULL),
lightEnable(false),
bgDefaultColor(QColor(198, 208, 199))
{
@ -47,8 +52,8 @@ class LcdWidget : public QWidget
~LcdWidget()
{
if (previousBuf) {
free(previousBuf);
if (localBuf) {
free(localBuf);
}
}
@ -62,8 +67,9 @@ class LcdWidget : public QWidget
lcdSize = (width * height) * ((depth+7) / 8);
else
lcdSize = (width * ((height+7)/8)) * depth;
previousBuf = (unsigned char *)malloc(lcdSize);
memset(previousBuf, 0, lcdSize);
localBuf = (unsigned char *)malloc(lcdSize);
memset(localBuf, 0, lcdSize);
}
void setBgDefaultColor(const QColor & color)
@ -102,10 +108,12 @@ class LcdWidget : public QWidget
void onLcdChanged(bool light)
{
if (light != lightEnable || memcmp(previousBuf, lcdBuf, lcdSize)) {
QMutexLocker locker(&lcdMtx);
lightEnable = light;
memcpy(previousBuf, lcdBuf, lcdSize);
memcpy(localBuf, lcdBuf, lcdSize);
if (!redrawTimer.isValid() || redrawTimer.hasExpired(LCD_WIDGET_REFRESH_PERIOD)) {
update();
redrawTimer.start();
}
}
@ -117,24 +125,26 @@ class LcdWidget : public QWidget
int lcdSize;
unsigned char *lcdBuf;
unsigned char *previousBuf;
unsigned char *localBuf;
bool lightEnable;
QColor bgColor;
QColor bgDefaultColor;
QMutex lcdMtx;
QElapsedTimer redrawTimer;
inline void doPaint(QPainter & p)
{
QRgb rgb;
uint16_t z;
if (!lcdBuf)
if (!localBuf)
return;
if (lcdDepth == 16) {
for (int x = 0; x < lcdWidth; x++) {
for (int y = 0; y < lcdHeight; y++) {
z = ((uint16_t *)lcdBuf)[y * lcdWidth + x];
z = ((uint16_t *)localBuf)[y * lcdWidth + x];
rgb = qRgb(255 * ((z & 0xF800) >> 11) / 0x1F,
255 * ((z & 0x07E0) >> 5) / 0x3F,
255 * (z & 0x001F) / 0x1F);
@ -147,7 +157,7 @@ class LcdWidget : public QWidget
if (lcdDepth == 12) {
for (int x = 0; x < lcdWidth; x++) {
for (int y = 0; y < lcdHeight; y++) {
z = ((uint16_t *)lcdBuf)[y * lcdWidth + x];
z = ((uint16_t *)localBuf)[y * lcdWidth + x];
rgb = qRgb(255 * ((z & 0xF00) >> 8) / 0x0F,
255 * ((z & 0x0F0) >> 4) / 0x0F,
255 * (z & 0x00F) / 0x0F);
@ -181,12 +191,12 @@ class LcdWidget : public QWidget
mask = (1 << (y % 8));
for (int x = 0; x < lcdWidth; x++, idx++) {
if (lcdDepth == 1) {
if (lcdBuf[idx] & mask)
if (localBuf[idx] & mask)
p.drawRect(2 * x, 2 * y, 1, 1);
continue;
}
// lcdDepth == 4
z = (y & 1) ? (lcdBuf[idx] >> 4) : (lcdBuf[idx] & 0x0F);
z = (y & 1) ? (localBuf[idx] >> 4) : (localBuf[idx] & 0x0F);
if (!z)
continue;
if (z != previousDepth) {

View file

@ -34,6 +34,7 @@
#include "appdata.h"
#include "appdebugmessagehandler.h"
#include "constants.h"
#include "customdebug.h"
#include "eeprominterface.h"
#include "simulator.h"
#include "simulatormainwindow.h"
@ -95,6 +96,8 @@ int main(int argc, char *argv[])
if (AppDebugMessageHandler::instance())
AppDebugMessageHandler::instance()->installAppMessageHandler();
CustomDebug::setFilterRules();
g.init();
QTranslator companionTranslator;
@ -257,6 +260,7 @@ int finish(int exitCode)
qDebug() << "SIMULATOR EXIT" << exitCode;
unregisterSimulators();
unregisterOpenTxFirmwares();
unregisterStorageFactories();
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
SDL_Quit();

View file

@ -24,6 +24,8 @@
#include "helpers.h"
#include "storage.h"
#include <QFile>
#define FW_MARK "FW"
#define VERS_MARK "VERS"
#define DATE_MARK "DATE"

View file

@ -64,6 +64,12 @@ void registerStorageFactories()
registerStorageFactory(new SdcardStorageFactory());
}
void unregisterStorageFactories()
{
foreach (StorageFactory * factory, registeredStorageFactories)
delete factory;
}
bool Storage::load(RadioData & radioData)
{
QFile file(filename);
@ -72,29 +78,36 @@ bool Storage::load(RadioData & radioData)
return false;
}
bool ret = false;
foreach(StorageFactory * factory, registeredStorageFactories) {
StorageFormat * format = factory->instance(filename);
if (format->load(radioData)) {
board = format->getBoard();
setWarning(format->warning());
return true;
ret = true;
break;
}
else {
setError(format->error());
}
delete format;
}
return false;
return ret;
}
bool Storage::write(const RadioData & radioData)
{
bool ret = false;
foreach(StorageFactory * factory, registeredStorageFactories) {
if (factory->probe(filename)) {
return factory->instance(filename)->write(radioData);
StorageFormat * format = factory->instance(filename);
ret = format->write(radioData);
delete format;
break;
}
}
return false;
return ret;
}
bool convertEEprom(const QString & sourceEEprom, const QString & destinationEEprom, const QString & firmwareFilename)

View file

@ -48,7 +48,7 @@ class StorageFormat
board(Board::BOARD_UNKNOWN)
{
}
virtual ~StorageFormat() {}
virtual bool load(RadioData & radioData) = 0;
virtual bool write(const RadioData & radioData) = 0;
@ -104,6 +104,7 @@ class StorageFactory
StorageFactory()
{
}
virtual ~StorageFactory() {}
virtual QString name() = 0;
virtual bool probe(const QString & filename) = 0;
virtual StorageFormat * instance(const QString & filename) = 0;
@ -145,7 +146,7 @@ class Storage : public StorageFormat
{
}
virtual QString name() { return "storage"; };
virtual QString name() { return "storage"; }
void setError(const QString & error)
{
@ -162,6 +163,7 @@ class Storage : public StorageFormat
};
void registerStorageFactories();
void unregisterStorageFactories();
#if 0
unsigned long LoadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index);

View file

@ -40,19 +40,6 @@ uint8_t getStickMode()
return limit<uint8_t>(0, g_eeGeneral.stickMode, 3);
}
#if defined(PCBTARANIS)
void resetTrims()
{
TRIMS_GPIO_REG_RVD |= TRIMS_GPIO_PIN_RVD;
TRIMS_GPIO_REG_RVU |= TRIMS_GPIO_PIN_RVU;
TRIMS_GPIO_REG_RHL |= TRIMS_GPIO_PIN_RHL;
TRIMS_GPIO_REG_RHR |= TRIMS_GPIO_PIN_RHR;
TRIMS_GPIO_REG_LVD |= TRIMS_GPIO_PIN_LVD;
TRIMS_GPIO_REG_LVU |= TRIMS_GPIO_PIN_LVU;
TRIMS_GPIO_REG_LHL |= TRIMS_GPIO_PIN_LHL;
TRIMS_GPIO_REG_LHR |= TRIMS_GPIO_PIN_LHR;
}
#endif
OpenTxSimulator::OpenTxSimulator()
{
@ -96,11 +83,8 @@ void OpenTxSimulator::start(QByteArray & ee, bool tests)
void OpenTxSimulator::start(const char * filename, bool tests)
{
#if defined(ROTARY_ENCODER_NAVIGATION)
for (uint8_t i=0; i<DIM(rotencValue); i++) {
rotencValue[i] = 0;
}
#endif
if (main_thread_running)
return;
StartEepromThread(filename);
StartAudioThread(volumeGain);
@ -109,6 +93,9 @@ void OpenTxSimulator::start(const char * filename, bool tests)
void OpenTxSimulator::stop()
{
if (!main_thread_running)
return;
StopSimu();
#if defined(CPUARM)
StopAudioThread();

View file

@ -23,7 +23,7 @@
#include <stdarg.h>
#include <string>
#if !defined _MSC_VER || defined __GNUC__
#if !defined (_MSC_VER) || defined (__GNUC__)
#include <chrono>
#include <sys/time.h>
#endif
@ -135,6 +135,13 @@ void simuInit()
simuSetSwitch(i, 0);
simuSetKey(i, false); // a little dirty, but setting keys that don't exist is perfectly OK here
}
for (int i=0; i<(NUM_STICKS+NUM_AUX_TRIMS)*2; i++)
simuSetTrim(i, false);
#if defined(ROTARY_ENCODER_NAVIGATION)
for (uint8_t i=0; i<DIM(rotencValue); i++)
rotencValue[i] = 0;
#endif
}
#define NEG_CASE(sw_or_key, pin, mask) \
@ -216,9 +223,9 @@ void simuSetKey(uint8_t key, bool state)
KEY_CASE(KEY_UP, KEYS_GPIO_REG_UP, KEYS_GPIO_PIN_UP)
KEY_CASE(KEY_DOWN, KEYS_GPIO_REG_DOWN, KEYS_GPIO_PIN_DOWN)
#endif
#if defined(PCBSKY9X) && !defined(REVX) && !defined(AR9X)
#if defined(PCBSKY9X) && !defined(REVX) && !defined(AR9X) && defined(ROTARY_ENCODERS)
KEY_CASE(BTN_REa, PIOB->PIO_PDSR, 0x40)
#elif defined(PCBGRUVIN9X) || defined(PCBMEGA2560)
#elif (defined(PCBGRUVIN9X) || defined(PCBMEGA2560)) && (defined(ROTARY_ENCODERS) || defined(ROTARY_ENCODER_NAVIGATION))
KEY_CASE(BTN_REa, pind, 0x20)
#elif defined(PCB9X) && defined(ROTARY_ENCODER_NAVIGATION)
KEY_CASE(BTN_REa, RotEncoder, 0x20)
@ -337,6 +344,9 @@ void simuSetSwitch(uint8_t swtch, int8_t state)
void StartSimu(bool tests, const char * sdPath, const char * settingsPath)
{
if (main_thread_running)
return;
s_current_protocol[0] = 255;
menuLevel = 0;
@ -380,6 +390,9 @@ void StartSimu(bool tests, const char * sdPath, const char * settingsPath)
void StopSimu()
{
if (!main_thread_running)
return;
main_thread_running = 0;
#if defined(CPUARM)
@ -525,6 +538,7 @@ void StartAudioThread(int volumeGain)
simuAudio.leftoverLen = 0;
simuAudio.threadRunning = true;
simuAudio.volumeGain = volumeGain;
TRACE_SIMPGMSPACE("StartAudioThread(%d)", volumeGain);
setScaledVolume(VOLUME_LEVEL_DEF);
pthread_attr_t attr;
@ -569,12 +583,17 @@ void lcdOff()
void lcdRefresh()
{
static bool lightEnabled = (bool)isBacklightEnabled();
#if defined(PCBFLAMENCO)
TW8823_SendScreen();
#endif
memcpy(simuLcdBuf, displayBuf, sizeof(simuLcdBuf));
if ((bool(isBacklightEnabled()) != lightEnabled) || memcmp(simuLcdBuf, displayBuf, DISPLAY_BUFFER_SIZE)) {
memcpy(simuLcdBuf, displayBuf, DISPLAY_BUFFER_SIZE);
lightEnabled = (bool)isBacklightEnabled();
simuLcdRefresh = true;
}
}
void telemetryPortInit(uint8_t baudrate)

View file

@ -28,7 +28,7 @@ uint8_t * eeprom_buffer_data;
volatile int32_t eeprom_buffer_size;
bool eeprom_read_operation;
bool eeprom_thread_running = true;
bool eeprom_thread_running = false;
#if defined(EEPROM_SIZE)
uint8_t eeprom[EEPROM_SIZE];
@ -154,6 +154,7 @@ void StartEepromThread(const char * filename)
if (!fp)
perror("error in fopen");
}
#ifdef __APPLE__
eeprom_write_sem = sem_open("eepromsem", O_CREAT, S_IRUSR | S_IWUSR, 0);
#else
@ -161,8 +162,10 @@ void StartEepromThread(const char * filename)
sem_init(eeprom_write_sem, 0, 0);
#endif
if (!pthread_create(&eeprom_thread_pid, NULL, &eeprom_thread_function, NULL))
eeprom_thread_running = true;
pthread_create(&eeprom_thread_pid, NULL, &eeprom_thread_function, NULL);
else
perror("Could not create eeprom thread.");
}
void StopEepromThread()
@ -178,5 +181,6 @@ void StopEepromThread()
free(eeprom_write_sem);
#endif
if (fp) fclose(fp);
if (fp)
fclose(fp);
}

View file

@ -97,8 +97,8 @@ void simuFatfsSetPaths(const char * sdPath, const char * settingsPath)
if (settingsPath) {
simuSettingsDirectory = removeTrailingPathDelimiter(fixPathDelimiters(settingsPath));
}
TRACE_SIMPGMSPACE("simuFatfsSetPaths(): simuSdDirectory: \"\"", simuSdDirectory.c_str());
TRACE_SIMPGMSPACE("simuFatfsSetPaths(): simuSettingsDirectory: \"\"", simuSettingsDirectory.c_str());
TRACE_SIMPGMSPACE("simuFatfsSetPaths(): simuSdDirectory: \"%s\"", simuSdDirectory.c_str());
TRACE_SIMPGMSPACE("simuFatfsSetPaths(): simuSettingsDirectory: \"%s\"", simuSettingsDirectory.c_str());
}
bool startsWith(const char *path, const char * start)