Project fixes and correct MARTe style makefile and source structure

This commit is contained in:
Martino Ferrari
2026-03-03 15:15:52 +01:00
parent 631417ef10
commit e6102ba433
51 changed files with 3309 additions and 1865 deletions

View File

@@ -0,0 +1 @@
include Makefile.inc

View File

@@ -0,0 +1,31 @@
OBJSX=TcpLogger.x
PACKAGE=Components/Interfaces
ROOT_DIR=../../../../
MAKEDEFAULTDIR=$(MARTe2_DIR)/MakeDefaults
include $(MAKEDEFAULTDIR)/MakeStdLibDefs.$(TARGET)
INCLUDES += -I.
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L0Types
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L2Objects
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L3Streams
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Messages
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Logger
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Configuration
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L5GAMs
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L3Services
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4Messages
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4LoggerService
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L5GAMs
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
all: $(OBJS) $(SUBPROJ) \
$(BUILD_DIR)/TcpLogger$(LIBEXT) \
$(BUILD_DIR)/TcpLogger$(DLLEXT)
echo $(OBJS)
include $(MAKEDEFAULTDIR)/MakeStdLibRules.$(TARGET)

View File

@@ -0,0 +1,156 @@
#include "TcpLogger.h"
#include "Threads.h"
#include "StringHelper.h"
#include "ConfigurationDatabase.h"
namespace MARTe {
CLASS_REGISTER(TcpLogger, "1.0")
TcpLogger::TcpLogger() :
ReferenceContainer(), LoggerConsumerI(), EmbeddedServiceMethodBinderI(),
service(*this)
{
port = 8082;
readIdx = 0;
writeIdx = 0;
workerThreadId = InvalidThreadIdentifier;
for (uint32 i=0; i<MAX_CLIENTS; i++) {
activeClients[i] = NULL_PTR(BasicTCPSocket*);
}
}
TcpLogger::~TcpLogger() {
service.Stop();
server.Close();
clientsMutex.FastLock();
for (uint32 i=0; i<MAX_CLIENTS; i++) {
if (activeClients[i] != NULL_PTR(BasicTCPSocket*)) {
activeClients[i]->Close();
delete activeClients[i];
activeClients[i] = NULL_PTR(BasicTCPSocket*);
}
}
clientsMutex.FastUnLock();
}
bool TcpLogger::Initialise(StructuredDataI & data) {
if (!ReferenceContainer::Initialise(data)) return false;
if (!data.Read("Port", port)) {
(void)data.Read("TcpPort", port);
}
(void)eventSem.Create();
ConfigurationDatabase threadData;
threadData.Write("Timeout", (uint32)1000);
if (!service.Initialise(threadData)) return false;
if (!server.Open()) return false;
if (!server.Listen(port)) {
return false;
}
printf("[TcpLogger] Listening on port %u\n", port);
if (service.Start() != ErrorManagement::NoError) {
return false;
}
return true;
}
void TcpLogger::ConsumeLogMessage(LoggerPage *logPage) {
if (logPage == NULL_PTR(LoggerPage*)) return;
// 1. Mirror to stdout
StreamString levelStr;
ErrorManagement::ErrorCodeToStream(logPage->errorInfo.header.errorType, levelStr);
printf("[%s] %s\n", levelStr.Buffer(), logPage->errorStrBuffer);
fflush(stdout);
// 2. Queue for TCP
InsertLogIntoQueue(logPage->errorInfo, logPage->errorStrBuffer);
}
void TcpLogger::InsertLogIntoQueue(const ErrorManagement::ErrorInformation &info, const char8 * const description) {
uint32 next = (writeIdx + 1) % QUEUE_SIZE;
if (next != readIdx) {
TcpLogEntry &entry = queue[writeIdx % QUEUE_SIZE];
entry.info = info;
StringHelper::Copy(entry.description, description);
writeIdx = next;
(void)eventSem.Post();
}
}
ErrorManagement::ErrorType TcpLogger::Execute(ExecutionInfo & info) {
if (info.GetStage() == ExecutionInfo::TerminationStage) return ErrorManagement::NoError;
if (info.GetStage() == ExecutionInfo::StartupStage) {
workerThreadId = Threads::Id();
return ErrorManagement::NoError;
}
while (info.GetStage() == ExecutionInfo::MainStage) {
// 1. Check for new connections
BasicTCPSocket *newClient = server.WaitConnection(1);
if (newClient != NULL_PTR(BasicTCPSocket *)) {
clientsMutex.FastLock();
bool added = false;
for (uint32 i=0; i<MAX_CLIENTS; i++) {
if (activeClients[i] == NULL_PTR(BasicTCPSocket*)) {
activeClients[i] = newClient;
added = true;
break;
}
}
clientsMutex.FastUnLock();
if (!added) {
newClient->Close();
delete newClient;
} else {
(void)newClient->SetBlocking(false);
}
}
// 2. Stream data to clients
bool hadData = false;
while (readIdx != writeIdx) {
hadData = true;
uint32 idx = readIdx % QUEUE_SIZE;
TcpLogEntry &entry = queue[idx];
StreamString level;
ErrorManagement::ErrorCodeToStream(entry.info.header.errorType, level);
StreamString packet;
packet.Printf("LOG %s %s\n", level.Buffer(), entry.description);
uint32 size = packet.Size();
clientsMutex.FastLock();
for (uint32 j=0; j<MAX_CLIENTS; j++) {
if (activeClients[j] != NULL_PTR(BasicTCPSocket*)) {
uint32 s = size;
if (!activeClients[j]->Write(packet.Buffer(), s)) {
activeClients[j]->Close();
delete activeClients[j];
activeClients[j] = NULL_PTR(BasicTCPSocket*);
}
}
}
clientsMutex.FastUnLock();
readIdx = (readIdx + 1) % QUEUE_SIZE;
}
if (!hadData) {
(void)eventSem.Wait(TimeoutType(100));
eventSem.Reset();
} else {
Sleep::MSec(1);
}
}
return ErrorManagement::NoError;
}
}

