#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; } /** * Update system info by raw data. */ void SysMonitor_UpdateSysinfoRaw(const uint8_t *buff) { ASSERT(sysMonitorInst != NULL); uint8_t buffIndx; buffIndx = GetWritable(sysMonitorInst->sysInfoCtrl); sysMonitorInst->sysInfoCtrl.wBusy = buffIndx; // Decapsulate Systeminfo SYSINFO *infoEntry = &(sysMonitorInst->sysInfo[buffIndx]); memcpy(&(infoEntry->psBDS), buff, sizeof(infoEntry->psBDS)); buff += sizeof(infoEntry->psBDS); memcpy(&(infoEntry->pBDS), buff, sizeof(infoEntry->pBDS)); buff += sizeof(infoEntry->pBDS); memcpy(&(infoEntry->psGPS), buff, sizeof(infoEntry->psGPS)); buff += sizeof(infoEntry->psGPS); memcpy(&(infoEntry->pGPS), buff, sizeof(infoEntry->pGPS)); buff += sizeof(infoEntry->pGPS); memcpy(&(infoEntry->tmInd), buff, sizeof(infoEntry->tmInd)); buff += sizeof(infoEntry->tmInd); memcpy(&(infoEntry->tmFly), buff, sizeof(infoEntry->tmFly)); buff += sizeof(infoEntry->tmFly); memcpy(&(infoEntry->stFly), buff, sizeof(infoEntry->stFly)); buff += sizeof(infoEntry->stFly); memcpy(&(infoEntry->posX), buff, sizeof(infoEntry->posX)); buff += sizeof(infoEntry->posX); memcpy(&(infoEntry->posY), buff, sizeof(infoEntry->posY)); buff += sizeof(infoEntry->posY); memcpy(&(infoEntry->posZ), buff, sizeof(infoEntry->posZ)); buff += sizeof(infoEntry->posZ); memcpy(&(infoEntry->vX), buff, sizeof(infoEntry->vX)); buff += sizeof(infoEntry->vX); memcpy(&(infoEntry->vY), buff, sizeof(infoEntry->vY)); buff += sizeof(infoEntry->vY); memcpy(&(infoEntry->vZ), buff, sizeof(infoEntry->vZ)); buff += sizeof(infoEntry->vZ); memcpy(&(infoEntry->pitch), buff, sizeof(infoEntry->pitch)); buff += sizeof(infoEntry->pitch); memcpy(&(infoEntry->yaw), buff, sizeof(infoEntry->yaw)); buff += sizeof(infoEntry->yaw); memcpy(&(infoEntry->roll), buff, sizeof(infoEntry->roll)); 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; } /** * Get system info as raw data. */ void SysMonitor_GetSysinfoRaw(uint8_t *buff) { 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; // Encapsulate Systeminfo SYSINFO *infoEntry = &(sysMonitorInst->sysInfo[buffIndx]); memcpy(buff, &(infoEntry->psBDS), sizeof(infoEntry->psBDS)); buff += sizeof(infoEntry->psBDS); memcpy(buff, &(infoEntry->pBDS), sizeof(infoEntry->pBDS)); buff += sizeof(infoEntry->pBDS); memcpy(buff, &(infoEntry->psGPS), sizeof(infoEntry->psGPS)); buff += sizeof(infoEntry->psGPS); memcpy(buff, &(infoEntry->pGPS), sizeof(infoEntry->pGPS)); buff += sizeof(infoEntry->pGPS); memcpy(buff, &(infoEntry->tmInd), sizeof(infoEntry->tmInd)); buff += sizeof(infoEntry->tmInd); memcpy(buff, &(infoEntry->tmFly), sizeof(infoEntry->tmFly)); buff += sizeof(infoEntry->tmFly); memcpy(buff, &(infoEntry->stFly), sizeof(infoEntry->stFly)); buff += sizeof(infoEntry->stFly); memcpy(buff, &(infoEntry->posX), sizeof(infoEntry->posX)); buff += sizeof(infoEntry->posX); memcpy(buff, &(infoEntry->posY), sizeof(infoEntry->posY)); buff += sizeof(infoEntry->posY); memcpy(buff, &(infoEntry->posZ), sizeof(infoEntry->posZ)); buff += sizeof(infoEntry->posZ); memcpy(buff, &(infoEntry->vX), sizeof(infoEntry->vX)); buff += sizeof(infoEntry->vX); memcpy(buff, &(infoEntry->vY), sizeof(infoEntry->vY)); buff += sizeof(infoEntry->vY); memcpy(buff, &(infoEntry->vZ), sizeof(infoEntry->vZ)); buff += sizeof(infoEntry->vZ); memcpy(buff, &(infoEntry->pitch), sizeof(infoEntry->pitch)); buff += sizeof(infoEntry->pitch); memcpy(buff, &(infoEntry->yaw), sizeof(infoEntry->yaw)); buff += sizeof(infoEntry->yaw); memcpy(buff, &(infoEntry->roll), sizeof(infoEntry->roll)); sysMonitorInst->sysInfoCtrl.rBusy = buffIndex_old; } // @Send Payload /** * Update send payload by raw data. */ void SysMonitor_UpdateSendPayloadRaw(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 as raw data. */ void SysMonitor_GetSendPayloadRaw(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 by raw data. */ void SysMonitor_UpdateRecvPayloadRaw(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 as raw data. */ void SysMonitor_GetRecvPayloadRaw(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; } /** * Get the latest link layer log as raw data */ void SysMonitor_GetLinklayerLogRaw(uint8_t *buff) { 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; // Encapsulate log LINKLOG *logEntry = &(sysMonitorInst->linkLog[buffIndx]); // TODO: 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; } /** * Get the latest physical layer log as raw data */ void SysMonitor_GetPhysicalLayerLogRaw(uint8_t *buff) { 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; // Encapsulate log PHYLOG *logEntry = &(sysMonitorInst->phyLog[buffIndx]); // TODO: 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; } /** * Get the latest hardware running status as raw data. */ void SysMonitor_GetHardwareStatusRaw(uint8_t *buff) { 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; // Encapsulate log HWSTATE *logEntry = &(sysMonitorInst->hwState[buffIndx]); memcpy(buff, &(logEntry->spPsVolt), sizeof(logEntry->spPsVolt)); buff += sizeof(logEntry->spPsVolt); memcpy(buff, &(logEntry->spPsAuxVolt), sizeof(logEntry->spPsAuxVolt)); buff += sizeof(logEntry->spPsAuxVolt); memcpy(buff, &(logEntry->spDdrVolt), sizeof(logEntry->spDdrVolt)); buff += sizeof(logEntry->spDdrVolt); memcpy(buff, &(logEntry->spPlVolt), sizeof(logEntry->spPlVolt)); buff += sizeof(logEntry->spPlVolt); memcpy(buff, &(logEntry->spPlAuxVolt), sizeof(logEntry->spPlAuxVolt)); buff += sizeof(logEntry->spPlAuxVolt); memcpy(buff, &(logEntry->spBramVolt), sizeof(logEntry->spBramVolt)); buff += sizeof(logEntry->spBramVolt); memcpy(buff, &(logEntry->spTemp), sizeof(logEntry->spTemp)); buff += sizeof(logEntry->spTemp); memcpy(buff, &(logEntry->antVolt), sizeof(logEntry->antVolt)); buff += sizeof(logEntry->antVolt); memcpy(buff, &(logEntry->antTemp), sizeof(logEntry->antTemp)); buff += sizeof(logEntry->antTemp); memcpy(buff, &(logEntry->antPll), sizeof(logEntry->antPll)); buff += sizeof(logEntry->antPll); memcpy(buff, &(logEntry->antMgc0), sizeof(logEntry->antMgc0)); buff += sizeof(logEntry->antMgc0); memcpy(buff, &(logEntry->antMgc1), sizeof(logEntry->antMgc1)); buff += sizeof(logEntry->antMgc1); sysMonitorInst->hwStateCtrl.rBusy = buffIndex_old; } // @System log /** * Get the latest system running log. */ void SysMonitor_GetSyslog(SYSLOG *log) { ASSERT(sysMonitorInst != NULL); SysMonitor_GetLinklayerLog(&(log->linkLog)); SysMonitor_GetPhysicalLayerLog(&(log->phyLog)); SysMonitor_GetHardwareStatus(&(log->hwSate)); } /** * Get the latest system running log as raw data. */ void SysMonitor_GetSyslogRaw(uint8_t *buff) { ASSERT(sysMonitorInst != NULL); SysMonitor_GetLinklayerLogRaw(buff); buff += SLOTLOG_PACK_LEN; SysMonitor_GetPhysicalLayerLogRaw(buff); buff += SLOTLOG_PACK_LEN; SysMonitor_GetHardwareStatusRaw(buff); }