Task.h 2.9 KB

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