浏览代码

http_download needs a bigger stack for cspot which required to move it to EXTRAM

philippe44 1 年之前
父节点
当前提交
90f53db953

+ 1 - 1
build-scripts/I2S-4MFlash-sdkconfig.defaults

@@ -948,7 +948,7 @@ CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y
 CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
 CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
 # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
 # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y
 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y
-CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
+CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=2
 # CONFIG_FREERTOS_ASSERT_FAIL_ABORT is not set
 # CONFIG_FREERTOS_ASSERT_FAIL_ABORT is not set
 CONFIG_FREERTOS_ASSERT_DISABLE=y
 CONFIG_FREERTOS_ASSERT_DISABLE=y
 CONFIG_FREERTOS_ISR_STACKSIZE=2096
 CONFIG_FREERTOS_ISR_STACKSIZE=2096

+ 1 - 1
build-scripts/Muse-sdkconfig.defaults

@@ -907,7 +907,7 @@ CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y
 CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
 CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
 # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
 # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y
 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y
-CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
+CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=2
 # CONFIG_FREERTOS_ASSERT_FAIL_ABORT is not set
 # CONFIG_FREERTOS_ASSERT_FAIL_ABORT is not set
 CONFIG_FREERTOS_ASSERT_DISABLE=y
 CONFIG_FREERTOS_ASSERT_DISABLE=y
 CONFIG_FREERTOS_ISR_STACKSIZE=2096
 CONFIG_FREERTOS_ISR_STACKSIZE=2096

+ 1 - 1
build-scripts/SqueezeAmp-sdkconfig.defaults

@@ -918,7 +918,7 @@ CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y
 CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
 CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
 # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
 # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y
 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y
-CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
+CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=2
 # CONFIG_FREERTOS_ASSERT_FAIL_ABORT is not set
 # CONFIG_FREERTOS_ASSERT_FAIL_ABORT is not set
 CONFIG_FREERTOS_ASSERT_DISABLE=y
 CONFIG_FREERTOS_ASSERT_DISABLE=y
 CONFIG_FREERTOS_ISR_STACKSIZE=2096
 CONFIG_FREERTOS_ISR_STACKSIZE=2096

+ 1 - 1
components/services/monitor.c

@@ -26,7 +26,7 @@
 #include "cJSON.h"
 #include "cJSON.h"
 #include "tools.h"
 #include "tools.h"
 
 
-#define PSEUDO_IDLE_STACK_SIZE	(8*1024)
+#define PSEUDO_IDLE_STACK_SIZE	(6*1024)
 
 
 #define MONITOR_TIMER	(10*1000)
 #define MONITOR_TIMER	(10*1000)
 #define SCRATCH_SIZE	256
 #define SCRATCH_SIZE	256

+ 2 - 4
components/spotify/cspot_sink.c

