Parcourir la source

ADC-Info für Systeme ohne Tiva.

Rind il y a 1 an
Parent
commit
46fb6ec64d
5 fichiers modifiés avec 445 ajouts et 23 suppressions
  1. 2 0
      gfasysinfo.pro
  2. 344 0
      src/adcinfo.cpp
  3. 59 0
      src/adcinfo.h
  4. 38 21
      src/main.cpp
  5. 2 2
      src/spiinfo.cpp

+ 2 - 0
gfasysinfo.pro

@@ -34,6 +34,7 @@ SOURCES += \
     src/mysqlwrap.cpp \
     src/procfile.cpp \
     src/spiinfo.cpp \
+    src/adcinfo.cpp \
     src/stgdevinfo.cpp
 
 HEADERS += \
@@ -41,4 +42,5 @@ HEADERS += \
     src/mysqlwrap.h \
     src/procfile.h \
     src/spiinfo.h \
+    src/adcinfo.h \
     src/stgdevinfo.h

+ 344 - 0
src/adcinfo.cpp

@@ -0,0 +1,344 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/statvfs.h>
+#include <sys/statfs.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <poll.h>
+#include <signal.h>
+#include <errno.h>
+#include "adcinfo.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef _DEBUG
+#define TRACE(...)							fprintf(stdout, __VA_ARGS__), fflush(stdout)
+#else	//	_DEBUG
+#define TRACE(...)
+#endif	//	_DEBUG
+
+#define UNUSED(v)							(void)v
+#define _countof(a)							(sizeof(a) / sizeof(*a))
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define _SDA_POLL_INTERVAL_MS				200ULL
+#define _SDA_UPDATE_INTERVAL_US				(_SDA_POLL_INTERVAL_MS * 10000ULL)
+
+#define _ADC_INFO_BASE_DIR					"/sys/bus/iio/devices/iio:device0/"
+#define _ADC_IN_V0							_ADC_INFO_BASE_DIR "in_voltage0_raw"
+#define _ADC_IN_V1							_ADC_INFO_BASE_DIR "in_voltage1_raw"
+#define _ADC_IN_V2							_ADC_INFO_BASE_DIR "in_voltage2_raw"
+#define _ADC_IN_V3							_ADC_INFO_BASE_DIR "in_voltage3_raw"
+#define _ADC_IN_V4							_ADC_INFO_BASE_DIR "in_voltage4_raw"
+#define _ADC_IN_V5							_ADC_INFO_BASE_DIR "in_voltage5_raw"
+#define _ADC_IN_V6							_ADC_INFO_BASE_DIR "in_voltage6_raw"
+#define _ADC_IN_V7							_ADC_INFO_BASE_DIR "in_voltage7_raw"
+
+/////////////////////////////////////////////////////////////////////////////
+
+static const int g_kty_tab[][2] =
+{
+  {199,  1250},
+  {351,  1000},
+  {643,   750},
+  {1185,  500},
+  {2048,  250},
+  {3025,    0},
+  {3705, -250}
+};
+
+#define KTY_TAB_LEN							((int)_countof(g_kty_tab))
+
+/////////////////////////////////////////////////////////////////////////////
+
+CAdcInfo::CAdcInfo(void) : m_bPaused(false), m_bStateTransition(false)
+{
+	char szDisp[256];
+	if((m_gtt = ::GfAIpcGetTargetType(szDisp, sizeof(szDisp))) != GTT_NoGfATarget)
+	{
+		m_strDisplayName = szDisp;
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+bool CAdcInfo::TargetHasTiva(void) const
+{
+	return (m_gtt == GTT_GfATargetWithTiva);
+}
+
+bool CAdcInfo::IsGfATarget(void) const
+{
+	return (m_gtt != GTT_NoGfATarget);
+}
+
+GfATargetTypes CAdcInfo::GetTargetType(void) const
+{
+	return m_gtt;
+}
+
+std::string CAdcInfo::GetDisplayName(void) const
+{
+	return m_strDisplayName;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int CAdcInfo::lin_kty(int resistance) const
+{
+	int i;
+
+	if(resistance <= g_kty_tab[0][0])
+		return(g_kty_tab[0][1]);
+	else if(resistance >= g_kty_tab[KTY_TAB_LEN - 1][0])
+		return(g_kty_tab[KTY_TAB_LEN - 1][1]);
+
+	for(i = 1; i < KTY_TAB_LEN; i++)
+	{
+		if(g_kty_tab[i][0] >= resistance)
+			break;
+	}
+
+	// linear interpolation
+	return 	g_kty_tab[i - 1][1]							+	// y1 +
+			(												// (
+				(g_kty_tab[i][1] - g_kty_tab[i - 1][1])	*	//    (y2 - y1)	*
+				(resistance - g_kty_tab[i - 1][0])		/	//    (x  - x1)	/
+				(g_kty_tab[i][0] - g_kty_tab[i - 1][0])		//    (x2 - x1)
+			);												// )
+}
+
+int CAdcInfo::ScaleInt(int in_min, int in_max, int out_min, int out_max, int wert) const
+{
+	int abc;
+	abc = (((long)out_max - (long)out_min) * (long)wert) / ( (long)in_max - (long)in_min);
+	abc = abc + out_min;
+	return abc;
+}
+
+int CAdcInfo::ReadIntegerValue(int fd, int &val) const
+{
+	int nRet;
+	char szVal[32];
+
+	if((nRet = read(fd, szVal, sizeof(szVal) - 1)) > 0)
+	{
+		szVal[nRet] = '\0';
+		val = atoi(szVal);
+		nRet = lseek(fd, 0, SEEK_SET);
+	}
+	
+	return nRet;
+}
+
+int CAdcInfo::ReadADCValue(int fd, GFA_SYSINFO_SPI &spi, int nWhich) const
+{
+	int nRet, nVal, nScaled;
+
+	if((nRet = ReadIntegerValue(fd, nVal)) == 0)
+	{
+		switch(nWhich)
+		{
+		case 0:
+			nScaled = ScaleInt(0, 4096, 0, 774, nVal);					// val / 100.0 (interne 5V Hauptversorgungsspannung skaliert)
+			spi.adc.fVoltageSys = (float)nScaled / 100.f;				// UV5Vsys
+			break;
+		case 1:
+			nScaled = ScaleInt(0, 4096, 0, 360, nVal);					// val / 100.0 (Spannung Pufferbatterie skaliert)
+			spi.adc.fVoltageBackupBattery = (float)nScaled / 100.f;		// UBatV3
+			break;
+		case 2:
+			nScaled = ScaleInt(0, 4096, 0, 3150, nVal) + 40;			// val / 100.0 + 0.4 (Versorgungsspannung skaliert)
+			spi.adc.fVoltagePowerSupply = (float)nScaled / 100.f;		// UVers
+			break;
+		case 3:
+			nScaled = ScaleInt(0, 4096, 0, 563, nVal);
+			spi.adc.fVoltageBattery = (float)nScaled / 100.f;			// UV3V6Bat
+			break;
+		case 4:
+			nScaled = lin_kty(nVal);									// val / 10.0 (Boardtemperatur linear interpoliert)
+			spi.adc.fTemperatureBoard = (float)nScaled / 10.f;			// Temp
+			break;
+		default:
+			nRet = -1;
+			break;
+		}
+	}
+
+	return nRet;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void* CAdcInfo::ThreadRoutine(void *pParam)
+{
+    TRACE("Enter CAdcInfo::ThreadRoutine: TID: %ld\n", syscall(SYS_gettid));
+	LPEXEC_PARAMS pep = (LPEXEC_PARAMS)pParam;
+
+	if(pep)
+	{
+		const char *pszAdcFiles[] = {
+			_ADC_IN_V0,		// val / 100.0 (interne 5V Hauptversorgungsspannung skaliert)
+			_ADC_IN_V1,		// val / 100.0 (Spannung Pufferbatterie skaliert)
+			_ADC_IN_V2,		// val / 100.0 + 0.4 (Versorgungsspannung skaliert)
+			_ADC_IN_V3,		// val / 100.0 (interne 3V Akkuspannung skaliert)
+			_ADC_IN_V4		// val / 10.0 (Boardtemperatur linear interpoliert)
+		};
+		
+		bool bInitializing = true, bRun = false;
+		int nRet, nSig;
+		GFA_SYSINFO_SPI spi;
+		pollfd pfd[_countof(pszAdcFiles)];
+
+		do
+		{
+			memset(&spi, 0, sizeof(spi));
+
+			do
+			{
+				for(size_t i = 0; i < _countof(pfd); ++i)
+				{
+					if((pfd[i].fd = open(pszAdcFiles[i], O_RDONLY, 0)) < 0)
+						break;
+					ReadADCValue(pfd[i].fd, spi, i);
+					pfd[i].events = POLLIN;
+					pfd[i].revents = 0;
+				}
+
+				::GfaIpcAppCtrlUpdateSpiInfo(pep->hAC, spi, false);
+				bInitializing = false;
+				bRun = true;
+			}
+			while(false);
+
+			while(bRun)
+			{
+				if((nRet = WaitSignalTimeout(_SDA_UPDATE_INTERVAL_US, &nSig)) == ETIMEDOUT)
+				{
+					if(!m_bPaused)
+					{
+						if((nRet = poll(pfd, _countof(pfd), _SDA_POLL_INTERVAL_MS)) > 0)
+						{
+							int nUpdates = 0;
+
+							for(int i = 0; i < (int)_countof(pfd); ++i)
+							{
+								if(pfd[i].revents & POLLIN)
+								{
+									if(!(nRet = ReadADCValue(pfd[i].fd, spi, i)))
+									{
+										++nUpdates;
+									}
+									else if(nRet < 0)
+									{
+										TRACE("ReadADCValue from '%s' failed: %s\n", pszAdcFiles[i], strerror(errno));
+										bInitializing = true;
+										bRun = false;
+										break;
+									}
+								}
+							}
+
+							if(nUpdates > 0)
+								::GfaIpcAppCtrlUpdateSpiInfo(pep->hAC, spi, false);
+						}
+						else if(nRet < 0)
+						{
+							TRACE("poll failed: %s\n", strerror(errno));
+							bInitializing = true;
+							bRun = false;
+						}
+					}
+
+					m_bStateTransition = false;
+				}
+				else if(!nRet) // signal received
+				{
+					TRACE("%s signal %d received.\n", "CAdcInfo::ThreadRoutine", nSig);
+
+					switch(nSig)
+					{
+					case S_Init:
+						::GfaIpcAppCtrlUpdateSpiInfo(pep->hAC, spi, false);
+						break;
+					case S_Update:
+						::GfaIpcAppCtrlUpdateSpiInfo(pep->hAC, spi, false);
+						break;
+					case S_Pause:
+						m_bStateTransition = !m_bPaused;
+						m_bPaused = true;
+						::GfaIpcAppCtrlUpdateSpiInfo(pep->hAC, spi, true);
+						break;
+					case S_Resume:
+						m_bStateTransition = m_bPaused;
+						m_bPaused = false;
+						break;
+					case S_Terminate:
+						bInitializing = false;
+						bRun = false;
+						break;
+					default:
+						break;
+					}
+				}
+				else
+				{
+					TRACE("WaitSignalTimeout failed: %s\n", strerror(errno));
+					bInitializing = true;
+					bRun = false;
+					break;
+				}
+			}
+
+			::GfaIpcAppCtrlUpdateSpiInfo(pep->hAC, spi, true);
+
+			for(size_t i = 0; i < _countof(pfd); ++i)
+			{
+				if(pfd[i].fd >= 0)
+				{
+					close(pfd[i].fd);
+					pfd[i].fd = -1;
+				}
+			}
+
+			if(!bRun && bInitializing)
+			{
+				if(!WaitSignalTimeout(_SDA_UPDATE_INTERVAL_US, &nSig))
+				{
+					TRACE("%s signal %d received.\n", "CAdcInfo::ThreadRoutine", nSig);
+
+					switch(nSig)
+					{
+					case S_Init:
+						break;
+					case S_Update:
+						break;
+					case S_Pause:
+						m_bStateTransition = !m_bPaused;
+						m_bPaused = true;
+						break;
+					case S_Resume:
+						m_bStateTransition = m_bPaused;
+						m_bPaused = false;
+						break;
+					case S_Terminate:
+						bInitializing = false;
+						bRun = false;
+						break;
+					default:
+						break;
+					}
+				}
+			}
+		}
+		while(bInitializing);
+
+	}
+
+	TRACE("%s exit.\n", "CAdcInfo::ThreadRoutine");
+	return nullptr;
+}

+ 59 - 0
src/adcinfo.h

@@ -0,0 +1,59 @@
+// adcinfo.h :
+//
+
+#if !defined(AGD_ADCINFO_H__6B637742_EA8A_451D_951F_B890A70309CC__INCLUDED_)
+#define AGD_ADCINFO_H__6B637742_EA8A_451D_951F_B890A70309CC__INCLUDED_
+
+#include <string>
+#include <gfa/gfaipc.h>
+#include <gfa/ipcpriv.h>
+#include <gfa/thread.h>
+
+/////////////////////////////////////////////////////////////////////////////
+// CAdcInfo does the same things as CSpiInfo, but without SPI and Tiva
+// adcinfo.h - Declarations:
+
+class CAdcInfo : public CThread
+{
+public:
+	typedef enum
+	{
+		S_Init = 1,
+		S_Update,
+		S_Pause,
+		S_Resume,
+		S_Terminate
+	}Signals;
+
+public:
+	typedef struct _EXEC_PARAMS
+	{
+		HAPPCTRL hAC;
+	}EXEC_PARAMS, *LPEXEC_PARAMS;
+	typedef const EXEC_PARAMS *LPCEXEC_PARAMS;
+
+public:
+	CAdcInfo(void);
+	GfATargetTypes GetTargetType(void) const;
+	std::string GetDisplayName(void) const;
+	bool TargetHasTiva(void) const;
+	bool IsGfATarget(void) const;
+
+protected:
+	virtual void* ThreadRoutine(void *pParam);
+
+private:
+	int lin_kty(int resistance) const;
+	int ScaleInt(int in_min, int in_max, int out_min, int out_max, int wert) const;
+	int ReadIntegerValue(int fd, int &val) const;
+	int ReadADCValue(int fd, GFA_SYSINFO_SPI &spi, int nWhich) const;
+
+private:
+	bool m_bPaused;
+	bool m_bStateTransition;
+	GfATargetTypes m_gtt;
+	std::string m_strDisplayName;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+#endif	//	!defined(AGD_ADCINFO_H__6B637742_EA8A_451D_951F_B890A70309CC__INCLUDED_)

+ 38 - 21
src/main.cpp

@@ -23,6 +23,7 @@
 #include "stgdevinfo.h"
 #include "mysqlinfo.h"
 #include "spiinfo.h"
+#include "adcinfo.h"
 
 /////////////////////////////////////////////////////////////////////////////
 
@@ -119,7 +120,7 @@ static void _UnlockSHM(HSHM hShm)
 
 static void _SigHandler(int sig)
 {
-	UNUSED(sig);
+	TRACE("Received signal '%s'.\n", strsignal(sig));
 	g_fPause = false;
 	g_fRun = false;
 	g_fZombie = false;
@@ -132,7 +133,7 @@ static void _SigHandler(int sig)
 int main(int argc, char *argv[])
 {
 	int c;
-	HAPPCTRL hAC = NULL;
+	HAPPCTRL hAC = nullptr;
 	HAPPINFO hAI;
 	CCycleTimer ct(_CYCLE_INTV), perfCnt(0U);
 	cy_time_t wStart, wEnd, wCur = 0;
@@ -140,6 +141,7 @@ int main(int argc, char *argv[])
 	CMySqlInfo mySqlInfo;
 	CStgDevInfo stgDevInfo;
 	CSpiInfo spiInfo;
+	CAdcInfo adcInfo;
 	bool bOsIsHypervised = stgDevInfo.IsSystemHypervised();
 	bool bTargetHasTiva = spiInfo.TargetHasTiva();
 	bool bStateTransition, bUpdateStgDevInfo;
@@ -166,24 +168,24 @@ int main(int argc, char *argv[])
 	struct sigaction sa;
 	memset(&sa, 0, sizeof(sa));
 	::sigfillset(&g_set);
-	::sigdelset(&g_set, SIGSEGV);
+//	::sigdelset(&g_set, SIGSEGV);
 
 	sa.sa_handler = _SigHandler;
-    sigaction(SIGHUP, &sa, NULL);	// handles user's terminal disconnect
-    sigaction(SIGQUIT, &sa, NULL);	// handles Ctrl + '\'
-	sigaction(SIGTERM, &sa, NULL);	// handles normal termination
-	sigaction(SIGABRT, &sa, NULL);	// handles abnormal termination (i.e. abort())
-	sigaction(SIGINT, &sa, NULL);	// handles Ctrl + 'C'
+    sigaction(SIGHUP, &sa, nullptr);	// handles user's terminal disconnect
+    sigaction(SIGQUIT, &sa, nullptr);	// handles Ctrl + '\'
+	sigaction(SIGTERM, &sa, nullptr);	// handles normal termination
+	sigaction(SIGABRT, &sa, nullptr);	// handles abnormal termination (i.e. abort())
+	sigaction(SIGINT, &sa, nullptr);	// handles Ctrl + 'C'
 
 	// ignore signals
 	sa.sa_handler = SIG_IGN;
-    sigaction(SIGTSTP, &sa, NULL);	// ignores Ctrl + 'Z'
-    sigaction(SIGCHLD, &sa, NULL);	// ignores child process termination
-    sigaction(0, &sa, NULL);		// ignores shell termination
+    sigaction(SIGTSTP, &sa, nullptr);	// ignores Ctrl + 'Z'
+    sigaction(SIGCHLD, &sa, nullptr);	// ignores child process termination
+    sigaction(0, &sa, nullptr);			// ignores shell termination
 
 	/////////////////////////////////////////////////////////////////////////
 	// initialize
-	
+
 	CMySqlInfo::EXEC_PARAMS myep;
 	CStgDevInfo::EXEC_PARAMS step;
 	CSpiInfo::EXEC_PARAMS spep;
@@ -208,7 +210,7 @@ int main(int argc, char *argv[])
 	    }
 
 		::GfaIpcDumpSHMROT();
-		
+
 		TRACE("My Name:  %s\n", _APPNAME);
 		TRACE("My AppID: %llu\n", _APPID);
 		TRACE("My PID:   %d\n", getpid());
@@ -216,18 +218,23 @@ int main(int argc, char *argv[])
 
 		myep = {hAC, sDbUser, sDbPass};
 		mySqlInfo.Create(&myep);
-		
+
 		if(!bOsIsHypervised)
 		{
 			step = {hAC};
 			stgDevInfo.Create(&step);
 		}
-		
+
 		if(bTargetHasTiva)
 		{
 			spep = {hAC};
 			spiInfo.Create(&spep);
 		}
+		else
+		{
+			spep = {hAC};
+			adcInfo.Create(&spep);
+		}
 
 		g_fZombie = false;
 		g_fRun = true;
@@ -239,6 +246,8 @@ int main(int argc, char *argv[])
 
 		if(bTargetHasTiva)
 			spiInfo.Signal(CSpiInfo::S_Init);
+		else
+			adcInfo.Signal(CAdcInfo::S_Init);
 	}
 	while(false);
 
@@ -266,7 +275,7 @@ int main(int argc, char *argv[])
 
 		/////////////////////////////////////////////////////////////////////
 		// if not paused, do work
-		
+
 		if(g_fRun)
 		{
 			if(bStateTransition)
@@ -280,6 +289,8 @@ int main(int argc, char *argv[])
 
 					if(bTargetHasTiva)
 						spiInfo.Signal(CSpiInfo::S_Pause);
+					else
+						adcInfo.Signal(CAdcInfo::S_Pause);
 				}
 				else
 				{
@@ -290,9 +301,11 @@ int main(int argc, char *argv[])
 
 					if(bTargetHasTiva)
 						spiInfo.Signal(CSpiInfo::S_Resume);
+					else
+						adcInfo.Signal(CAdcInfo::S_Resume);
 				}
 			}
-			
+
 			if(bUpdateStgDevInfo)
 			{
 				if(!bOsIsHypervised)
@@ -326,15 +339,19 @@ int main(int argc, char *argv[])
 
 	if(bTargetHasTiva)
 		spiInfo.Signal(CSpiInfo::S_Terminate);
+	else
+		adcInfo.Signal(CAdcInfo::S_Terminate);
 
-	mySqlInfo.Join(NULL);
+	mySqlInfo.Join(nullptr);
 
 	if(!bOsIsHypervised)
-		stgDevInfo.Join(NULL);
+		stgDevInfo.Join(nullptr);
 
 	if(bTargetHasTiva)
-		spiInfo.Join(NULL);
-	
+		spiInfo.Join(nullptr);
+	else
+		adcInfo.Join(nullptr);
+
 	if(g_fZombie)
 	{
 		if(hAC)

+ 2 - 2
src/spiinfo.cpp

@@ -122,8 +122,8 @@ int CSpiInfo::ReadFirmwareVersion(int fd, GFA_SYSINFO_SPI &spi) const
 
 void* CSpiInfo::ThreadRoutine(void *pParam)
 {
-	LPEXEC_PARAMS pep = (LPEXEC_PARAMS)pParam;
     TRACE("Enter CSpiInfo::ThreadRoutine: TID: %ld\n", syscall(SYS_gettid));
+	LPEXEC_PARAMS pep = (LPEXEC_PARAMS)pParam;
 
 	if(pep)
 	{
@@ -307,5 +307,5 @@ void* CSpiInfo::ThreadRoutine(void *pParam)
 	}
 
 	TRACE("%s exit.\n", "CSpiInfo::ThreadRoutine");
-	return NULL;
+	return nullptr;
 }