main.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <signal.h>
  5. #include <poll.h>
  6. #include <vector>
  7. #include <gfa/gfasitarautils.h>
  8. #include <gfa/gfaipc.h>
  9. #include "../src/defines.h"
  10. #include "app.h"
  11. /////////////////////////////////////////////////////////////////////////////
  12. #define _APPNAME_MQTTCL "MQTTCL"
  13. #define _APPNAME_REMANENT "Remanent"
  14. #define _APPNAME_REST "REST"
  15. #define _CTRL_MSG_HANG 0x08
  16. #define _CTRL_MSG_ALLOC 0x10
  17. #define _CTRL_MSG_FREE 0x20
  18. #define _HANG_LOOPS 1000000000
  19. #define _NORMAL_LOOPS 100000
  20. #define _MEM_WASTE_SIZE 524288
  21. /////////////////////////////////////////////////////////////////////////////
  22. #define UNUSED(v) (void)v
  23. static volatile bool g_fRun = false;
  24. static volatile bool g_fPause = false;
  25. static volatile bool g_fHang = false;
  26. static volatile bool g_fAlloc = false;
  27. static volatile bool g_fFree = false;
  28. /////////////////////////////////////////////////////////////////////////////
  29. static const char *g_pszStateNames[] =
  30. {
  31. "Not running",
  32. "Initializing",
  33. "Running",
  34. "Paused",
  35. "Hanging",
  36. "Terminating",
  37. "Invalid"
  38. };
  39. static std::vector<void*> g_vP;
  40. /////////////////////////////////////////////////////////////////////////////
  41. static void _SigHandler(int sig)
  42. {
  43. UNUSED(sig);
  44. g_fPause = false;
  45. g_fRun = false;
  46. }
  47. /////////////////////////////////////////////////////////////////////////////
  48. static int _InputAvailable(void)
  49. {
  50. static struct pollfd poIn[1] = {{0, POLLIN, 0}};
  51. int n = poll(poIn, 1, 0);
  52. return n;
  53. }
  54. /////////////////////////////////////////////////////////////////////////////
  55. static void _ProcessCtrlMessages(HAPPCTRL hAC, HAPPINFO hAI)
  56. {
  57. ctrlmsg_t nCtrlMsg;
  58. while(g_fRun && (nCtrlMsg = ::GfaIpcAppCtrlGetNextCtrlMsg(hAI)))
  59. {
  60. switch(nCtrlMsg)
  61. {
  62. case GFA_APPCTRL_CTRLMSG_STOP:
  63. g_fRun = false;
  64. TRACE("Received Message: STOP!\n");
  65. break;
  66. case GFA_APPCTRL_CTRLMSG_PAUSE:
  67. if(!g_fPause)
  68. {
  69. g_fPause = true;
  70. ::GfaIpcAppCtrlSetState(hAC, GIAS_Paused);
  71. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Paused]);
  72. }
  73. break;
  74. case GFA_APPCTRL_CTRLMSG_RESUME:
  75. if(g_fPause)
  76. {
  77. g_fPause = false;
  78. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  79. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
  80. }
  81. break;
  82. case _CTRL_MSG_HANG:
  83. g_fHang = true;
  84. break;
  85. case _CTRL_MSG_ALLOC:
  86. g_fAlloc = true;
  87. break;
  88. case _CTRL_MSG_FREE:
  89. g_fFree = true;
  90. break;
  91. default:
  92. break;
  93. }
  94. }
  95. }
  96. /////////////////////////////////////////////////////////////////////////////
  97. static void _ProcessStateEvents(HAPPCTRL hAC, HAPPINFO hAI)
  98. {
  99. appid_t nAppIdSrc;
  100. char szDispName[128];
  101. while(g_fRun && (nAppIdSrc = ::GfaIpcAppCtrlGetNextStateEvtSrc(hAI)))
  102. {
  103. GfaIpcAppStates state = ::GfaIpcAppCtrlGetState(hAC, nAppIdSrc);
  104. GfaIpcAppCtrlGetDisplayName(hAC, nAppIdSrc, szDispName, sizeof(szDispName));
  105. TRACE("%-8s: State: %s\n", szDispName, g_pszStateNames[state]);
  106. switch(nAppIdSrc)
  107. {
  108. case GFA_APPCTRL_APPID_REMANENT:
  109. if(state == GIAS_Running)
  110. {
  111. if(g_fPause)
  112. {
  113. g_fPause = false;
  114. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  115. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
  116. }
  117. }
  118. else
  119. {
  120. if(!g_fPause)
  121. {
  122. g_fPause = true;
  123. ::GfaIpcAppCtrlSetState(hAC, GIAS_Paused);
  124. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Paused]);
  125. }
  126. }
  127. break;
  128. case GFA_APPCTRL_APPID_REST:
  129. break;
  130. case GFA_APPCTRL_APPID_MQTTCL:
  131. break;
  132. }
  133. }
  134. }
  135. /////////////////////////////////////////////////////////////////////////////
  136. static void _ProcessInput(HAPPCTRL hAC)
  137. {
  138. if(_InputAvailable())
  139. {
  140. ctrlmsg_t msg = 0;
  141. appid_t aiTarget = 0;
  142. int nRet = scanf("%llu %llu", &aiTarget, &msg);
  143. if(nRet == 2)
  144. {
  145. ::GfaIpcAppCtrlSendCtrlMsg(hAC, aiTarget, msg);
  146. }
  147. }
  148. }
  149. /////////////////////////////////////////////////////////////////////////////
  150. static int _DoWork(void)
  151. {
  152. int i, j = 0, k = _NORMAL_LOOPS;
  153. if(g_fAlloc)
  154. {
  155. TRACE("Wasting %d KiB of memory.\n", _MEM_WASTE_SIZE >> 10);
  156. void *p = malloc(_MEM_WASTE_SIZE);
  157. g_vP.push_back(p);
  158. g_fAlloc = false;
  159. UNUSED(p);
  160. }
  161. if(g_fFree)
  162. {
  163. TRACE("Freeing memory.\n");
  164. for(auto i = g_vP.begin(); i != g_vP.end(); i++)
  165. {
  166. free(*i);
  167. }
  168. g_vP.clear();
  169. g_fFree = false;
  170. }
  171. if(g_fHang)
  172. {
  173. k = _HANG_LOOPS;
  174. TRACE("Performing %d nonsense loops.\n", k);
  175. g_fHang = false;
  176. }
  177. for(i = 0; i < k; ++i)
  178. {
  179. j += 4;
  180. j -= 2;
  181. j += 1;
  182. j -= 3;
  183. }
  184. return j;
  185. }
  186. /////////////////////////////////////////////////////////////////////////////
  187. /////////////////////////////////////////////////////////////////////////////
  188. /////////////////////////////////////////////////////////////////////////////
  189. int main(void)
  190. {
  191. HAPPCTRL hAC = NULL;
  192. HAPPINFO hAI;
  193. /////////////////////////////////////////////////////////////////////////
  194. /////////////////////////////////////////////////////////////////////////
  195. /////////////////////////////////////////////////////////////////////////
  196. // signal handling
  197. struct sigaction sa;
  198. memset(&sa, 0, sizeof(sa));
  199. // handle signals
  200. sa.sa_handler = _SigHandler;
  201. sigaction(SIGHUP, &sa, NULL); // handles user's terminal disconnect
  202. sigaction(SIGQUIT, &sa, NULL); // handles Ctrl + '\'
  203. sigaction(SIGTERM, &sa, NULL); // handles normal termination
  204. sigaction(SIGABRT, &sa, NULL); // handles abnormal termination (i.e. abort())
  205. sigaction(SIGINT, &sa, NULL); // handles Ctrl + 'C'
  206. // ignore signals
  207. sa.sa_handler = SIG_IGN;
  208. sigaction(SIGTSTP, &sa, NULL); // ignores Ctrl + 'Z'
  209. sigaction(SIGCHLD, &sa, NULL); // ignores child process termination
  210. sigaction(0, &sa, NULL); // ignores shell termination
  211. /////////////////////////////////////////////////////////////////////////
  212. /////////////////////////////////////////////////////////////////////////
  213. /////////////////////////////////////////////////////////////////////////
  214. // initialize
  215. do
  216. {
  217. if(!(hAC = ::GfaIpcAppCtrlAcquire(_APPID_0, _APPNAME_0, _CYCLE_INTV * 1000, _CYCLE_INTV * 3000)))
  218. break;
  219. ;;GfaIpcDumpSHMROT();
  220. ::GfaIpcAppCtrlPresetDisplayName(hAC, GFA_APPCTRL_APPID_USER_01, "qmlApp");
  221. ::GfaIpcAppCtrlSetState(hAC, GIAS_Initializing);
  222. if(!::GfaIpcAppCtrlSubscribeStateEvents(hAC, _APPID_1 | _APPID_2 | GFA_APPCTRL_APPID_USER_01))
  223. break;
  224. TRACE("My Name: %s\n", _APPNAME_0);
  225. TRACE("My AppID: %llu\n", _APPID_0);
  226. TRACE("My PID: %d\n", getpid());
  227. TRACE("My Cycle: %d\n", _CYCLE_INTV);
  228. g_fRun = true;
  229. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  230. }
  231. while(false);
  232. /////////////////////////////////////////////////////////////////////////
  233. /////////////////////////////////////////////////////////////////////////
  234. /////////////////////////////////////////////////////////////////////////
  235. // run
  236. CCycleTimer ct(_CYCLE_INTV);
  237. cy_time_t wStart, wEnd, wCur = 0;
  238. while(g_fRun)
  239. {
  240. /////////////////////////////////////////////////////////////////////
  241. // trigger cycle timer
  242. ct.Trigger();
  243. /////////////////////////////////////////////////////////////////////
  244. // test input
  245. _ProcessInput(hAC);
  246. /////////////////////////////////////////////////////////////////////
  247. // update app control info
  248. if((hAI = ::GfaIpcAppCtrlInfoUpdate(hAC, wCur)))
  249. {
  250. _ProcessCtrlMessages(hAC, hAI);
  251. _ProcessStateEvents(hAC, hAI);
  252. }
  253. /////////////////////////////////////////////////////////////////////
  254. // if not paused, do work
  255. if(!g_fPause && g_fRun)
  256. {
  257. wStart = ct.GetMicroTick();
  258. _DoWork();
  259. wEnd = ct.GetMicroTick();
  260. wCur = wEnd - wStart;
  261. }
  262. /////////////////////////////////////////////////////////////////////
  263. // if running, sleep
  264. if(g_fRun)
  265. ct.Sleep1();
  266. }
  267. /////////////////////////////////////////////////////////////////////////
  268. /////////////////////////////////////////////////////////////////////////
  269. /////////////////////////////////////////////////////////////////////////
  270. // terminate
  271. if(hAC)
  272. {
  273. ::GfaIpcAppCtrlSetState(hAC, GIAS_Terminating);
  274. ::GfaIpcAppCtrlRelease(hAC);
  275. }
  276. return 0;
  277. }