123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <signal.h>
- #include <poll.h>
- #include <vector>
- #include <gfa/gfasitarautils.h>
- #include <gfa/gfaipc.h>
- #include "../src/defines.h"
- #include "app.h"
- /////////////////////////////////////////////////////////////////////////////
- #define _APPNAME_MQTTCL "MQTTCL"
- #define _APPNAME_REMANENT "Remanent"
- #define _APPNAME_REST "REST"
- #define _CTRL_MSG_HANG 0x08
- #define _CTRL_MSG_ALLOC 0x10
- #define _CTRL_MSG_FREE 0x20
- #define _HANG_LOOPS 1000000000
- #define _NORMAL_LOOPS 100000
- #define _MEM_WASTE_SIZE 524288
- /////////////////////////////////////////////////////////////////////////////
- #define UNUSED(v) (void)v
- static volatile bool g_fRun = false;
- static volatile bool g_fPause = false;
- static volatile bool g_fHang = false;
- static volatile bool g_fAlloc = false;
- static volatile bool g_fFree = false;
- /////////////////////////////////////////////////////////////////////////////
- static const char *g_pszStateNames[] =
- {
- "Not running",
- "Initializing",
- "Running",
- "Paused",
- "Hanging",
- "Terminating",
- "Invalid"
- };
- static std::vector<void*> g_vP;
- /////////////////////////////////////////////////////////////////////////////
- static void _SigHandler(int sig)
- {
- UNUSED(sig);
- g_fPause = false;
- g_fRun = false;
- }
- /////////////////////////////////////////////////////////////////////////////
- static int _InputAvailable(void)
- {
- static struct pollfd poIn[1] = {{0, POLLIN, 0}};
- int n = poll(poIn, 1, 0);
- return n;
- }
- /////////////////////////////////////////////////////////////////////////////
- static void _ProcessCtrlMessages(HAPPCTRL hAC, HAPPINFO hAI)
- {
- ctrlmsg_t nCtrlMsg;
- while(g_fRun && (nCtrlMsg = ::GfaIpcAppCtrlGetNextCtrlMsg(hAI)))
- {
- switch(nCtrlMsg)
- {
- case GFA_APPCTRL_CTRLMSG_STOP:
- g_fRun = false;
- TRACE("Received Message: STOP!\n");
- break;
- case GFA_APPCTRL_CTRLMSG_PAUSE:
- if(!g_fPause)
- {
- g_fPause = true;
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Paused);
- TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Paused]);
- }
- break;
- case GFA_APPCTRL_CTRLMSG_RESUME:
- if(g_fPause)
- {
- g_fPause = false;
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
- TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
- }
- break;
- case _CTRL_MSG_HANG:
- g_fHang = true;
- break;
- case _CTRL_MSG_ALLOC:
- g_fAlloc = true;
- break;
- case _CTRL_MSG_FREE:
- g_fFree = true;
- break;
- default:
- break;
- }
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- static void _ProcessStateEvents(HAPPCTRL hAC, HAPPINFO hAI)
- {
- appid_t nAppIdSrc;
- char szDispName[128];
- while(g_fRun && (nAppIdSrc = ::GfaIpcAppCtrlGetNextStateEvtSrc(hAI)))
- {
- GfaIpcAppStates state = ::GfaIpcAppCtrlGetState(hAC, nAppIdSrc);
- GfaIpcAppCtrlGetDisplayName(hAC, nAppIdSrc, szDispName, sizeof(szDispName));
- TRACE("%-8s: State: %s\n", szDispName, g_pszStateNames[state]);
- switch(nAppIdSrc)
- {
- case GFA_APPCTRL_APPID_REMANENT:
- if(state == GIAS_Running)
- {
- if(g_fPause)
- {
- g_fPause = false;
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
- TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
- }
- }
- else
- {
- if(!g_fPause)
- {
- g_fPause = true;
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Paused);
- TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Paused]);
- }
- }
- break;
- case GFA_APPCTRL_APPID_REST:
- break;
- case GFA_APPCTRL_APPID_MQTTCL:
- break;
- }
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- static void _ProcessInput(HAPPCTRL hAC)
- {
- if(_InputAvailable())
- {
- ctrlmsg_t msg = 0;
- appid_t aiTarget = 0;
- int nRet = scanf("%llu %llu", &aiTarget, &msg);
- if(nRet == 2)
- {
- ::GfaIpcAppCtrlSendCtrlMsg(hAC, aiTarget, msg);
- }
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- static int _DoWork(void)
- {
- int i, j = 0, k = _NORMAL_LOOPS;
- if(g_fAlloc)
- {
- TRACE("Wasting %d KiB of memory.\n", _MEM_WASTE_SIZE >> 10);
- void *p = malloc(_MEM_WASTE_SIZE);
- g_vP.push_back(p);
- g_fAlloc = false;
- UNUSED(p);
- }
- if(g_fFree)
- {
- TRACE("Freeing memory.\n");
- for(auto i = g_vP.begin(); i != g_vP.end(); i++)
- {
- free(*i);
- }
- g_vP.clear();
- g_fFree = false;
- }
- if(g_fHang)
- {
- k = _HANG_LOOPS;
- TRACE("Performing %d nonsense loops.\n", k);
- g_fHang = false;
- }
- for(i = 0; i < k; ++i)
- {
- j += 4;
- j -= 2;
- j += 1;
- j -= 3;
- }
- return j;
- }
- /////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
- int main(void)
- {
- HAPPCTRL hAC = NULL;
- HAPPINFO hAI;
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- // signal handling
- struct sigaction sa;
- memset(&sa, 0, sizeof(sa));
- // handle signals
- 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'
- // 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
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- // initialize
- do
- {
- if(!(hAC = ::GfaIpcAppCtrlAcquire(_APPID_0, _APPNAME_0, _CYCLE_INTV * 1000, _CYCLE_INTV * 3000)))
- break;
- ;;GfaIpcDumpSHMROT();
- ::GfaIpcAppCtrlPresetDisplayName(hAC, GFA_APPCTRL_APPID_USER_01, "qmlApp");
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Initializing);
- if(!::GfaIpcAppCtrlSubscribeStateEvents(hAC, _APPID_1 | _APPID_2 | GFA_APPCTRL_APPID_USER_01))
- break;
- TRACE("My Name: %s\n", _APPNAME_0);
- TRACE("My AppID: %llu\n", _APPID_0);
- TRACE("My PID: %d\n", getpid());
- TRACE("My Cycle: %d\n", _CYCLE_INTV);
- g_fRun = true;
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
- }
- while(false);
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- // run
- CCycleTimer ct(_CYCLE_INTV);
- cy_time_t wStart, wEnd, wCur = 0;
- while(g_fRun)
- {
- /////////////////////////////////////////////////////////////////////
- // trigger cycle timer
- ct.Trigger();
- /////////////////////////////////////////////////////////////////////
- // test input
- _ProcessInput(hAC);
- /////////////////////////////////////////////////////////////////////
- // update app control info
- if((hAI = ::GfaIpcAppCtrlInfoUpdate(hAC, wCur)))
- {
- _ProcessCtrlMessages(hAC, hAI);
- _ProcessStateEvents(hAC, hAI);
- }
- /////////////////////////////////////////////////////////////////////
- // if not paused, do work
- if(!g_fPause && g_fRun)
- {
- wStart = ct.GetMicroTick();
- _DoWork();
- wEnd = ct.GetMicroTick();
- wCur = wEnd - wStart;
- }
- /////////////////////////////////////////////////////////////////////
- // if running, sleep
- if(g_fRun)
- ct.Sleep1();
- }
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- // terminate
- if(hAC)
- {
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Terminating);
- ::GfaIpcAppCtrlRelease(hAC);
- }
- return 0;
- }
|