|  | @@ -18,7 +18,6 @@ namespace bell
 | 
	
		
			
				|  |  |      public:
 | 
	
		
			
				|  |  |          std::string taskName;
 | 
	
		
			
				|  |  |          int stackSize, core;
 | 
	
		
			
				|  |  | -        bool isRunning = false;
 | 
	
		
			
				|  |  |          bool runOnPSRAM;
 | 
	
		
			
				|  |  |          Task(std::string taskName, int stackSize, int priority, int core, bool runOnPSRAM = true)
 | 
	
		
			
				|  |  |          {
 | 
	
	
		
			
				|  | @@ -27,21 +26,28 @@ namespace bell
 | 
	
		
			
				|  |  |              this->core = core;
 | 
	
		
			
				|  |  |              this->runOnPSRAM = runOnPSRAM;
 | 
	
		
			
				|  |  |  #ifdef ESP_PLATFORM
 | 
	
		
			
				|  |  | +			this->xStack = NULL;
 | 
	
		
			
				|  |  |  			this->priority = CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT + priority;
 | 
	
		
			
				|  |  |  			if (this->priority < 0) this->priority = ESP_TASK_PRIO_MIN;
 | 
	
		
			
				|  |  | +			if (runOnPSRAM) {
 | 
	
		
			
				|  |  | +				this->xStack = (StackType_t*) heap_caps_malloc(this->stackSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        virtual ~Task() {}
 | 
	
		
			
				|  |  | +        virtual ~Task() {
 | 
	
		
			
				|  |  | +#ifdef ESP_PLATFORM
 | 
	
		
			
				|  |  | +			if (xStack) heap_caps_free(xStack);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          bool startTask()
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |  #ifdef ESP_PLATFORM
 | 
	
		
			
				|  |  |              if (runOnPSRAM)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                xTaskBuffer = (StaticTask_t *)heap_caps_malloc(sizeof(StaticTask_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
 | 
	
		
			
				|  |  | -                xStack = (StackType_t *)heap_caps_malloc(this->stackSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                return (xTaskCreateStaticPinnedToCore(taskEntryFuncPSRAM, this->taskName.c_str(), this->stackSize, this, this->priority, xStack, xTaskBuffer, this->core) != NULL);
 | 
	
		
			
				|  |  | +                xTaskBuffer = (StaticTask_t*) heap_caps_malloc(sizeof(StaticTask_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
 | 
	
		
			
				|  |  | +                return (xTaskCreateStaticPinnedToCore(taskEntryFuncPSRAM, this->taskName.c_str(), this->stackSize, this, 
 | 
	
		
			
				|  |  | +													  this->priority, xStack, xTaskBuffer, this->core) != NULL);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              else
 | 
	
		
			
				|  |  |              {
 | 
	
	
		
			
				|  | @@ -54,64 +60,43 @@ namespace bell
 | 
	
		
			
				|  |  |                  esp_pthread_set_cfg(&cfg);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | -            return (pthread_create(&_thread, NULL, taskEntryFunc, this) == 0);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        void waitForTaskToReturn()
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -#ifdef ESP_PLATFORM
 | 
	
		
			
				|  |  | -            if (runOnPSRAM)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                while (isRunning)
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    vTaskDelay(100 / portTICK_PERIOD_MS);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                heap_caps_free(xStack);
 | 
	
		
			
				|  |  | -				// TCB are cleanup in IDLE task, so give it some time
 | 
	
		
			
				|  |  | -				TimerHandle_t timer = xTimerCreate( "cleanup", pdMS_TO_TICKS(5000), pdFALSE, xTaskBuffer, 
 | 
	
		
			
				|  |  | -													[](TimerHandle_t xTimer) {
 | 
	
		
			
				|  |  | -														heap_caps_free(pvTimerGetTimerID(xTimer));
 | 
	
		
			
				|  |  | -														xTimerDelete(xTimer, portMAX_DELAY);
 | 
	
		
			
				|  |  | -													} );	
 | 
	
		
			
				|  |  | -				xTimerStart(timer, portMAX_DELAY);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                (void)pthread_join(_thread, NULL);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -#else
 | 
	
		
			
				|  |  | -            (void)pthread_join(_thread, NULL);
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | +            return (pthread_create(&thread, NULL, taskEntryFunc, this) == 0);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      protected:
 | 
	
		
			
				|  |  |          virtual void runTask() = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private:
 | 
	
		
			
				|  |  | +        pthread_t thread;
 | 
	
		
			
				|  |  |  #ifdef ESP_PLATFORM
 | 
	
		
			
				|  |  |  		int priority;
 | 
	
		
			
				|  |  |          StaticTask_t *xTaskBuffer;
 | 
	
		
			
				|  |  |          StackType_t *xStack;
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | -        static void *taskEntryFunc(void *This)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            ((Task *)This)->runTask();
 | 
	
		
			
				|  |  | -            return NULL;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -#ifdef ESP_PLATFORM
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          static void taskEntryFuncPSRAM(void *This)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | +			Task* self = (Task*) This;
 | 
	
		
			
				|  |  | +            self->runTask();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            ((Task *)This)->isRunning = true;
 | 
	
		
			
				|  |  | +			// TCB are cleanup in IDLE task, so give it some time
 | 
	
		
			
				|  |  | +			TimerHandle_t timer = xTimerCreate( "cleanup", pdMS_TO_TICKS(5000), pdFALSE, self->xTaskBuffer, 
 | 
	
		
			
				|  |  | +												[](TimerHandle_t xTimer) {
 | 
	
		
			
				|  |  | +													heap_caps_free(pvTimerGetTimerID(xTimer));
 | 
	
		
			
				|  |  | +													xTimerDelete(xTimer, portMAX_DELAY);
 | 
	
		
			
				|  |  | +								  } );	
 | 
	
		
			
				|  |  | +			xTimerStart(timer, portMAX_DELAY);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            Task *self = (Task *)This;
 | 
	
		
			
				|  |  | -            self->isRunning = true;
 | 
	
		
			
				|  |  | -            self->runTask();
 | 
	
		
			
				|  |  | -            self->isRunning = false;
 | 
	
		
			
				|  |  | -            vTaskDelete(NULL);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +			vTaskDelete(NULL);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        pthread_t _thread;
 | 
	
		
			
				|  |  | +        static void *taskEntryFunc(void *This)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +			Task* self = (Task*) This;
 | 
	
		
			
				|  |  | +			self->runTask();
 | 
	
		
			
				|  |  | +			pthread_join(self->thread, NULL);
 | 
	
		
			
				|  |  | +            return NULL;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      };
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 |