292 lines
8.0 KiB
C
292 lines
8.0 KiB
C
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include "common.h"
|
|
#include "system_monitor.h"
|
|
|
|
#define BUFF_A 0x00
|
|
#define BUFF_B 0x01
|
|
#define BUFF_NONE 0xFF
|
|
|
|
#define SYSINFO_PACK_LEN 54 // bytes
|
|
#define PAYLOAD_PACK_LEN 46 // bytes
|
|
#define SLOTLOG_PACK_LEN 88 // bytes
|
|
#define PRTCLLOG_PACK_ELN 24 // bytes
|
|
#define HWSTATE_PACK_ELN 12 // bytes
|
|
|
|
typedef struct
|
|
{
|
|
uint8_t latest;
|
|
uint8_t rBusy;
|
|
uint8_t wBusy;
|
|
} PINGPONG;
|
|
|
|
typedef struct
|
|
{
|
|
PINGPONG recvCtrl;
|
|
PAYLOAD recv[2];
|
|
PINGPONG sendCtrl;
|
|
PAYLOAD send[2];
|
|
PINGPONG sysInfoCtrl;
|
|
SYSINFO sysInfo[2];
|
|
PINGPONG linkLogCtrl;
|
|
LINKLOG linkLog[2];
|
|
PINGPONG phyLogCtrl;
|
|
PHYLOG phyLog[2];
|
|
PINGPONG hwStateCtrl;
|
|
HWSTATE hwState[2];
|
|
} SYSMONITOR;
|
|
|
|
static SYSMONITOR *sysMonitorInst;
|
|
|
|
uint8_t GetWritable(PINGPONG ctrllor);
|
|
uint8_t GetReadable(PINGPONG ctrllor);
|
|
|
|
inline uint8_t GetWritable(PINGPONG ctrllor)
|
|
{
|
|
// Allow only one write.
|
|
ASSERT(ctrllor.wBusy == BUFF_NONE);
|
|
if (ctrllor.rBusy == BUFF_NONE)
|
|
return ((ctrllor.latest == BUFF_B) ? BUFF_A : BUFF_B);
|
|
else
|
|
return ((ctrllor.rBusy == BUFF_B) ? BUFF_A : BUFF_B);
|
|
}
|
|
|
|
inline uint8_t GetReadable(PINGPONG ctrllor)
|
|
{
|
|
if (ctrllor.wBusy == BUFF_NONE || ctrllor.wBusy != ctrllor.latest)
|
|
return ((ctrllor.latest == BUFF_NONE) ? BUFF_A : BUFF_B);
|
|
else
|
|
return ((ctrllor.wBusy == BUFF_B) ? BUFF_A : BUFF_B);
|
|
}
|
|
|
|
// System monitor initialise
|
|
int32_t SysMonitor_Init(void)
|
|
{
|
|
sysMonitorInst = calloc(1, sizeof(SYSMONITOR));
|
|
if (sysMonitorInst == NULL)
|
|
{
|
|
return ENOMEM;
|
|
}
|
|
memset(&(sysMonitorInst->recvCtrl), BUFF_NONE, sizeof(PINGPONG));
|
|
memset(&(sysMonitorInst->sendCtrl), BUFF_NONE, sizeof(PINGPONG));
|
|
memset(&(sysMonitorInst->sysInfoCtrl), BUFF_NONE, sizeof(PINGPONG));
|
|
memset(&(sysMonitorInst->linkLogCtrl), BUFF_NONE, sizeof(PINGPONG));
|
|
memset(&(sysMonitorInst->phyLogCtrl), BUFF_NONE, sizeof(PINGPONG));
|
|
memset(&(sysMonitorInst->hwStateCtrl), BUFF_NONE, sizeof(PINGPONG));
|
|
|
|
sysMonitorInst->recv[0].dataId = DATA_ID_NONE;
|
|
sysMonitorInst->recv[1].dataId = DATA_ID_NONE;
|
|
sysMonitorInst->send[0].dataId = DATA_ID_NONE;
|
|
sysMonitorInst->send[1].dataId = DATA_ID_NONE;
|
|
return SUCCESS;
|
|
}
|
|
|
|
// System monitor initialise
|
|
void SysMonitor_Destroy(void)
|
|
{
|
|
free(sysMonitorInst);
|
|
}
|
|
|
|
// @System Info
|
|
/**
|
|
* Update system info.
|
|
*/
|
|
void SysMonitor_UpdateSysinfo(const SYSINFO *info)
|
|
{
|
|
uint8_t buffIndx;
|
|
buffIndx = GetWritable(sysMonitorInst->sysInfoCtrl);
|
|
sysMonitorInst->sysInfoCtrl.wBusy = buffIndx;
|
|
memcpy(&(sysMonitorInst->sysInfo[buffIndx]), info, sizeof(SYSINFO));
|
|
sysMonitorInst->sysInfoCtrl.latest = buffIndx;
|
|
sysMonitorInst->sysInfoCtrl.wBusy = BUFF_NONE;
|
|
}
|
|
|
|
/**
|
|
* Get system info.
|
|
*/
|
|
void SysMonitor_GetSysinfo(SYSINFO *info)
|
|
{
|
|
ASSERT(sysMonitorInst != NULL);
|
|
uint8_t buffIndx, buffIndex_old;
|
|
buffIndex_old = sysMonitorInst->sysInfoCtrl.rBusy;
|
|
if (buffIndex_old != BUFF_NONE)
|
|
buffIndx = buffIndex_old; // Keep it busy
|
|
else
|
|
buffIndx = GetReadable(sysMonitorInst->sysInfoCtrl);
|
|
sysMonitorInst->sysInfoCtrl.rBusy = buffIndx;
|
|
memcpy(info, &(sysMonitorInst->sysInfo[buffIndx]), sizeof(SYSINFO));
|
|
sysMonitorInst->sysInfoCtrl.rBusy = buffIndex_old;
|
|
}
|
|
|
|
// @Send Payload
|
|
/**
|
|
* Update send payload by.
|
|
*/
|
|
void SysMonitor_UpdateSendPayload(const uint8_t *buff, size_t len)
|
|
{
|
|
ASSERT(sysMonitorInst != NULL);
|
|
uint8_t buffIndx;
|
|
buffIndx = GetWritable(sysMonitorInst->sendCtrl);
|
|
sysMonitorInst->sendCtrl.wBusy = buffIndx;
|
|
memcpy(sysMonitorInst->send[buffIndx].data, buff, len);
|
|
sysMonitorInst->send[buffIndx].dataId++;
|
|
sysMonitorInst->sendCtrl.latest = buffIndx;
|
|
sysMonitorInst->sendCtrl.wBusy = BUFF_NONE;
|
|
}
|
|
|
|
/**
|
|
* Get the latest send payload.
|
|
*/
|
|
void SysMonitor_GetSendPayload(uint8_t *buff, uint32_t *id, size_t len)
|
|
{
|
|
ASSERT(sysMonitorInst != NULL);
|
|
uint8_t buffIndx, buffIndex_old;
|
|
buffIndex_old = sysMonitorInst->sendCtrl.rBusy;
|
|
if (buffIndex_old != BUFF_NONE)
|
|
buffIndx = buffIndex_old; // Keep it busy
|
|
else
|
|
buffIndx = GetReadable(sysMonitorInst->sendCtrl);
|
|
sysMonitorInst->sendCtrl.rBusy = buffIndx;
|
|
if (sysMonitorInst->send[buffIndx].dataId != DATA_ID_NONE)
|
|
{
|
|
memcpy(buff, sysMonitorInst->send[buffIndx].data, len);
|
|
}
|
|
*id = sysMonitorInst->send[buffIndx].dataId;
|
|
sysMonitorInst->sendCtrl.rBusy = buffIndex_old;
|
|
}
|
|
|
|
// @Receive Payload
|
|
/**
|
|
* Update receive payload.
|
|
*/
|
|
void SysMonitor_UpdateRecvPayload(const uint8_t *buff, size_t len)
|
|
{
|
|
ASSERT(sysMonitorInst != NULL);
|
|
uint8_t buffIndx;
|
|
buffIndx = GetWritable(sysMonitorInst->recvCtrl);
|
|
sysMonitorInst->recvCtrl.wBusy = buffIndx;
|
|
memcpy(sysMonitorInst->recv[buffIndx].data, buff, len);
|
|
sysMonitorInst->recv[buffIndx].dataId++;
|
|
sysMonitorInst->recvCtrl.latest = buffIndx;
|
|
sysMonitorInst->recvCtrl.wBusy = BUFF_NONE;
|
|
}
|
|
|
|
/**
|
|
* Get the latest receive payload.
|
|
*/
|
|
void SysMonitor_GetRecvPayload(uint8_t *buff, uint32_t *id, size_t len)
|
|
{
|
|
ASSERT(sysMonitorInst != NULL);
|
|
uint8_t buffIndx, buffIndex_old;
|
|
buffIndex_old = sysMonitorInst->recvCtrl.rBusy;
|
|
if (buffIndex_old != BUFF_NONE)
|
|
buffIndx = buffIndex_old; // Keep it busy
|
|
else
|
|
buffIndx = GetReadable(sysMonitorInst->recvCtrl);
|
|
sysMonitorInst->recvCtrl.rBusy = buffIndx;
|
|
if (sysMonitorInst->recv[buffIndx].dataId != DATA_ID_NONE)
|
|
{
|
|
memcpy(buff, sysMonitorInst->recv[buffIndx].data, len);
|
|
}
|
|
*id = sysMonitorInst->recv[buffIndx].dataId;
|
|
sysMonitorInst->recvCtrl.rBusy = buffIndex_old;
|
|
}
|
|
|
|
// @Link layer log
|
|
/**
|
|
* Update link layer log
|
|
*/
|
|
void SysMonitor_UpdateLinklayerLog(const LINKLOG *log)
|
|
{
|
|
ASSERT(sysMonitorInst != NULL);
|
|
uint8_t buffIndx;
|
|
buffIndx = GetWritable(sysMonitorInst->linkLogCtrl);
|
|
sysMonitorInst->linkLogCtrl.wBusy = buffIndx;
|
|
memcpy(&(sysMonitorInst->linkLog[buffIndx]), log, sizeof(LINKLOG));
|
|
sysMonitorInst->linkLogCtrl.latest = buffIndx;
|
|
sysMonitorInst->linkLogCtrl.wBusy = BUFF_NONE;
|
|
}
|
|
|
|
/**
|
|
* Get the latest link layer log
|
|
*/
|
|
void SysMonitor_GetLinklayerLog(LINKLOG *log)
|
|
{
|
|
ASSERT(sysMonitorInst != NULL);
|
|
uint8_t buffIndx, buffIndex_old;
|
|
buffIndex_old = sysMonitorInst->linkLogCtrl.rBusy;
|
|
if (buffIndex_old != BUFF_NONE)
|
|
buffIndx = buffIndex_old; // Keep it busy
|
|
else
|
|
buffIndx = GetReadable(sysMonitorInst->linkLogCtrl);
|
|
sysMonitorInst->linkLogCtrl.rBusy = buffIndx;
|
|
memcpy(log, &(sysMonitorInst->linkLog[buffIndx]), sizeof(LINKLOG));
|
|
sysMonitorInst->linkLogCtrl.rBusy = buffIndex_old;
|
|
}
|
|
|
|
// @Physical layer log
|
|
/**
|
|
* Update physical layer log
|
|
*/
|
|
void SysMonitor_UpdatePhysicalLayerLog(const PHYLOG *log)
|
|
{
|
|
ASSERT(sysMonitorInst != NULL);
|
|
uint8_t buffIndx;
|
|
buffIndx = GetWritable(sysMonitorInst->phyLogCtrl);
|
|
sysMonitorInst->phyLogCtrl.wBusy = buffIndx;
|
|
memcpy(&(sysMonitorInst->phyLog[buffIndx]), log, sizeof(PHYLOG));
|
|
sysMonitorInst->phyLogCtrl.latest = buffIndx;
|
|
sysMonitorInst->phyLogCtrl.wBusy = BUFF_NONE;
|
|
}
|
|
|
|
/**
|
|
* Get the latest physical layer log
|
|
*/
|
|
void SysMonitor_GetPhysicalLayerLog(PHYLOG *log)
|
|
{
|
|
ASSERT(sysMonitorInst != NULL);
|
|
uint8_t buffIndx, buffIndex_old;
|
|
buffIndex_old = sysMonitorInst->phyLogCtrl.rBusy;
|
|
if (buffIndex_old != BUFF_NONE)
|
|
buffIndx = buffIndex_old; // Keep it busy
|
|
else
|
|
buffIndx = GetReadable(sysMonitorInst->phyLogCtrl);
|
|
sysMonitorInst->phyLogCtrl.rBusy = buffIndx;
|
|
memcpy(log, &(sysMonitorInst->phyLog[buffIndx]), sizeof(PHYLOG));
|
|
sysMonitorInst->phyLogCtrl.rBusy = buffIndex_old;
|
|
}
|
|
|
|
|
|
// @Hardware state
|
|
/**
|
|
* Log hardware running status.
|
|
*/
|
|
void SysMonitor_UpdateHardwareStatus(const HWSTATE *state)
|
|
{
|
|
ASSERT(sysMonitorInst != NULL);
|
|
uint8_t buffIndx;
|
|
buffIndx = GetWritable(sysMonitorInst->hwStateCtrl);
|
|
sysMonitorInst->hwStateCtrl.wBusy = buffIndx;
|
|
memcpy(&(sysMonitorInst->hwState[buffIndx]), state, sizeof(HWSTATE));
|
|
sysMonitorInst->hwStateCtrl.latest = buffIndx;
|
|
sysMonitorInst->hwStateCtrl.wBusy = BUFF_NONE;
|
|
}
|
|
|
|
/**
|
|
* Get the latest hardware running status.
|
|
*/
|
|
void SysMonitor_GetHardwareStatus(HWSTATE *state)
|
|
{
|
|
ASSERT(sysMonitorInst != NULL);
|
|
uint8_t buffIndx, buffIndex_old;
|
|
buffIndex_old = sysMonitorInst->hwStateCtrl.rBusy;
|
|
if (buffIndex_old != BUFF_NONE)
|
|
buffIndx = buffIndex_old; // Keep it busy
|
|
else
|
|
buffIndx = GetReadable(sysMonitorInst->hwStateCtrl);
|
|
sysMonitorInst->hwStateCtrl.rBusy = buffIndx;
|
|
memcpy(state, &(sysMonitorInst->hwState[buffIndx]), sizeof(HWSTATE));
|
|
sysMonitorInst->hwStateCtrl.rBusy = buffIndex_old;
|
|
}
|