mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-18 10:19:20 +02:00
hardware protocol v2: configuration, wiring and debug panel
Adds the WITH_HARDWARE_PROTOCOL_V2 build option and the eu07.ini entries which configure it: uart2 declares a serial link and may be repeated for several controllers, the remaining uart2* entries tune frame size, heartbeat, rate limits and logging. UART v1 is untouched and both may be active at the same time on different ports. The driver mode starts the manager when at least one link is configured and pumps it from the input polling loop, and the debug panel gains a Hardware Protocol v2 section reporting link and session condition, packet rates, round trip time, protocol and transport error counters and whatever diagnostics the device itself reports, with switches for protocol and frame logging.
This commit is contained in:
@@ -9,6 +9,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -53,4 +54,13 @@ struct config
|
||||
bool debug_frames = false;
|
||||
};
|
||||
|
||||
// logging switches which can be flipped at run time from the simulator debug panel
|
||||
struct debug_switches
|
||||
{
|
||||
std::atomic<bool> log_messages { false };
|
||||
std::atomic<bool> log_frames { false };
|
||||
};
|
||||
|
||||
extern debug_switches debug_flags;
|
||||
|
||||
} // namespace hardware
|
||||
|
||||
@@ -30,6 +30,8 @@ constexpr std::size_t read_chunk_size = 4096;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
debug_switches debug_flags;
|
||||
|
||||
hardware_manager *hardware_manager::s_instance = nullptr;
|
||||
|
||||
hardware_link::hardware_link( std::unique_ptr<hardware_transport> Transport, config const &Config ) : m_transport( std::move( Transport ) ), m_config( Config ), m_session( *this, Config )
|
||||
@@ -224,6 +226,9 @@ hardware_manager::hardware_manager( config const &Config ) : m_config( Config )
|
||||
}
|
||||
#endif
|
||||
|
||||
debug_flags.log_messages = m_config.debug;
|
||||
debug_flags.log_frames = m_config.debug_frames;
|
||||
|
||||
m_reports.resize( m_links.size() );
|
||||
|
||||
if( false == m_links.empty() )
|
||||
@@ -259,18 +264,28 @@ void hardware_manager::worker()
|
||||
}
|
||||
}
|
||||
|
||||
void hardware_manager::update( double const Deltatime )
|
||||
void hardware_manager::update()
|
||||
{
|
||||
if( true == m_links.empty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// the input polling code doesn't carry a time step, so the sessions get their own
|
||||
auto const now = std::chrono::steady_clock::now();
|
||||
double deltatime = 0.0;
|
||||
if( true == m_updatestarted )
|
||||
{
|
||||
deltatime = std::clamp( std::chrono::duration<double>( now - m_lastupdate ).count(), 0.0, 0.5 );
|
||||
}
|
||||
m_updatestarted = true;
|
||||
m_lastupdate = now;
|
||||
|
||||
state_registry::capture( m_snapshot );
|
||||
|
||||
for( std::size_t index = 0; index < m_links.size(); ++index )
|
||||
{
|
||||
m_links[ index ]->update( Deltatime, m_snapshot );
|
||||
m_links[ index ]->update( deltatime, m_snapshot );
|
||||
m_reports[ index ] = m_links[ index ]->report();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,8 +82,8 @@ public:
|
||||
explicit hardware_manager( config const &Config );
|
||||
~hardware_manager();
|
||||
|
||||
// called once per simulation frame from the input polling code
|
||||
void update( double const Deltatime );
|
||||
// called once per simulation frame from the input polling code; the time step is measured here
|
||||
void update();
|
||||
|
||||
std::vector<link_report> const &reports() const { return m_reports; }
|
||||
bool active() const { return false == m_links.empty(); }
|
||||
@@ -102,6 +102,8 @@ private:
|
||||
std::vector<std::unique_ptr<hardware_link>> m_links;
|
||||
std::vector<link_report> m_reports;
|
||||
state_snapshot m_snapshot;
|
||||
std::chrono::steady_clock::time_point m_lastupdate;
|
||||
bool m_updatestarted = false;
|
||||
std::thread m_thread;
|
||||
std::atomic<bool> m_quit { false };
|
||||
};
|
||||
|
||||
@@ -182,7 +182,7 @@ void protocol_session::send( message_type const Type, std::uint8_t const Flags,
|
||||
++m_diagnostics.tx_frames;
|
||||
m_txrate.add();
|
||||
|
||||
if( true == m_config.debug_frames )
|
||||
if( true == debug_flags.log_frames )
|
||||
{
|
||||
WriteLog( "hardware: tx " + std::string( to_string( Type ) ) + ", " + std::to_string( Payload.size() ) + " bytes" );
|
||||
}
|
||||
@@ -206,7 +206,7 @@ void protocol_session::send_nack( std::uint32_t const Transaction, message_type
|
||||
send( message_type::nack, packetflag_response | packetflag_error, writer );
|
||||
++m_diagnostics.nacks;
|
||||
|
||||
if( true == m_config.debug )
|
||||
if( true == debug_flags.log_messages )
|
||||
{
|
||||
WriteLog( "hardware: nack " + std::string( to_string( Type ) ) + ", " + std::string( to_string( Error ) ) );
|
||||
}
|
||||
@@ -318,7 +318,7 @@ void protocol_session::handle_packet( decoded_packet const &Packet )
|
||||
m_lastreceivedsequence = Packet.header.sequence;
|
||||
m_sequenceseen = true;
|
||||
|
||||
if( true == m_config.debug_frames )
|
||||
if( true == debug_flags.log_frames )
|
||||
{
|
||||
WriteLog( "hardware: rx " + std::string( to_string( Packet.header.type ) ) + ", " + std::to_string( Packet.payload.size() ) + " bytes" );
|
||||
}
|
||||
@@ -366,7 +366,7 @@ void protocol_session::handle_packet( decoded_packet const &Packet )
|
||||
|
||||
case message_type::device_ready:
|
||||
m_state = session_state::ready;
|
||||
if( true == m_config.debug )
|
||||
if( true == debug_flags.log_messages )
|
||||
{
|
||||
WriteLog( "hardware: device '" + m_devicename + "' is ready" );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user