#include #include #include #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; }