MotorControlModuleSDFM_TMS3.../Projects/EFC_Application/UMLibrary/driver/netx/NetX.hh

302 lines
9.7 KiB
C++
Raw Blame History

/*
* NetX.hh
*
* Created on: 30 <20><><EFBFBD><EFBFBD>. 2021 <20>.
* Author: titov
*/
#ifndef UMLIBRARY_DRIVER_NETX_NETX_HH_
#define UMLIBRARY_DRIVER_NETX_NETX_HH_
#include <utility>
#include <cstring>
#include <functional>
#include <map>
#include <set>
#include <vector>
#include <memory_resource>
#include <stdint.h>
#include "../../peripheral/ProtectedMemory.hh"
#include "../../peripheral/IMemoryAccess.hh"
#include "../../systemic/IProcess.hh"
#include "../../communication/IMessageServer.hh"
#include "../../communication/format/BinaryDataPublisher.hh"
#include "../../communication/format/BinaryDataCollector.hh"
#include "lowcifx/HilscherDualPortMemoryMap.hh"
#include "lowcifx/HilscherPacket.hh"
namespace driver {
namespace netx {
class NetX {
public:
NetX( std::pair<const char *, std::size_t> name,
std::pair<peripheral::protected_char *, std::size_t> dpm );
static bool isReady( peripheral::protected_char * dpm_origin );
bool isReady() const;
bool isError() const;
void reset();
class CommunicationChannel {
public:
enum ChannelId {
CH0, CH1, CH2, CH3
};
typedef uint32_t ErrorCode;
struct Info {
uint16_t id; //!<
uint16_t type; //!<DOC060302DPM17EN, page 84. Table 60: System Channel: Communication Class
uint16_t protocol; //!<DOC060302DPM17EN, page 85-86. Table 61: System Channel: Protocol Class
uint16_t conformance; //!<DOC060302DPM17EN, page 86.
};
struct Mailbox : public systemic::IProcess,
public communication::IMessageRouter {};
CommunicationChannel( std::pmr::memory_resource * description, std::pmr::memory_resource * buffer );
peripheral::IMemoryAccess & cyclic();
communication::IBinaryDataReadEvent & cyclic_read();
communication::IBinaryDataWriteEvent & cyclic_write();
Mailbox & mailbox();
bool isError() const;
bool isRunning() const;
bool isCommunicating() const;
bool isProtocolRegistred() const;
ErrorCode getErrorCode() const;
float getErrorCounter() const;
float getWatchdogCounter() const; //!<
void start();
void stop();
void watchdog(); //!<
Info info() const;
private:
struct HandshakeData : public peripheral::IMemoryAccess,
communication::IBinaryDataReadEvent, communication::IBinaryDataWriteEvent {
bool ready_to_be_read(); //!<
bool view( char * data, std::size_t begin, std::size_t size ); //!<
bool accept(); //!<
bool ready_to_be_written(); //!<
bool set( const char * data, std::size_t begin, std::size_t size ); //!<
bool commit(); //!<
//!<21><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
void read_event( communication::IBinaryDataSubscriber & subscriber );
//!<21><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
void write_event( communication::IBinaryDataIssuer & issuer );
bool read( char * data, std::size_t begin, std::size_t size );
bool write( const char * data, std::size_t begin, std::size_t size );
bool isReadComplete() const;
bool isWriteComplete() const;
std::size_t getCapacity() const;
peripheral::protected_char * input = nullptr;
peripheral::protected_char * output = nullptr;
peripheral::protected_char * handshake = nullptr;
std::size_t capacity = 0;
bool read_complete = false;
bool write_request = false;
const uint16_t read_mask;
const uint16_t write_mask;
HandshakeData( uint16_t read_mask, uint16_t write_mask );
};
HandshakeData pd0_data;
HandshakeData pd1_data;
HandshakeData mb_rec_data;
HandshakeData mb_tx_data;
class MailboxHandler : public Mailbox {
typedef std::map<ServerId, communication::IMessageServer *, std::greater<ServerId>,
std::pmr::polymorphic_allocator<
std::pair<const ServerId, communication::IMessageServer *> > >
Servers;
HandshakeData & receive;
HandshakeData & transmit;
Servers servers;
enum State {
RequestRegisterApplication,
WaitRegisterApplication,
ConfirmationRegisterApplication,
AcceptRegisterApplication,
WaitReceive,
ReadHeader,
ReadData,
AcceptReceive,
RequestServer,
WaitSend,
WriteHeader,
WriteData,
AcceptSend,
Stop,
} state;
bool application_registred;
struct Packet {
packet::HIL_PACKET_HEADER header;
std::vector< char, std::pmr::polymorphic_allocator<char> > data;
Packet( std::pmr::memory_resource * buffer );
} request, response;
struct Client : public communication::IMessageClient {
Client( std::vector< char, std::pmr::polymorphic_allocator<char> > & data );
std::vector< char, std::pmr::polymorphic_allocator<char> > & data;
bool response( const char * data, std::size_t size );
bool flag = false;
};
public:
MailboxHandler( HandshakeData & receive, HandshakeData & transmit,
std::pmr::memory_resource * description, std::pmr::memory_resource * buffer );
void attach(communication::IMessageServer * server, ServerId id );
void start();
bool stop();
void process();
const bool & enable() const;
} mailbox_handler;
friend NetX;
peripheral::protected_char * handshake;
peripheral::protected_char * channel;
bool board_ready_status;
mutable std::pair< uint32_t, bool> cos_cache;
Info self_info;
void setBoardReadyStatus( bool ready_status );
void updateAppCos( uint32_t set, uint32_t clear = 0 );
uint32_t readNetXCos() const;
};
CommunicationChannel * open( CommunicationChannel::ChannelId id,
std::pmr::memory_resource * allocator,
std::pmr::memory_resource * description, std::pmr::memory_resource * buffer );
private:
typedef uint32_t ErrorCode;
typedef uint32_t ServerId;
static const std::size_t NETX_COMM_CHANNELS_NUM = 4;
static const std::size_t NETX_APP_CHANNELS_NUM = 2;
static const uint32_t NETX_DPM_COOKIE = 0x5874656E;
struct DpmLayout {
struct {
std::pair<peripheral::protected_char *, std::size_t> channel;
std::pair<peripheral::protected_char *, std::size_t> handshake;
std::pair<peripheral::protected_char *, std::size_t> mailbox_send;
std::pair<peripheral::protected_char *, std::size_t> mailbox_receive;
} system;
struct {
std::pair<peripheral::protected_char *, std::size_t> channel;
} handshake;
struct {
std::pair<peripheral::protected_char *, std::size_t> channel;
std::pair<peripheral::protected_char *, std::size_t> handshake;
std::pair<peripheral::protected_char *, std::size_t> cyclic_in;
std::pair<peripheral::protected_char *, std::size_t> cyclic_out;
std::pair<peripheral::protected_char *, std::size_t> mailbox_send;
std::pair<peripheral::protected_char *, std::size_t> mailbox_receive;
uint16_t type;
uint16_t protocol;
uint16_t conformance;
} communications[NETX_COMM_CHANNELS_NUM];
struct {
std::pair<peripheral::protected_char *, std::size_t> channel;
std::pair<peripheral::protected_char *, std::size_t> handshake;
} applications[NETX_APP_CHANNELS_NUM];
} layout;
struct Dpm {
peripheral::protected_char * base;
std::size_t size;
} dpm;
struct Info {
uint16_t dip_address; //!<
uint16_t device_class; //!<
uint32_t device_number; //!<
uint32_t serial_number; //!<
} device_info;
struct Channel {
enum Id {
System,
Handshake,
CommunicationAlfa,
CommunicationBeta,
CommunicationGamma,
CommunicationDelta,
ApplicationZero,
ApplicationOne
};
static const std::size_t num_channels = 8;
static peripheral::protected_char * handshake( peripheral::protected_char * base, Id id );
static peripheral::protected_char * status( peripheral::protected_char * base, Id id );
};
mutable bool ready_status;
CommunicationChannel * communication_channels[NETX_COMM_CHANNELS_NUM];
mutable ErrorCode errors[Channel::num_channels];
void resetSystem();
static bool checkDpmCookie( peripheral::protected_char * dpm_origin );
bool hasDefaultDpmLayout() const;
bool isChannelReady( Channel::Id channel ) const;
bool isChannelRunning( Channel::Id channel ) const;
bool isChannelCommunicating( Channel::Id channel ) const;
void notifyChannels( bool new_ready_status ) const;
std::pair<bool, uint32_t> checkChannelError( Channel::Id channel ) const;
};
} /* namespace netx */
} /* namespace driver */
#endif /* UMLIBRARY_DRIVER_NETX_NETX_HH_ */