View File

@@ -0,0 +1,65 @@
#ifndef TCPLOGGER_H
#define TCPLOGGER_H
#include "LoggerConsumerI.h"
#include "ReferenceContainer.h"
#include "EmbeddedServiceMethodBinderI.h"
#include "BasicTCPSocket.h"
#include "SingleThreadService.h"
#include "FastPollingMutexSem.h"
#include "EventSem.h"
namespace MARTe {
struct TcpLogEntry {
ErrorManagement::ErrorInformation info;
char8 description[MAX_ERROR_MESSAGE_SIZE];
};
/**
* @brief Logger consumer that publishes framework logs to TCP and stdout.
* @details Implements LoggerConsumerI to be used inside a LoggerService.
*/
class TcpLogger : public ReferenceContainer, public LoggerConsumerI, public EmbeddedServiceMethodBinderI {
public:
CLASS_REGISTER_DECLARATION()
TcpLogger();
virtual ~TcpLogger();
virtual bool Initialise(StructuredDataI & data);
/**
* @brief Implementation of LoggerConsumerI.
* Called by LoggerService.
*/
virtual void ConsumeLogMessage(LoggerPage *logPage);
/**
* @brief Worker thread method for TCP streaming.
*/
virtual ErrorManagement::ErrorType Execute(ExecutionInfo & info);
private:
void InsertLogIntoQueue(const ErrorManagement::ErrorInformation &info, const char8 * const description);
uint16 port;
BasicTCPSocket server;
static const uint32 MAX_CLIENTS = 8;
BasicTCPSocket* activeClients[MAX_CLIENTS];
FastPollingMutexSem clientsMutex;
SingleThreadService service;
ThreadIdentifier workerThreadId;
static const uint32 QUEUE_SIZE = 1024;
TcpLogEntry queue[QUEUE_SIZE];
volatile uint32 readIdx;
volatile uint32 writeIdx;
EventSem eventSem;
};
}
#endif