Task.h 2.8 KB

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