@@ -136,10 +136,8 @@ static bool cmd_handler(cspot_event_t event, ...) {
 		displayer_timer(DISPLAYER_ELAPSED, va_arg(args, int), -1);
 		displayer_timer(DISPLAYER_ELAPSED, va_arg(args, int), -1);
 		break;
 		break;
 	case CSPOT_TRACK_INFO: {
 	case CSPOT_TRACK_INFO: {
-		uint32_t duration = va_arg(args, int);
-        uint32_t offset = va_arg(args, int);
-		char *artist = va_arg(args, char*), *album = va_arg(args, char*), *title = va_arg(args, char*);
-		char *artwork = va_arg(args, char*);
+		uint32_t duration = va_arg(args, int), offset = va_arg(args, int);
+		char *artist = va_arg(args, char*), *album = va_arg(args, char*), *title = va_arg(args, char*), *artwork = va_arg(args, char*);
 		if (artwork && displayer_can_artwork()) {
 		if (artwork && displayer_can_artwork()) {
 			ESP_LOGI(TAG, "requesting artwork %s", artwork);
 			ESP_LOGI(TAG, "requesting artwork %s", artwork);
 			http_download(artwork, 128*1024, got_artwork, NULL);
 			http_download(artwork, 128*1024, got_artwork, NULL);

+ 1 - 0
components/squeezelite/output_i2s.c

@@ -742,6 +742,7 @@ static void IRAM_ATTR spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst) {
 	register u16_t aux;
 	register u16_t aux;
 #endif
 #endif
     
     
+    // we assume frame == 0 as well...
     if (!src) {
     if (!src) {
         count =  192;
         count =  192;
         vu = VUCP24[0];
         vu = VUCP24[0];

+ 81 - 28
components/tools/tools.c

@@ -1,4 +1,4 @@
-/* 
+/*
  *  (c) Philippe G. 20201, philippe_44@outlook.com
  *  (c) Philippe G. 20201, philippe_44@outlook.com
  *	see other copyrights below
  *	see other copyrights below
  *
  *
@@ -20,6 +20,10 @@
 #include "esp_log.h"
 #include "esp_log.h"
 #include "tools.h"
 #include "tools.h"
 
 
+#if CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS < 2
+#error CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS must be at least 2
+#endif
+
 const static char TAG[] = "tools";
 const static char TAG[] = "tools";
 
 
 /****************************************************************************************
 /****************************************************************************************
@@ -104,11 +108,11 @@ static uint8_t UNICODEtoCP1252(uint16_t chr) {
 void utf8_decode(char *src) {
 void utf8_decode(char *src) {
 	uint32_t codep = 0, state = UTF8_ACCEPT;
 	uint32_t codep = 0, state = UTF8_ACCEPT;
 	char *dst = src;
 	char *dst = src;
-			
+
 	while (src && *src) {
 	while (src && *src) {
 		if (!decode(&state, &codep, *src++)) *dst++ = UNICODEtoCP1252(codep);
 		if (!decode(&state, &codep, *src++)) *dst++ = UNICODEtoCP1252(codep);
 	}
 	}
-	
+
 	*dst = '\0';
 	*dst = '\0';
 }
 }
 
 
@@ -178,12 +182,61 @@ char * strdup_psram(const char * source){
 }
 }
 
 
 /****************************************************************************************
 /****************************************************************************************
- * URL download 
+ * Task manager
+ */
+#define TASK_TLS_INDEX 1
+
+typedef struct {
+    StaticTask_t *xTaskBuffer;
+    StackType_t *xStack;
+} task_context_t;
+
+static void task_cleanup(int index, task_context_t *context) {
+    free(context->xTaskBuffer);
+    free(context->xStack);
+    free(context);    
+}
+
+BaseType_t xTaskCreateEXTRAM( TaskFunction_t pvTaskCode,
+                            const char * const pcName,
+                            configSTACK_DEPTH_TYPE usStackDepth,
+                            void *pvParameters,
+                            UBaseType_t uxPriority,
+                            TaskHandle_t *pxCreatedTask) {
+    // create the worker task as a static
+    task_context_t *context = calloc(1, sizeof(task_context_t));
+    context->xTaskBuffer = (StaticTask_t*) heap_caps_malloc(sizeof(StaticTask_t), (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT));
+	context->xStack = heap_caps_malloc(usStackDepth,(MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT));
+    TaskHandle_t handle = xTaskCreateStatic(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, context->xStack, context->xTaskBuffer);
+
+    // store context in TCB or free everything in case of failure
+    if (!handle) {
+        free(context->xTaskBuffer);
+        free(context->xStack);
+        free(context);    
+    } else {
+        vTaskSetThreadLocalStoragePointerAndDelCallback( handle, TASK_TLS_INDEX, context, (TlsDeleteCallbackFunction_t) task_cleanup);
+    }
+    
+    if (pxCreatedTask) *pxCreatedTask = handle;
+    return handle != NULL ? pdPASS : pdFAIL;
+}
+
+void vTaskDeleteEXTRAM(TaskHandle_t xTask) {
+    /* At this point we leverage FreeRTOS extension to have callbacks on task deletion. 
+     * If not, we need to have here our own deletion implementation that include delayed
+     * free for when this is called with NULL (self-deletion)
+     */
+    vTaskDelete(xTask);
+}
+
+/****************************************************************************************
+ * URL download
  */
  */
- 
+
 typedef struct {
 typedef struct {
 	void *user_context;
 	void *user_context;
-	http_download_cb_t callback;	
+	http_download_cb_t callback;
 	size_t max, bytes;
 	size_t max, bytes;
 	bool abort;
 	bool abort;
 	uint8_t *data;
 	uint8_t *data;
@@ -192,22 +245,22 @@ typedef struct {
 
 
 static void http_downloader(void *arg);
 static void http_downloader(void *arg);
 static esp_err_t http_event_handler(esp_http_client_event_t *evt);
 static esp_err_t http_event_handler(esp_http_client_event_t *evt);
- 
+
 void http_download(char *url, size_t max, http_download_cb_t callback, void *context) {
 void http_download(char *url, size_t max, http_download_cb_t callback, void *context) {
 	http_context_t *http_context = (http_context_t*) heap_caps_calloc(sizeof(http_context_t), 1, MALLOC_CAP_SPIRAM);
 	http_context_t *http_context = (http_context_t*) heap_caps_calloc(sizeof(http_context_t), 1, MALLOC_CAP_SPIRAM);
-	
+
 	esp_http_client_config_t config = {
 	esp_http_client_config_t config = {
 		.url = url,
 		.url = url,
 		.event_handler = http_event_handler,
 		.event_handler = http_event_handler,
 		.user_data = http_context,
 		.user_data = http_context,
-	};	
-		
+	};
+
 	http_context->callback = callback;
 	http_context->callback = callback;
 	http_context->user_context = context;
 	http_context->user_context = context;
 	http_context->max = max;
 	http_context->max = max;
 	http_context->client = esp_http_client_init(&config);
 	http_context->client = esp_http_client_init(&config);
-	
-	xTaskCreate(http_downloader, "downloader", 4*1024, http_context, ESP_TASK_PRIO_MIN + 1, NULL);
+
+	xTaskCreateEXTRAM(http_downloader, "downloader", 8*1024, http_context, ESP_TASK_PRIO_MIN + 1, NULL);
 }
 }
 
 
 static void http_downloader(void *arg) {
 static void http_downloader(void *arg) {
@@ -215,14 +268,14 @@ static void http_downloader(void *arg) {
 
 
 	esp_http_client_perform(http_context->client);
 	esp_http_client_perform(http_context->client);
 	esp_http_client_cleanup(http_context->client);
 	esp_http_client_cleanup(http_context->client);
-	
+
 	free(http_context);
 	free(http_context);
-	vTaskDelete(NULL);
+	vTaskDeleteEXTRAM(NULL);
 }
 }
 
 
 static esp_err_t http_event_handler(esp_http_client_event_t *evt) {
 static esp_err_t http_event_handler(esp_http_client_event_t *evt) {
 	http_context_t *http_context = (http_context_t*) evt->user_data;
 	http_context_t *http_context = (http_context_t*) evt->user_data;
-		
+
 	if (http_context->abort) return ESP_FAIL;
 	if (http_context->abort) return ESP_FAIL;
 
 
 	switch(evt->event_id) {
 	switch(evt->event_id) {
@@ -234,42 +287,42 @@ static esp_err_t http_event_handler(esp_http_client_event_t *evt) {
 		if (!strcasecmp(evt->header_key, "Content-Length")) {
 		if (!strcasecmp(evt->header_key, "Content-Length")) {
 			size_t len = atoi(evt->header_value);
 			size_t len = atoi(evt->header_value);
 			if (!len || len > http_context->max) {
 			if (!len || len > http_context->max) {
-				ESP_LOGI(TAG, "content-length null or too large %zu / %zu", len, http_context->max);			
+				ESP_LOGI(TAG, "content-length null or too large %zu / %zu", len, http_context->max);
 				http_context->abort = true;
 				http_context->abort = true;
-			}	
-		}	
+			}
+		}
 		break;
 		break;
 	case HTTP_EVENT_ON_DATA: {
 	case HTTP_EVENT_ON_DATA: {
 		size_t len = esp_http_client_get_content_length(evt->client);
 		size_t len = esp_http_client_get_content_length(evt->client);
 		if (!http_context->data) {
 		if (!http_context->data) {
 			if ((http_context->data = (uint8_t*) malloc(len)) == NULL) {
 			if ((http_context->data = (uint8_t*) malloc(len)) == NULL) {
 				http_context->abort = true;
 				http_context->abort = true;
-				ESP_LOGE(TAG, "gailed to allocate memory for output buffer %zu", len);
+				ESP_LOGE(TAG, "failed to allocate memory for output buffer %zu", len);
 				return ESP_FAIL;
 				return ESP_FAIL;
-			}	
-		}	
+			}
+		}
 		memcpy(http_context->data + http_context->bytes, evt->data, evt->data_len);
 		memcpy(http_context->data + http_context->bytes, evt->data, evt->data_len);
 		http_context->bytes += evt->data_len;
 		http_context->bytes += evt->data_len;
 		break;
 		break;
-	}	
+	}
 	case HTTP_EVENT_ON_FINISH:
 	case HTTP_EVENT_ON_FINISH:
-		http_context->callback(http_context->data, http_context->bytes, http_context->user_context);			
+		http_context->callback(http_context->data, http_context->bytes, http_context->user_context);
 		break;
 		break;
 	case HTTP_EVENT_DISCONNECTED: {
 	case HTTP_EVENT_DISCONNECTED: {
 		int mbedtls_err = 0;
 		int mbedtls_err = 0;
 		esp_err_t err = esp_tls_get_and_clear_last_error(evt->data, &mbedtls_err, NULL);
 		esp_err_t err = esp_tls_get_and_clear_last_error(evt->data, &mbedtls_err, NULL);
 		if (err != ESP_OK) {
 		if (err != ESP_OK) {
-			ESP_LOGE(TAG, "HTTP download disconnect %d", err);				
+			ESP_LOGE(TAG, "HTTP download disconnect %d", err);
 			if (http_context->data) free(http_context->data);
 			if (http_context->data) free(http_context->data);
-			http_context->callback(NULL, 0, http_context->user_context);		
+			http_context->callback(NULL, 0, http_context->user_context);
 			return ESP_FAIL;
 			return ESP_FAIL;
 		}
 		}
 		break;
 		break;
 	default:
 	default:
 		break;
 		break;
-	}	
 	}
 	}
-	
+	}
+
 	return ESP_OK;
 	return ESP_OK;
 }
 }
- 
+

+ 12 - 0
components/tools/tools.h

@@ -56,6 +56,18 @@ const char* str_or_null(const char * str);
 typedef void (*http_download_cb_t)(uint8_t* data, size_t len, void *context);
 typedef void (*http_download_cb_t)(uint8_t* data, size_t len, void *context);
 void		http_download(char *url, size_t max, http_download_cb_t callback, void *context);
 void		http_download(char *url, size_t max, http_download_cb_t callback, void *context);
 
 
+/* Use these to dynamically create tasks whose stack is on EXTRAM. Be aware that it 
+ * requires configNUM_THREAD_LOCAL_STORAGE_POINTERS to bet set to 2 at least (index 0
+ * is used by pthread and this uses index 1, obviously
+ */
+BaseType_t xTaskCreateEXTRAM( TaskFunction_t pvTaskCode,
+                            const char * const pcName,
+                            configSTACK_DEPTH_TYPE usStackDepth,
+                            void *pvParameters,
+                            UBaseType_t uxPriority,
+                            TaskHandle_t *pxCreatedTask);
+void vTaskDeleteEXTRAM(TaskHandle_t xTask);                            
+
 extern const char unknown_string_placeholder[];
 extern const char unknown_string_placeholder[];
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus