MotorControlModuleSDFM_TMS3.../Projects/EFC_Application/UMLibrary/driver/ParametersStorage.hpp

188 lines
4.8 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_ */