main.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*
  2. main.c
  3. authod: wjl
  4. 应用程序主要使用pt来完成
  5. */
  6. #include "includes.h"
  7. //pt任务部分声明
  8. pt_timer_t pt_timerPool;
  9. struct pt pt_NetWorkTask;
  10. struct pt pt_QueueComReadTask;
  11. struct pt pt_QueueRecordReadTask;
  12. struct pt pt_DomainTask;
  13. struct pt pt_TTSTask;
  14. struct pt pt_PlayerTask;
  15. struct pt pt_RecorderTask;
  16. struct pt pt_AuthLoginTask;
  17. struct pt pt_LocationTask;
  18. struct pt pt_McuIapTask;
  19. struct pt pt_LbsMotionTask;
  20. struct pt pt_HookTask;
  21. struct pt pt_NearTask;
  22. struct pt pt_VoiceUploadTask;
  23. struct pt pt_HearTickTask;
  24. #ifdef ENABLE_ANT_MODE
  25. struct pt pt_McuAckTask;
  26. #endif
  27. #if defined ENABLE_TICKET
  28. struct pt pt_TicketTask;
  29. #endif
  30. /*读取模块相关信息*/
  31. void modemInfoRead(void){
  32. snprintf(app.opVersion,sizeof(app.opVersion),"%s",LSAPI_SYS_getOPVERSION());
  33. wlog_info("OpVersion:%s",app.opVersion);
  34. snprintf(app.fmVersion,sizeof(app.fmVersion),"%s",LSAPI_SYS_getFMVERSION());
  35. wlog_info("FmVersion:%s",app.fmVersion);
  36. }
  37. /*
  38. ptTickRun
  39. pt 需要的时间池用于pt任务调试
  40. */
  41. void ptTickRun(void){
  42. PTTimerTick(&pt_timerPool); //pt需要的系统时钟,最好是准确的
  43. }
  44. //初始化数据及外设接口
  45. static void InitStart(void){
  46. if(0!=msgQueueSet()){//初始化消息队列
  47. wlog_error("msgQueueSet err");
  48. }
  49. app_init();//应用数据测试,需要比para_inits先调用
  50. para_inits();//系统参数测试,需要在app_init后调用
  51. recordsInit();//初始化记录文件区
  52. authLoginInit();
  53. onWorkChecking(TRUE);
  54. onWorkTimerInit();
  55. userTimerInit();
  56. bspInit();//外设部分初始化
  57. #ifdef ENABLE_ANT_MODE
  58. wlog_info("%s VER:%s MODULE:%s TEST:%d CUST:%d ant mode start...", APP_NAME, APP_VERSION, APP_MODULE_TYPE, APP_TEST, APP_CUSTOMER);
  59. #else
  60. wlog_info("%s VER:%s MODULE:%s TEST:%d CUST:%d start...", APP_NAME, APP_VERSION, APP_MODULE_TYPE, APP_TEST, APP_CUSTOMER);
  61. #endif
  62. //先发消息,MCU先把电源锁住
  63. setInitMcu();
  64. //再振动
  65. vibraNow();
  66. //检测是否有未播放文件
  67. if(TRUE==vFileGetUnplaySet()) vibratWorkNow(TRUE);
  68. }
  69. #ifdef ENABLE_ANT_MODE
  70. PT_THREAD (ptMcuAckTask(pt_timer_t *ptPool, struct pt *pt)){
  71. static pt_timer_t ptTimer;
  72. //定时发设置MCU指令给MCU
  73. PT_BEGIN(pt);
  74. while(1){
  75. setInitMcu();
  76. PTTimerStart(ptPool, &ptTimer,500);//need set to 1 seconds
  77. PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
  78. }
  79. PT_END(pt);
  80. }
  81. #endif
  82. /*
  83. taskRun
  84. 应用程序主要任务入口
  85. */
  86. static void taskRun(void){
  87. //深度休眠投票:每个PT如果空闲了,则向属于自己的票据投上
  88. //当票箱满员后,当前任务开启一个下次唤醒的定时器,并交出系统资源调度
  89. #ifndef ENABLE_ANT_MODE //天线调试模式
  90. if(app.tgMode==FALSE){
  91. //ptDomainTask-->domain.c 负责域名解析任务,应用将需要解析的要求推入域名列队,域名任务会自动消耗
  92. ptDomainTask(&pt_timerPool, &pt_DomainTask);//has better run first
  93. //ptNetWorkTask-->netWork.c 负责网络任务,包括注册,拨号,设备硬件参数等
  94. ptNetWorkTask(&pt_timerPool, &pt_NetWorkTask);
  95. //ptQueueRecordReadTask-->plyRec.c 语音消息队列读取任务
  96. ptQueueRecordReadTask(&pt_timerPool, &pt_QueueRecordReadTask);
  97. //ptTTSTask-->tts.c TTS播报任务
  98. ptTTSTask(&pt_timerPool, &pt_TTSTask);
  99. //ptPlayerTask-->plyRec.c 对讲语音播放逻辑控制任务
  100. ptPlayerTask(&pt_timerPool, &pt_PlayerTask);
  101. //ptRecorderTask-->plyRec.c 对讲语音录制逻辑控制任务
  102. ptRecorderTask(&pt_timerPool, &pt_RecorderTask);
  103. //ptAuthLoginTask-->authlogin.c 系统开机后登陆IOT服务器
  104. ptAuthLoginTask(&pt_timerPool, &pt_AuthLoginTask);
  105. //ptLocationTask-->location.c 负责处理GPS跟LSB业务
  106. ptLocationTask(&pt_timerPool, &pt_LocationTask);
  107. //ptMcuIapTask-->mcuIap.c 负责处理更新IAP的业务
  108. ptMcuIapTask(&pt_timerPool, &pt_McuIapTask);
  109. //ptLbsMotionTask-->location.c 负责LSB处理业务
  110. ptLbsMotionTask(&pt_timerPool, &pt_LbsMotionTask);
  111. //ptHookTask-->hook.c 钩子任务
  112. ptHookTask(&pt_timerPool, &pt_HookTask);
  113. //ptNearTask-->location.c 负责附近信息业务的收集
  114. ptNearTask(&pt_timerPool, &pt_NearTask);
  115. //ptVoiceUploadTask-->plyRec.c 录制语音上传服务器任务控制
  116. ptVoiceUploadTask(&pt_timerPool, &pt_VoiceUploadTask);
  117. //ptHearTickTask-->authlogin.c
  118. // ptHearTickTask(&pt_timerPool, &pt_HearTickTask);//请放在ptAuthLoginTask后面调用
  119. #if defined ENABLE_TICKET
  120. //ptTickTask-->ticket.c 深度睡眠任务
  121. ptTicketTask(&pt_timerPool, &pt_TicketTask);
  122. #endif
  123. }
  124. #else
  125. ptMcuAckTask(&pt_timerPool, &pt_McuAckTask);
  126. #endif
  127. if(FALSE==app.tmMode)
  128. //ptQueueComReadTask-->app.c 通用消息队列读取任务
  129. ptQueueComReadTask(&pt_timerPool, &pt_QueueComReadTask);
  130. }
  131. T_BOOL appQuit=FALSE;
  132. #ifdef USE_DETECTED_THREAD
  133. static unsigned int ptTickCnt=0;
  134. #endif
  135. /*定义一个定时器用于其它作用,比如按键SOS超时,定时器的话,在休眠时也能用*/
  136. LSAPI_OSI_Timer_t *ptimer_user = NULL;
  137. unsigned char userTimerFun=0;
  138. void userTimerCb(void *param){
  139. switch(userTimerFun){
  140. case 1:
  141. app.ksos=1;
  142. wlog_info("keyPress Timeout, vibra");
  143. vibraNow();
  144. if(app.onWorkZone==0 && sut_para.sosUpoadEnable_N==0) wlog_warn("un_onworkzone,sos disable, quit upload");
  145. else warnSendNow(WARN_SOS);
  146. break;
  147. }
  148. userTimerFun=0;
  149. if(NULL != ptimer_user) LSAPI_OSI_TimerStop(ptimer_user);
  150. }
  151. static void userTimerEntry(void *param){
  152. ptimer_user = LSAPI_OSI_TimerCreate(LSAPI_OSI_ThreadCurrent(), userTimerCb, NULL);
  153. if(NULL==ptimer_user){
  154. wlog_error("ptimer_user timer error !!!!!");
  155. return;
  156. }
  157. wlog_info("ptimer_user entry start ok");
  158. LSAPI_OSI_Event_t event = {};
  159. for(;;){LSAPI_OSI_EventWait(LSAPI_OSI_ThreadCurrent(), &event);}
  160. LSAPI_OSI_ThreadExit();
  161. }
  162. void userTimerInit(void){
  163. if(NULL==LSAPI_OSI_ThreadCreate("userTimerEntry", userTimerEntry, NULL, LSAPI_OSI_PRIORITY_NORMAL, USER_TIMER_THREAD_STACK, 4)){
  164. wlog_error("userTimer Thread create failed!");
  165. }
  166. }
  167. void userTimerStart(T_UINT32 timeMs,unsigned char fun){
  168. if(NULL==ptimer_user){
  169. wlog_error("ptimer_user null, start failed");
  170. return;
  171. }
  172. wlog_info("userTimerStart:%d ms",timeMs);
  173. userTimerFun=fun;
  174. LSAPI_OSI_TimerStart(ptimer_user, timeMs);
  175. }
  176. void userTimerSTOP(void){
  177. wlog_info("userTimer stop");
  178. if(NULL != ptimer_user) LSAPI_OSI_TimerStop(ptimer_user);
  179. }
  180. //主线程根据系统时间产生pt心跳,系统可以休眠
  181. static int64_t lasttimems;
  182. /*pt心跳*/
  183. void ptTimePro(void){
  184. int i;
  185. int64_t timems,j;
  186. timems=LSAPI_OSI_UpTime();
  187. j=timems-lasttimems;
  188. if(j>=10){
  189. for(i=0;i<j/10;i++) ptTickRun();
  190. lasttimems=timems-j%10;
  191. }else if(j<0) lasttimems=timems;//刷固件或其它情况,有可能LSAPI_OSI_UpTime返回的值有较大变化,会导致pt任务无法执行
  192. }
  193. void hpocRun(void){
  194. InitStart();
  195. wlog_info("start loop");
  196. modemInfoRead();
  197. lasttimems=LSAPI_OSI_UpTime();
  198. while(appQuit==FALSE){
  199. #ifdef USE_DETECTED_THREAD
  200. ptTickCnt++;
  201. #endif
  202. taskRun();
  203. LSAPI_OSI_ThreadSleep(5);
  204. ptTimePro();
  205. }
  206. }
  207. ///////////////////////////////////////////////
  208. #define TIME_OFFSET_SECOND 32*CFW_TIME_ZONE_SECOND
  209. int64_t getBaseSeconds(void){
  210. return (LSAPI_OSI_EpochSecond() + TIME_OFFSET_SECOND);
  211. }
  212. void getMyClock(MY_CLOCK *myclock){
  213. time_t lt = getBaseSeconds();
  214. struct tm ltm;
  215. gmtime_r(&lt, &ltm);
  216. myclock->year=ltm.tm_year + 1900;
  217. myclock->month=ltm.tm_mon+1;
  218. myclock->day=ltm.tm_mday;
  219. myclock->hour=ltm.tm_hour;//+USER_TIME_ZONE;
  220. myclock->min=ltm.tm_min;
  221. myclock->sec=ltm.tm_sec;
  222. }
  223. void setMyClock(MY_CLOCK myclock){
  224. struct tm ltm;
  225. memset(&ltm,0,sizeof(ltm));
  226. ltm.tm_year=myclock.year-1900;
  227. ltm.tm_mon=myclock.month-1;
  228. ltm.tm_mday=myclock.day;
  229. ltm.tm_hour=myclock.hour-USER_TIME_ZONE;
  230. ltm.tm_min=myclock.min;
  231. ltm.tm_sec=myclock.sec;
  232. LSAPI_OSI_SetEpochTime(1000*mktime(&ltm));
  233. }
  234. unsigned char *getBCDDateTime(void){
  235. static unsigned char bcdDate[6];
  236. MY_CLOCK myclock;
  237. getMyClock(&myclock);
  238. bcdDate[0]=decToBCD(myclock.year-2000);
  239. bcdDate[1]=decToBCD(myclock.month);
  240. bcdDate[2]=decToBCD(myclock.day);
  241. bcdDate[3]=decToBCD(myclock.hour);
  242. bcdDate[4]=decToBCD(myclock.min);
  243. bcdDate[5]=decToBCD(myclock.sec);
  244. return bcdDate;
  245. }
  246. #ifdef USE_DETECTED_THREAD
  247. //用于检测pt滴答是否正常
  248. void detector(void *param){
  249. char info[80];
  250. wlog_info("detector start");
  251. for(;;){
  252. LSAPI_OSI_ThreadSleep(500);
  253. snprintf(info, sizeof(info),"<tick>ptTickCnt:%d\r\n",ptTickCnt);
  254. outterInfo(info, strlen(info));
  255. }
  256. }
  257. #endif