284 lines
6.4 KiB
C++
284 lines
6.4 KiB
C++
/*
|
|
* DataImageStorage.hpp
|
|
*
|
|
* Created on: 16 ôåâð. 2021 ã.
|
|
* Author: titov
|
|
*/
|
|
|
|
#ifndef UMLIBRARY_DRIVER_DATAIMAGESTORAGE_HPP_
|
|
#define UMLIBRARY_DRIVER_DATAIMAGESTORAGE_HPP_
|
|
|
|
#include "../systemic/IParameterProvider.hh"
|
|
#include "../systemic/IProcess.hh"
|
|
|
|
#include "../peripheral/IMemoryAccess.hh"
|
|
|
|
#include "IParamStorage.hh"
|
|
|
|
#include <cstddef>
|
|
#include <stdint.h>
|
|
|
|
namespace driver {
|
|
|
|
template<class DataImage>
|
|
class DataImageStorage : public systemic::IProcess, public driver::IParamStorage {
|
|
public:
|
|
typedef DataImage Image;
|
|
|
|
DataImageStorage( peripheral::IMemoryAccess & persistent,
|
|
peripheral::protected_char * buff, std::size_t buff_size );
|
|
void process();
|
|
|
|
systemic::SharedData createParameterBuff( Id parameter_id, std::size_t size );
|
|
systemic::SharedData getParameterBuff( Id parameter_id ) const;
|
|
|
|
//!Äàííàÿ ðåàëèçàöèÿ íå ïîääåðæèâàåò âîçìîæíîñòü ñîõðàíåíèÿ îòäåëüíûõ ïàðàìåòðîâ.
|
|
bool flushParameterBuff( Id parameter_id ) { return false; }
|
|
|
|
void flush();
|
|
void load();
|
|
void clear();
|
|
|
|
bool isDataSync() const;
|
|
bool isCrcError() const;
|
|
|
|
virtual ~DataImageStorage() = default;
|
|
|
|
static const std::size_t align = alignof(long double);
|
|
|
|
protected:
|
|
peripheral::IMemoryAccess & memory; //!<Óêàçàòåëü íà èíòåðôåéñ ðàáîòû ñ ïàìÿòüþ
|
|
|
|
peripheral::protected_char * const buff; //!<Áóôåð äëÿ ðàáîòû ñ äàííûìè õðàíèìûìè â ïàìÿòè.
|
|
const std::size_t buff_size; //!<Ðàçìåð áóôåðà.
|
|
|
|
Image image; //!<Îáðàç äàííûõ.
|
|
|
|
struct State {
|
|
enum Id {
|
|
Idle,
|
|
UpdateCrc,
|
|
StartWrite,
|
|
WaitWrite,
|
|
StartReadHead,
|
|
WaitReadHead,
|
|
StartReadEnd,
|
|
WaitReadEnd,
|
|
DataImageReset,
|
|
};
|
|
};
|
|
|
|
typename State::Id state;
|
|
|
|
bool crc_error; //!<Îøèáêà êîíòðîëüíîé ñóììû äàííûõ, íåâîçìîæíî âîññòàíîâèòü.
|
|
bool data_ready; //!<Ñòðóêòóðà äàííûõ â ÎÇÓ çàãðóæåíà èç ÏÇÓ.
|
|
bool data_stored; //!<Ñòðóêòóðà äàííûõ â ÏÇÓ çàãðóæåíà èç ÎÇÓ.
|
|
|
|
bool isMemoryProcessing() const;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
template<class DataImage>
|
|
inline driver::DataImageStorage<DataImage>::DataImageStorage(
|
|
peripheral::IMemoryAccess & persistent, char * buff,
|
|
std::size_t buff_size ) : memory(persistent), buff(buff), buff_size(buff_size), state(State::StartReadHead),
|
|
crc_error(false), data_ready(false), data_stored(true) {}
|
|
|
|
template<class DataImage>
|
|
inline void driver::DataImageStorage<DataImage>::process() {
|
|
|
|
switch(state) {
|
|
case State::UpdateCrc: {
|
|
|
|
if( peripheral::write_lock( buff, buff_size ) ) {
|
|
|
|
image.update_crc();
|
|
|
|
peripheral::write_unlock( buff, buff_size );
|
|
|
|
state = State::StartWrite;
|
|
}
|
|
|
|
} break;
|
|
case State::StartWrite: {
|
|
|
|
if( memory.write( buff, 0, image.get_image_size() ) )
|
|
state = State::WaitWrite;
|
|
|
|
} break;
|
|
case State::WaitWrite: {
|
|
|
|
if( memory.isWriteComplete() )
|
|
state = State::StartReadEnd;
|
|
|
|
} break;
|
|
case State::StartReadHead: {
|
|
|
|
if( memory.read( buff, 0, sizeof(typename Image::Head) ) )
|
|
state = State::WaitReadHead;
|
|
|
|
} break;
|
|
case State::WaitReadHead: {
|
|
|
|
if( memory.isReadComplete() ) {
|
|
|
|
if( image.build_from_buff(buff, buff_size, align) ) {
|
|
|
|
state = State::StartReadEnd;
|
|
|
|
} else {
|
|
|
|
state = State::DataImageReset;
|
|
|
|
}
|
|
}
|
|
|
|
} break;
|
|
case State::StartReadEnd: {
|
|
|
|
if( memory.read( buff + sizeof(typename Image::Head), sizeof(typename Image::Head), image.get_image_size() - sizeof(typename Image::Head) ) )
|
|
state = State::WaitReadEnd;
|
|
|
|
} break;
|
|
case State::WaitReadEnd: {
|
|
|
|
if( memory.isReadComplete() ) {
|
|
|
|
bool crc_equal = image.check_crc();
|
|
|
|
if( crc_equal ) {
|
|
|
|
data_stored = data_ready = true;
|
|
crc_error = false;
|
|
|
|
state = State::Idle;
|
|
|
|
} else {
|
|
|
|
state = State::DataImageReset;
|
|
|
|
}
|
|
}
|
|
|
|
} break;
|
|
case State::DataImageReset: {
|
|
|
|
if( peripheral::write_lock( buff, buff_size ) ) {
|
|
|
|
image.reset();
|
|
|
|
peripheral::write_unlock( buff, buff_size );
|
|
|
|
data_stored = data_ready = false;
|
|
crc_error = true;
|
|
|
|
state = State::Idle;
|
|
}
|
|
|
|
} break;
|
|
case State::Idle: {} break;
|
|
};
|
|
}
|
|
|
|
template<class DataImage>
|
|
systemic::SharedData driver::DataImageStorage<DataImage>::createParameterBuff(
|
|
Id parameter_id, std::size_t size) {
|
|
|
|
if( isMemoryProcessing() )
|
|
return { nullptr, 0 };
|
|
|
|
std::pair<char *, std::size_t> setting = image.show_setting( parameter_id );
|
|
|
|
if( not setting.first or setting.second != size ) {
|
|
|
|
while( not peripheral::write_lock( buff, buff_size ) );
|
|
|
|
{
|
|
data_ready = not image.change_setting_info( parameter_id, size );
|
|
|
|
peripheral::write_unlock( buff, buff_size );
|
|
|
|
return image.show_setting(parameter_id);
|
|
}
|
|
|
|
}
|
|
|
|
return setting;
|
|
|
|
}
|
|
|
|
template<class DataImage>
|
|
systemic::SharedData driver::DataImageStorage<DataImage>::getParameterBuff(
|
|
Id parameter_id ) const {
|
|
|
|
if( isMemoryProcessing() )
|
|
return { nullptr, 0 };
|
|
|
|
return image.show_setting(parameter_id);
|
|
|
|
}
|
|
|
|
template<class DataImage>
|
|
void driver::DataImageStorage<DataImage>::flush() {
|
|
|
|
if( not isMemoryProcessing() ) {
|
|
|
|
data_stored = crc_error = false;
|
|
|
|
state = State::UpdateCrc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
template<class DataImage>
|
|
void driver::DataImageStorage<DataImage>::load() {
|
|
|
|
if( not isMemoryProcessing() and data_stored ) {
|
|
|
|
data_ready = false;
|
|
|
|
state = State::StartReadHead;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
template<class DataImage>
|
|
void driver::DataImageStorage<DataImage>::clear() {
|
|
|
|
while( not peripheral::write_lock( buff, buff_size ) );
|
|
|
|
image.reset();
|
|
|
|
data_stored = data_ready = false;
|
|
|
|
state = State::Idle;
|
|
|
|
}
|
|
|
|
template<class DataImage>
|
|
bool driver::DataImageStorage<DataImage>::isDataSync() const {
|
|
|
|
return data_ready and data_stored;
|
|
|
|
}
|
|
|
|
template<class DataImage>
|
|
bool driver::DataImageStorage<DataImage>::isCrcError() const {
|
|
|
|
return crc_error;
|
|
|
|
}
|
|
|
|
template<class DataImage>
|
|
bool driver::DataImageStorage<DataImage>::isMemoryProcessing() const {
|
|
|
|
return state != State::Idle;
|
|
|
|
}
|
|
|
|
#endif /* UMLIBRARY_DRIVER_DATAIMAGESTORAGE_HPP_ */
|