interface added and web ui created
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
#ifndef DEBUGSERVICEI_H
|
||||
#define DEBUGSERVICEI_H
|
||||
|
||||
/**
|
||||
* @file DebugServiceI.h
|
||||
* @brief Abstract interface for the MARTe2 debug/instrumentation service.
|
||||
*
|
||||
* All broker wrappers (DebugBrokerWrapper) depend solely on this interface,
|
||||
* decoupling them from the concrete TCP/UDP implementation. Alternative
|
||||
* transports — TTY, WebSocket, shared-memory ring, etc. — can be plugged in
|
||||
* by providing a new concrete implementation without touching any broker or
|
||||
* application code.
|
||||
*
|
||||
* The interface is split into two logical groups:
|
||||
*
|
||||
* RT-path API
|
||||
* Called from broker threads on every RT cycle. Implementations must
|
||||
* keep these methods as cheap as possible; the only permissible
|
||||
* synchronisation primitive is a fast spinlock (FastPollingMutexSem).
|
||||
*
|
||||
* Control-path API
|
||||
* Called from server / command-handler threads (TCP, TTY, Web …).
|
||||
* Latency here is acceptable; correctness and thread-safety matter.
|
||||
*
|
||||
* Concrete implementations register themselves during Initialise() via
|
||||
* SetInstance(). Broker wrappers retrieve the active instance via
|
||||
* GetInstance(); there is no ORD search on the hot path.
|
||||
*/
|
||||
|
||||
#include "DebugCore.h"
|
||||
#include "FastPollingMutexSem.h"
|
||||
#include "Object.h"
|
||||
#include "StreamString.h"
|
||||
#include "TypeDescriptor.h"
|
||||
#include "Vec.h"
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
// Forward declarations — concrete types are only needed in the implementation.
|
||||
class MemoryMapBroker;
|
||||
|
||||
struct SignalAlias {
|
||||
StreamString name;
|
||||
uint32 signalIndex;
|
||||
};
|
||||
|
||||
struct BrokerInfo {
|
||||
DebugSignalInfo **signalPointers;
|
||||
uint32 numSignals;
|
||||
MemoryMapBroker *broker;
|
||||
volatile bool *anyActiveFlag;
|
||||
Vec<uint32> *activeIndices;
|
||||
Vec<uint32> *activeSizes;
|
||||
FastPollingMutexSem *activeMutex;
|
||||
volatile bool *anyBreakFlag;
|
||||
Vec<uint32> *breakIndices;
|
||||
StreamString gamName;
|
||||
bool isOutput;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Abstract debug-service interface.
|
||||
*/
|
||||
class DebugServiceI {
|
||||
public:
|
||||
// -------------------------------------------------------------------------
|
||||
// Static instance registry
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Return the currently registered debug-service instance, or NULL.
|
||||
*
|
||||
* Called on every broker Init() path and from OutpautPauseAndStep().
|
||||
* Returns NULL when no debug service has been initialised, in which case
|
||||
* all instrumentation is a no-op.
|
||||
*/
|
||||
static DebugServiceI *GetInstance() { return instance; }
|
||||
|
||||
/**
|
||||
* @brief Register @p inst as the global debug-service.
|
||||
*
|
||||
* Concrete implementations call this from their Initialise() method.
|
||||
* Passing NULL deregisters the current instance (called from the
|
||||
* destructor so dangling pointers are never visible to broker threads).
|
||||
*/
|
||||
static void SetInstance(DebugServiceI *inst) { instance = inst; }
|
||||
|
||||
virtual ~DebugServiceI() {}
|
||||
|
||||
// =========================================================================
|
||||
// RT-path API (called from broker execute threads every cycle)
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* @brief Register a signal memory region with the debug service.
|
||||
*
|
||||
* Called once per signal during broker Init(). Returns a pointer to the
|
||||
* internal DebugSignalInfo that the broker caches for use on the hot path.
|
||||
* Thread-safe; must not be called after the RT loop has started.
|
||||
*/
|
||||
virtual DebugSignalInfo *RegisterSignal(void *memoryAddress,
|
||||
TypeDescriptor type,
|
||||
const char8 *name,
|
||||
uint8 numberOfDimensions = 0,
|
||||
uint32 numberOfElements = 1) = 0;
|
||||
|
||||
/**
|
||||
* @brief Process one signal on the RT path.
|
||||
*
|
||||
* Applies forced values (memcpy into signal memory) and, when tracing is
|
||||
* enabled and the decimation counter fires, pushes a sample to the trace
|
||||
* ring buffer. Called under the broker's activeMutex; implementations
|
||||
* must not acquire any lock that is also held by the Server thread.
|
||||
*/
|
||||
virtual void ProcessSignal(DebugSignalInfo *signalInfo,
|
||||
uint32 size,
|
||||
uint64 timestamp) = 0;
|
||||
|
||||
/**
|
||||
* @brief Register a broker so the service can push active/break index
|
||||
* updates to it without iterating every signal.
|
||||
*/
|
||||
virtual void RegisterBroker(DebugSignalInfo **signalPointers,
|
||||
uint32 numSignals,
|
||||
MemoryMapBroker *broker,
|
||||
volatile bool *anyActiveFlag,
|
||||
Vec<uint32> *activeIndices,
|
||||
Vec<uint32> *activeSizes,
|
||||
FastPollingMutexSem *activeMutex,
|
||||
volatile bool *anyBreakFlag,
|
||||
Vec<uint32> *breakIndices,
|
||||
const char8 *gamName = NULL_PTR(const char8 *),
|
||||
bool isOutput = false) = 0;
|
||||
|
||||
/** @brief Return true if the RT loop is currently held at a pause/breakpoint. */
|
||||
virtual bool IsPaused() const = 0;
|
||||
|
||||
/** @brief Set or clear the paused state (called by break-condition logic). */
|
||||
virtual void SetPaused(bool paused) = 0;
|
||||
|
||||
/** @brief Return true if a step count is pending (stepRemaining > 0). */
|
||||
virtual bool IsStepPending() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Consume one step credit for the current output-broker cycle.
|
||||
*
|
||||
* Called by every output broker after Execute(). No-op when stepRemaining
|
||||
* is zero (the common case); only acquires a mutex when stepping is active.
|
||||
*/
|
||||
virtual void ConsumeStepIfNeeded(
|
||||
const char8 *gamName,
|
||||
const char8 *threadName = NULL_PTR(const char8 *)) = 0;
|
||||
|
||||
// =========================================================================
|
||||
// Control-path API (called from server / command-handler threads)
|
||||
// =========================================================================
|
||||
|
||||
virtual uint32 ForceSignal (const char8 *name, const char8 *valueStr) = 0;
|
||||
virtual uint32 UnforceSignal(const char8 *name) = 0;
|
||||
virtual uint32 TraceSignal (const char8 *name, bool enable, uint32 decimation = 1) = 0;
|
||||
virtual uint32 SetBreak (const char8 *name, uint8 op, float64 threshold) = 0;
|
||||
virtual uint32 ClearBreak (const char8 *name) = 0;
|
||||
virtual bool IsInstrumented(const char8 *fullPath,
|
||||
bool &traceable, bool &forcable) = 0;
|
||||
virtual uint32 RegisterMonitorSignal(const char8 *path, uint32 periodMs) = 0;
|
||||
virtual uint32 UnmonitorSignal (const char8 *path) = 0;
|
||||
|
||||
// =========================================================================
|
||||
// Utility (implementation-agnostic, defined in DebugService.cpp)
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* @brief Resolve the fully-qualified ORD path of @p obj into @p fullPath.
|
||||
*
|
||||
* Static so it can be called without a service instance. All concrete
|
||||
* implementations (and InitSignals in DebugBrokerWrapper.h) use this
|
||||
* to build canonical signal names. The definition lives in
|
||||
* DebugService.cpp alongside FindPathInContainer().
|
||||
*/
|
||||
static bool GetFullObjectName(const Object &obj, StreamString &fullPath);
|
||||
|
||||
protected:
|
||||
/** Pointer to the single active debug-service instance. */
|
||||
static DebugServiceI *instance;
|
||||
};
|
||||
|
||||
} // namespace MARTe
|
||||
|
||||
#endif // DEBUGSERVICEI_H
|
||||
Reference in New Issue
Block a user