188 lines
4.9 KiB
C++
188 lines
4.9 KiB
C++
/*
|
||
* ParametersStorage.hpp
|
||
*
|
||
* Created on: 19 февр. 2021 г.
|
||
* Author: titov
|
||
*/
|
||
|
||
#ifndef UMLIBRARY_DRIVER_PARAMETERSSTORAGE_HPP_
|
||
#define UMLIBRARY_DRIVER_PARAMETERSSTORAGE_HPP_
|
||
|
||
#include "DataImageStorage.hpp"
|
||
|
||
#include "../peripheral/ProtectedMemory.hh"
|
||
#include "../systemic/SharedData.hh"
|
||
|
||
#include <memory_resource>
|
||
#include <deque>
|
||
|
||
namespace driver {
|
||
|
||
template<class DataImage>
|
||
class ParametersStorage : public DataImageStorage<DataImage> {
|
||
public:
|
||
|
||
typedef driver::IParamStorage::Id Id;
|
||
|
||
ParametersStorage( peripheral::IMemoryAccess & persistent,
|
||
peripheral::protected_char * buff, std::size_t buff_size, std::pmr::memory_resource * task_buffer_memory );
|
||
|
||
bool flushParameterBuff( Id parameter_id );
|
||
|
||
void process();
|
||
|
||
private:
|
||
std::deque< Id, std::pmr::polymorphic_allocator<Id> > tasks;
|
||
|
||
struct ParameterState {
|
||
enum Id {
|
||
Idle,
|
||
StartWriteOnce,
|
||
WaitWriteOnce,
|
||
UpdateCrc,
|
||
StartWriteCrc,
|
||
WaitWriteCrc,
|
||
PrepareReadOnce,
|
||
StartReadOnce,
|
||
WaitReadOnce,
|
||
};
|
||
};
|
||
|
||
typename ParameterState::Id parameter_state;
|
||
|
||
};
|
||
|
||
}
|
||
|
||
template<class DataImage>
|
||
driver::ParametersStorage<DataImage>::ParametersStorage(
|
||
peripheral::IMemoryAccess & persistent, peripheral::protected_char * buff,
|
||
std::size_t buff_size, std::pmr::memory_resource * task_buffer_memory ) : DataImageStorage<DataImage>(persistent, buff, buff_size),
|
||
tasks(task_buffer_memory), parameter_state(ParameterState::Idle) {}
|
||
|
||
template<class DataImage>
|
||
bool driver::ParametersStorage<DataImage>::flushParameterBuff(
|
||
Id parameter_id ) {
|
||
|
||
if( not DataImageStorage<DataImage>::data_ready or not DataImageStorage<DataImage>::image.show_setting_data_buff(parameter_id) )
|
||
return false;
|
||
|
||
tasks.push_back(parameter_id);
|
||
|
||
DataImageStorage<DataImage>::data_stored = false;
|
||
|
||
return true;
|
||
|
||
}
|
||
|
||
template<class DataImage>
|
||
void driver::ParametersStorage<DataImage>::process() {
|
||
|
||
DataImageStorage<DataImage>::process();
|
||
|
||
char * buff = DataImageStorage<DataImage>::buff;
|
||
bool & data_stored = DataImageStorage<DataImage>::data_stored;
|
||
DataImage & image = DataImageStorage<DataImage>::image;
|
||
peripheral::IMemoryAccess & memory = DataImageStorage<DataImage>::memory;
|
||
|
||
if( not DataImageStorage<DataImage>::isMemoryProcessing() ) switch(parameter_state) {
|
||
case ParameterState::Idle: {
|
||
|
||
if( not tasks.empty() ) {
|
||
|
||
parameter_state = ParameterState::StartWriteOnce;
|
||
}
|
||
|
||
} break;
|
||
case ParameterState::StartWriteOnce: {
|
||
|
||
Id parameter = tasks.front();
|
||
|
||
std::pair<char *, std::size_t> par_buff = image.show_setting( parameter );
|
||
|
||
if( memory.write( par_buff.first, par_buff.first - buff, par_buff.second ) )
|
||
parameter_state = ParameterState::WaitWriteOnce;
|
||
|
||
} break;
|
||
case ParameterState::WaitWriteOnce: {
|
||
|
||
if( memory.isWriteComplete() ) {
|
||
|
||
parameter_state = ParameterState::UpdateCrc;
|
||
|
||
}
|
||
|
||
} break;
|
||
case ParameterState::UpdateCrc: {
|
||
|
||
Id parameter = tasks.front();
|
||
|
||
std::pair<char *, std::size_t> crc_buff = image.show_setting_crc( parameter );
|
||
|
||
if( peripheral::write_lock( crc_buff.first, crc_buff.second ) ) {
|
||
|
||
image.update_data_crc( parameter );
|
||
|
||
peripheral::write_unlock( crc_buff.first, crc_buff.second );
|
||
|
||
parameter_state = ParameterState::StartWriteCrc;
|
||
}
|
||
|
||
} break;
|
||
case ParameterState::StartWriteCrc: {
|
||
|
||
Id parameter = tasks.front();
|
||
|
||
std::pair<char *, std::size_t> crc_buff = image.show_setting_crc( parameter );
|
||
|
||
if( memory.write( crc_buff.first, crc_buff.first - buff, crc_buff.second ) )
|
||
parameter_state = ParameterState::WaitWriteCrc;
|
||
|
||
} break;
|
||
case ParameterState::WaitWriteCrc: {
|
||
|
||
if( memory.isWriteComplete() ) {
|
||
|
||
parameter_state = ParameterState::StartReadOnce;
|
||
}
|
||
|
||
} break;
|
||
case ParameterState::PrepareReadOnce: {
|
||
|
||
Id parameter = tasks.front();
|
||
|
||
std::pair<char *, std::size_t> par_buff = image.show_setting( parameter );
|
||
|
||
} break;
|
||
case ParameterState::StartReadOnce: {
|
||
|
||
Id parameter = tasks.front();
|
||
|
||
std::pair<char *, std::size_t> par_buff = image.show_setting( parameter );
|
||
|
||
if( memory.read( par_buff.first, par_buff.first - buff, par_buff.second ) )
|
||
parameter_state = ParameterState::WaitReadOnce;
|
||
|
||
} break;
|
||
case ParameterState::WaitReadOnce: {
|
||
|
||
Id parameter = tasks.front();
|
||
|
||
if( memory.isReadComplete() ) {
|
||
|
||
if( image.check_data_crc(parameter) )
|
||
tasks.pop_front();
|
||
|
||
parameter_state = ParameterState::Idle;
|
||
|
||
if( tasks.empty() )
|
||
data_stored = true;
|
||
}
|
||
|
||
} break;
|
||
}
|
||
|
||
}
|
||
|
||
#endif /* UMLIBRARY_DRIVER_PARAMETERSSTORAGE_HPP_ */
|