ticket.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #include "ticket.h"
  2. static T_UINT32 ticket;
  3. //清空投票
  4. void ticketReset(void){
  5. int i;
  6. ticket=0;
  7. for(i=0;i<TICKET_PT_MAX;i++) ticketDeVote(i);
  8. }
  9. //投票
  10. void ticketVote(TICKET_ENUM vote){
  11. #if defined ENABLE_TICKET
  12. ticket &= ~(1<<vote);
  13. #endif
  14. }
  15. //撤票
  16. void ticketDeVote(TICKET_ENUM vote){
  17. #if defined ENABLE_TICKET
  18. ticket |= 1<<vote;
  19. #endif
  20. }
  21. //投票结果
  22. static T_BOOL isTicketReady(void){
  23. if(0==ticket) return TRUE;
  24. else return FALSE;
  25. }
  26. LSAPI_OSI_Thread_t *timeThread=NULL;
  27. LSAPI_OSI_Timer_t *ptimer_t = NULL;
  28. static T_BOOL timerSleepStatus=FALSE;
  29. void Timeroutcallback(void *param){
  30. wlog_info("Timeroutcallback enter");
  31. LSAPI_OSI_TimerStop(ptimer_t);
  32. threadPostEvent(timeThread,USER_EVENT_TIMEOUT,NULL);
  33. }
  34. /*
  35. 串口、网络等唤醒深度睡眠接口
  36. */
  37. void WakeupNow(char *name){
  38. #if defined ENABLE_TICKET
  39. if(ptimer_t==NULL || timeThread==NULL || timerSleepStatus==FALSE) return;
  40. wlog_info("WakeupNow by %s",name);
  41. LSAPI_OSI_TimerStop(ptimer_t);
  42. threadPostEvent(timeThread,USER_EVENT_TIMEOUT,NULL);
  43. #endif
  44. }
  45. static T_INT32 geMintWaitCnt(void);
  46. static void addWaitCnt(T_INT32 value);
  47. PT_THREAD (ptTicketTask(pt_timer_t *ptPool, struct pt *pt)){
  48. static pt_timer_t ptTimer;
  49. static T_UINT8 sleepDlyTime;
  50. T_INT32 value;
  51. static T_UINT32 sleeptime;
  52. static int64_t lastSleepTime;
  53. char info[30];
  54. PT_BEGIN(pt);
  55. while(1){
  56. if(FALSE==isTicketReady()) sleepDlyTime=0;
  57. else{
  58. if(++sleepDlyTime>=2){//延时2秒睡
  59. sleepDlyTime=0;
  60. //开启下次唤醒的定时器,也就是发心跳的时刻即可
  61. value=geMintWaitCnt();
  62. if(value>0){
  63. sleeptime=value*1000;
  64. snprintf(info, sizeof(info),"WaitEventTime:%d\r\n",value);
  65. outterInfo(info, strlen(info));
  66. //wlog_info("lastSleepTime:%d",value);
  67. timeThread=LSAPI_OSI_ThreadCurrent();
  68. if(NULL == ptimer_t) ptimer_t = LSAPI_OSI_TimerCreate(timeThread, Timeroutcallback, NULL);
  69. if(NULL != ptimer_t){
  70. if(FALSE==LSAPI_OSI_TimerStart(ptimer_t, sleeptime)){
  71. wlog_warn("sleep timer start failed");
  72. goto TICKET_END;
  73. }
  74. }else{
  75. wlog_warn("sleep timer create failed");
  76. goto TICKET_END;
  77. }
  78. lastSleepTime=LSAPI_OSI_UpTime();
  79. LSAPI_OSI_Event_t event = {};
  80. timerSleepStatus=TRUE;
  81. while(1){
  82. LSAPI_OSI_EventWait(timeThread, &event);
  83. if(event.id==USER_EVENT_TIMEOUT) break;
  84. }
  85. value=(LSAPI_OSI_UpTime()-lastSleepTime)/1000;
  86. ticketReset();
  87. timerSleepStatus=FALSE;
  88. //检测是否为负值,是否有可能获取时间的API会出现异常,导致出现负值,如果是负值,则使用sleeptime,可能有一秒误差,但没关系
  89. if(value<0) value=sleeptime/1000;//fanghu
  90. addWaitCnt(value);//更新相关计数器
  91. }
  92. }
  93. }
  94. TICKET_END:
  95. PTTimerStart(ptPool, &ptTimer,100);//need set to 1 seconds
  96. PT_WAIT_UNTIL(pt, PTTimerIsExpired(&ptTimer));
  97. }
  98. PT_END(pt);
  99. }
  100. static T_INT32 geMintWaitCnt(void){
  101. //获取所有计数器,并得出最小值
  102. #define VALUE_SIZE 6
  103. T_INT32 value[VALUE_SIZE],temp,i;
  104. temp=NO_SLEEP_TIME;
  105. for(i=0;i<VALUE_SIZE;i++) value[i]=NO_SLEEP_TIME;
  106. i=0;
  107. value[i++]=getAuthLoginCnt();
  108. value[i++]=getMaipCnt();
  109. value[i++]=getLocationCnt();
  110. value[i++]=getGnssCnt();
  111. value[i++]=getNearCnt();
  112. value[i++]=getHeartCnt();
  113. for(i=0;i<VALUE_SIZE;i++){
  114. temp=(value[i]>temp)?temp:value[i];
  115. }
  116. return temp;
  117. }
  118. static void addWaitCnt(T_INT32 value){
  119. //更新所有计数器值
  120. authLoginCntUpdate(value);
  121. miapCntUpdate(value);
  122. locationCntUpdate(value);
  123. //gnss,near使用的是本地时间,不需要更新
  124. heartCntUpdate(value);
  125. }
  126. /*定时显示一下票箱状态*/
  127. void ticketStatusShow(void){
  128. static unsigned char cnt=0;
  129. char info[100]="TICKET:";
  130. char tbuf[10];
  131. unsigned char i;
  132. if(cnt==0){
  133. if(ticket==0) wlog_info("TICKET:Idle");
  134. else{
  135. for(i=TICKET_PT_DOMAIN;i<TICKET_PT_MAX;i++){
  136. if(ticket & (1<<i)){
  137. snprintf(tbuf, sizeof(tbuf), "%d ",i);
  138. strcat(info, tbuf);
  139. }
  140. }
  141. wlog_info(info);
  142. }
  143. }
  144. if(++cnt>=10) cnt=0;//10秒打印一次
  145. }