Fix: Prevent wrong values of statistics data because of non-atomic transaction
This commit is contained in:
parent
9821c1905b
commit
14305a9f12
@ -40,11 +40,13 @@ bool RealTimeRunDataCommand::handleResponse(InverterAbstract* inverter, fragment
|
||||
|
||||
// Move all fragments into target buffer
|
||||
uint8_t offs = 0;
|
||||
inverter->Statistics()->beginAppendFragment();
|
||||
inverter->Statistics()->clearBuffer();
|
||||
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
||||
inverter->Statistics()->appendFragment(offs, fragment[i].fragment, fragment[i].len);
|
||||
offs += (fragment[i].len);
|
||||
}
|
||||
inverter->Statistics()->endAppendFragment();
|
||||
inverter->Statistics()->resetRxFailureCount();
|
||||
inverter->Statistics()->setLastUpdate(millis());
|
||||
return true;
|
||||
|
||||
@ -5,6 +5,11 @@
|
||||
#include "StatisticsParser.h"
|
||||
#include "../Hoymiles.h"
|
||||
|
||||
#define HOY_SEMAPHORE_TAKE() \
|
||||
do { \
|
||||
} while (xSemaphoreTake(_xSemaphore, portMAX_DELAY) != pdPASS)
|
||||
#define HOY_SEMAPHORE_GIVE() xSemaphoreGive(_xSemaphore)
|
||||
|
||||
static float calcYieldTotalCh0(StatisticsParser* iv, uint8_t arg0);
|
||||
static float calcYieldDayCh0(StatisticsParser* iv, uint8_t arg0);
|
||||
static float calcUdcCh(StatisticsParser* iv, uint8_t arg0);
|
||||
@ -28,6 +33,13 @@ const calcFunc_t calcFunctions[] = {
|
||||
{ CALC_IRR_CH, &calcIrradiation }
|
||||
};
|
||||
|
||||
StatisticsParser::StatisticsParser()
|
||||
: Parser()
|
||||
{
|
||||
_xSemaphore = xSemaphoreCreateMutex();
|
||||
HOY_SEMAPHORE_GIVE(); // release before first use
|
||||
}
|
||||
|
||||
void StatisticsParser::setByteAssignment(const byteAssign_t* byteAssignment, uint8_t size)
|
||||
{
|
||||
_byteAssignment = byteAssignment;
|
||||
@ -62,6 +74,16 @@ void StatisticsParser::appendFragment(uint8_t offset, uint8_t* payload, uint8_t
|
||||
_statisticLength += len;
|
||||
}
|
||||
|
||||
void StatisticsParser::beginAppendFragment()
|
||||
{
|
||||
HOY_SEMAPHORE_TAKE();
|
||||
}
|
||||
|
||||
void StatisticsParser::endAppendFragment()
|
||||
{
|
||||
HOY_SEMAPHORE_GIVE();
|
||||
}
|
||||
|
||||
const byteAssign_t* StatisticsParser::getAssignmentByChannelField(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId)
|
||||
{
|
||||
for (uint8_t i = 0; i < _byteAssignmentSize; i++) {
|
||||
@ -98,10 +120,12 @@ float StatisticsParser::getChannelFieldValue(ChannelType_t type, ChannelNum_t ch
|
||||
if (CMD_CALC != div) {
|
||||
// Value is a static value
|
||||
uint32_t val = 0;
|
||||
HOY_SEMAPHORE_TAKE();
|
||||
do {
|
||||
val <<= 8;
|
||||
val |= _payloadStatistic[ptr];
|
||||
} while (++ptr != end);
|
||||
HOY_SEMAPHORE_GIVE();
|
||||
|
||||
float result;
|
||||
if (pos->isSigned && pos->num == 2) {
|
||||
|
||||
@ -104,8 +104,11 @@ typedef struct {
|
||||
|
||||
class StatisticsParser : public Parser {
|
||||
public:
|
||||
StatisticsParser();
|
||||
void clearBuffer();
|
||||
void appendFragment(uint8_t offset, uint8_t* payload, uint8_t len);
|
||||
void beginAppendFragment();
|
||||
void endAppendFragment();
|
||||
|
||||
void setByteAssignment(const byteAssign_t* byteAssignment, uint8_t size);
|
||||
|
||||
@ -146,4 +149,6 @@ private:
|
||||
std::list<fieldSettings_t> _fieldSettings;
|
||||
|
||||
uint32_t _rxFailureCount = 0;
|
||||
|
||||
SemaphoreHandle_t _xSemaphore;
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user