gg_external_data.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * Copyright 2024 NXP
  3. * NXP Proprietary. This software is owned or controlled by NXP and may only be used strictly in
  4. * accordance with the applicable license terms. By expressly accepting such terms or by downloading, installing,
  5. * activating and/or otherwise using the software, you are agreeing that you have read, and that you agree to
  6. * comply with and are bound by, such license terms. If you do not agree to be bound by the applicable license
  7. * terms, then you may not retain, install, activate or otherwise use the software.
  8. */
  9. /*********************
  10. * INCLUDES
  11. *********************/
  12. #include <time.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include "lv_ll.h"
  16. #include "gg_external_data.h"
  17. #include "freemaster_client.h"
  18. #include <pthread.h>
  19. #if LV_USE_GUIDER_SIMULATOR && LV_USE_FREEMASTER
  20. /* Define a global variables */
  21. lv_ll_t GG_EDATA_TASK_LN;
  22. extern pthread_mutex_t gg_edata_ll_mutex;
  23. extern pthread_cond_t gg_edata_ll_cond;
  24. extern volatile int keep_running;
  25. bool gg_edata_ll_changed = false;
  26. uint64_t gg_get_us_time() {
  27. struct timespec ts;
  28. if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
  29. fprintf(stderr, "\nFailed to get time.");
  30. exit(EXIT_FAILURE);
  31. }
  32. return (uint64_t) (ts.tv_sec * 1000000 + ts.tv_nsec / 1000);
  33. }
  34. uint64_t gg_get_ms_time() {
  35. struct timespec ts;
  36. if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
  37. fprintf(stderr, "\nFailed to get time.");
  38. exit(EXIT_FAILURE);
  39. }
  40. return (uint64_t) (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
  41. }
  42. void gg_nanosleep(int ns) {
  43. struct timespec remaining, request = { 0, ns };
  44. nanosleep(&request, &remaining);
  45. }
  46. void gg_edata_task_init(void) {
  47. _lv_ll_init(&GG_EDATA_TASK_LN, sizeof(gg_edata_task_t));
  48. }
  49. void gg_edata_task_clear(lv_obj_t * act_scr) {
  50. #ifdef DEBUG
  51. fprintf(stdout, "External data: clear task list...\n");
  52. #endif
  53. pthread_mutex_lock(&gg_edata_ll_mutex);
  54. //_lv_ll_clear(&GG_EDATA_TASK_LN);
  55. gg_edata_task_t * head;
  56. head = _lv_ll_get_head(&GG_EDATA_TASK_LN);
  57. while (head) {
  58. bool task_deleted = false;
  59. readVariableParm *param = head->param;
  60. if (param->screen == act_scr) {
  61. task_deleted = true;
  62. gg_edata_ll_changed = true;
  63. _lv_ll_remove(&GG_EDATA_TASK_LN, head);
  64. }
  65. if(task_deleted)
  66. head = _lv_ll_get_head(&GG_EDATA_TASK_LN);
  67. else
  68. head = _lv_ll_get_next(&GG_EDATA_TASK_LN, head);
  69. }
  70. pthread_mutex_unlock(&gg_edata_ll_mutex);
  71. #ifdef DEBUG
  72. fprintf(stdout, "External data: clear task list [Done]\n");
  73. #endif
  74. }
  75. gg_edata_task_t * gg_edata_task_create(uint32_t period, gg_edata_task_cb_t cb, void * param)
  76. {
  77. pthread_mutex_lock(&gg_edata_ll_mutex);
  78. gg_edata_task_t * new_task = NULL;
  79. new_task = _lv_ll_ins_head(&GG_EDATA_TASK_LN);
  80. if(new_task != NULL) {
  81. new_task->last_time = 0;
  82. new_task->period = period;
  83. new_task->cb = cb;
  84. new_task->param = param;
  85. gg_edata_ll_changed = true;
  86. pthread_cond_signal(&gg_edata_ll_cond);
  87. #ifdef DEBUG
  88. fprintf(stdout, "External data: create new task.\n");
  89. #endif
  90. }
  91. pthread_mutex_unlock(&gg_edata_ll_mutex);
  92. return new_task;
  93. }
  94. void *gg_edata_task_exec()
  95. {
  96. gg_edata_task_t * head;
  97. head = _lv_ll_get_head(&GG_EDATA_TASK_LN);
  98. while(keep_running) {
  99. pthread_mutex_lock(&gg_edata_ll_mutex);
  100. /* always check the link. After screen transition, old screen is
  101. * deleted and new screen may have NO external data task
  102. */
  103. while (keep_running && _lv_ll_is_empty(&GG_EDATA_TASK_LN)) {
  104. #ifdef DEBUG
  105. fprintf(stdout, "External data: wait for task...\n");
  106. #endif
  107. /*no task, wait for signal and release the lock*/
  108. pthread_cond_wait(&gg_edata_ll_cond, &gg_edata_ll_mutex);
  109. }
  110. if (gg_edata_ll_changed || head == NULL) {
  111. head = _lv_ll_get_head(&GG_EDATA_TASK_LN);
  112. } else {
  113. head = _lv_ll_get_next(&GG_EDATA_TASK_LN, head);
  114. }
  115. if(head != NULL) {
  116. gg_edata_ll_changed = false;
  117. uint64_t currentTime = gg_get_ms_time();
  118. uint64_t realExecTime = (head->period) + (head->last_time);
  119. if(head->last_time == 0 || currentTime > realExecTime) {
  120. head->cb(head->param);
  121. head->last_time = currentTime;
  122. }
  123. }
  124. pthread_mutex_unlock(&gg_edata_ll_mutex);
  125. gg_nanosleep(100);
  126. }
  127. }
  128. #endif