2
0

Task.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #ifndef BELL_TASK_H
  2. #define BELL_TASK_H
  3. #ifdef ESP_PLATFORM
  4. #include <esp_pthread.h>
  5. #include <freertos/FreeRTOS.h>
  6. #include <freertos/timers.h>
  7. #include <freertos/task.h>
  8. #endif
  9. #include <pthread.h>
  10. namespace bell
  11. {
  12. class Task
  13. {
  14. public:
  15. std::string taskName;
  16. int stackSize, core;
  17. bool isRunning = false;
  18. bool runOnPSRAM;
  19. Task(std::string taskName, int stackSize, int priority, int core, bool runOnPSRAM = true)
  20. {
  21. this->taskName = taskName;
  22. this->stackSize = stackSize;
  23. this->core = core;
  24. this->runOnPSRAM = runOnPSRAM;
  25. #ifdef ESP_PLATFORM
  26. this->priority = ESP_TASK_PRIO_MIN + 1 + priority;
  27. if (this->priority < 0) this->priority = ESP_TASK_PRIO_MIN + 1;
  28. #endif
  29. }
  30. virtual ~Task() {}
  31. bool startTask()
  32. {
  33. #ifdef ESP_PLATFORM
  34. if (runOnPSRAM)
  35. {
  36. xTaskBuffer = (StaticTask_t *)heap_caps_malloc(sizeof(StaticTask_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
  37. xStack = (StackType_t *)heap_caps_malloc(this->stackSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
  38. return (xTaskCreateStaticPinnedToCore(taskEntryFuncPSRAM, this->taskName.c_str(), this->stackSize, this, 2, xStack, xTaskBuffer, this->core) != NULL);
  39. }
  40. else
  41. {
  42. esp_pthread_cfg_t cfg = esp_pthread_get_default_config();
  43. cfg.stack_size = stackSize;
  44. cfg.inherit_cfg = true;
  45. cfg.thread_name = this->taskName.c_str();
  46. cfg.pin_to_core = core;
  47. cfg.prio = priority;
  48. esp_pthread_set_cfg(&cfg);
  49. }
  50. #endif
  51. return (pthread_create(&_thread, NULL, taskEntryFunc, this) == 0);
  52. }
  53. void waitForTaskToReturn()
  54. {
  55. #ifdef ESP_PLATFORM
  56. if (runOnPSRAM)
  57. {
  58. while (isRunning)
  59. {
  60. vTaskDelay(100 / portTICK_PERIOD_MS);
  61. }
  62. heap_caps_free(xStack);
  63. // TCB are cleanup in IDLE task, so give it some time
  64. TimerHandle_t timer = xTimerCreate( "cleanup", pdMS_TO_TICKS(5000), pdFALSE, xTaskBuffer,
  65. [](TimerHandle_t xTimer) {
  66. heap_caps_free(pvTimerGetTimerID(xTimer));
  67. xTimerDelete(xTimer, portMAX_DELAY);
  68. } );
  69. xTimerStart(timer, portMAX_DELAY);
  70. }
  71. else
  72. {
  73. (void)pthread_join(_thread, NULL);
  74. }
  75. #else
  76. (void)pthread_join(_thread, NULL);
  77. #endif
  78. }
  79. protected:
  80. virtual void runTask() = 0;
  81. private:
  82. #ifdef ESP_PLATFORM
  83. int priority;
  84. StaticTask_t *xTaskBuffer;
  85. StackType_t *xStack;
  86. #endif
  87. static void *taskEntryFunc(void *This)
  88. {
  89. ((Task *)This)->runTask();
  90. return NULL;
  91. }
  92. #ifdef ESP_PLATFORM
  93. static void taskEntryFuncPSRAM(void *This)
  94. {
  95. ((Task *)This)->isRunning = true;
  96. Task *self = (Task *)This;
  97. self->isRunning = true;
  98. self->runTask();
  99. self->isRunning = false;
  100. vTaskDelete(NULL);
  101. }
  102. #endif
  103. pthread_t _thread;
  104. };
  105. }
  106. #endif