Fix: Prevent wrong values of systemconfigpara data because of non-atomic transaction

This commit is contained in:
Thomas Basler 2023-07-31 22:03:31 +02:00
parent 698ecbcd53
commit 74169c3b17
3 changed files with 35 additions and 1 deletions

View File

@ -27,11 +27,13 @@ bool SystemConfigParaCommand::handleResponse(InverterAbstract* inverter, fragmen
// Move all fragments into target buffer // Move all fragments into target buffer
uint8_t offs = 0; uint8_t offs = 0;
inverter->SystemConfigPara()->beginAppendFragment();
inverter->SystemConfigPara()->clearBuffer(); inverter->SystemConfigPara()->clearBuffer();
for (uint8_t i = 0; i < max_fragment_id; i++) { for (uint8_t i = 0; i < max_fragment_id; i++) {
inverter->SystemConfigPara()->appendFragment(offs, fragment[i].fragment, fragment[i].len); inverter->SystemConfigPara()->appendFragment(offs, fragment[i].fragment, fragment[i].len);
offs += (fragment[i].len); offs += (fragment[i].len);
} }
inverter->SystemConfigPara()->endAppendFragment();
inverter->SystemConfigPara()->setLastUpdateRequest(millis()); inverter->SystemConfigPara()->setLastUpdateRequest(millis());
inverter->SystemConfigPara()->setLastLimitRequestSuccess(CMD_OK); inverter->SystemConfigPara()->setLastLimitRequestSuccess(CMD_OK);
return true; return true;

View File

@ -6,6 +6,18 @@
#include "../Hoymiles.h" #include "../Hoymiles.h"
#include <cstring> #include <cstring>
#define HOY_SEMAPHORE_TAKE() \
do { \
} while (xSemaphoreTake(_xSemaphore, portMAX_DELAY) != pdPASS)
#define HOY_SEMAPHORE_GIVE() xSemaphoreGive(_xSemaphore)
SystemConfigParaParser::SystemConfigParaParser()
: Parser()
{
_xSemaphore = xSemaphoreCreateMutex();
HOY_SEMAPHORE_GIVE(); // release before first use
}
void SystemConfigParaParser::clearBuffer() void SystemConfigParaParser::clearBuffer()
{ {
memset(_payload, 0, SYSTEM_CONFIG_PARA_SIZE); memset(_payload, 0, SYSTEM_CONFIG_PARA_SIZE);
@ -22,15 +34,30 @@ void SystemConfigParaParser::appendFragment(uint8_t offset, uint8_t* payload, ui
_payloadLength += len; _payloadLength += len;
} }
void SystemConfigParaParser::beginAppendFragment()
{
HOY_SEMAPHORE_TAKE();
}
void SystemConfigParaParser::endAppendFragment()
{
HOY_SEMAPHORE_GIVE();
}
float SystemConfigParaParser::getLimitPercent() float SystemConfigParaParser::getLimitPercent()
{ {
return ((((uint16_t)_payload[2]) << 8) | _payload[3]) / 10.0; HOY_SEMAPHORE_TAKE();
float ret = ((((uint16_t)_payload[2]) << 8) | _payload[3]) / 10.0;
HOY_SEMAPHORE_GIVE();
return ret;
} }
void SystemConfigParaParser::setLimitPercent(float value) void SystemConfigParaParser::setLimitPercent(float value)
{ {
HOY_SEMAPHORE_TAKE();
_payload[2] = ((uint16_t)(value * 10)) >> 8; _payload[2] = ((uint16_t)(value * 10)) >> 8;
_payload[3] = ((uint16_t)(value * 10)); _payload[3] = ((uint16_t)(value * 10));
HOY_SEMAPHORE_GIVE();
} }
void SystemConfigParaParser::setLastLimitCommandSuccess(LastCommandSuccess status) void SystemConfigParaParser::setLastLimitCommandSuccess(LastCommandSuccess status)

View File

@ -7,8 +7,11 @@
class SystemConfigParaParser : public Parser { class SystemConfigParaParser : public Parser {
public: public:
SystemConfigParaParser();
void clearBuffer(); void clearBuffer();
void appendFragment(uint8_t offset, uint8_t* payload, uint8_t len); void appendFragment(uint8_t offset, uint8_t* payload, uint8_t len);
void beginAppendFragment();
void endAppendFragment();
float getLimitPercent(); float getLimitPercent();
void setLimitPercent(float value); void setLimitPercent(float value);
@ -32,4 +35,6 @@ private:
uint32_t _lastUpdateCommand = 0; uint32_t _lastUpdateCommand = 0;
uint32_t _lastUpdateRequest = 0; uint32_t _lastUpdateRequest = 0;
SemaphoreHandle_t _xSemaphore;
}; };