Using printf inside Task

GDX1024
Posts: 4
Joined: Mon Feb 19, 2018 12:39 pm

Using printf inside Task

Postby GDX1024 » Thu Jul 18, 2019 9:01 pm

I'm trying to use the printf inside a Task from freeRTOS and I can't. Outside the task, in the app_main(), it goes ok. But inside the task it starts printing a lot of information that I didn't ask for.

  1. [
  2. #include "freertos/FreeRTOS.h"
  3. #include "esp_system.h"
  4. #include "esp_event.h"
  5. #include "esp_event_loop.h"
  6. #include "nvs_flash.h"
  7. #include "driver/gpio.h"
  8.  
  9. void mytask(void *pvParameter){
  10.   while(1){
  11.     printf("hola, task!\n");
  12.     vTaskDelay(1000/portTICK_PERIOD_MS);
  13.   }
  14. }
  15.  
  16. void app_main(void)
  17. {
  18.     nvs_flash_init();
  19.  
  20.     xTaskCreate(&mytask, "blink_task", 512, NULL, 5, NULL);
  21. }
  22. ]
  23.  
  24. I don't know if I have to configure something. Any information would help a lot.

ESP_igrr
Posts: 2072
Joined: Tue Dec 01, 2015 8:37 am

Re: Using printf inside Task

Postby ESP_igrr » Thu Jul 18, 2019 10:26 pm

You probably need to increase the stack size to 2048 or more.

GDX1024
Posts: 4
Joined: Mon Feb 19, 2018 12:39 pm

Re: Using printf inside Task

Postby GDX1024 » Fri Jul 19, 2019 1:23 am

Yes. It was the stack. The esp was rebooting and starting all over again, and than printing the error again so fast that I could not see the stack message. I can't believe I need 2k of memory to print "hello, world".

thank you.

ESP_igrr
Posts: 2072
Joined: Tue Dec 01, 2015 8:37 am

Re: Using printf inside Task

Postby ESP_igrr » Fri Jul 19, 2019 10:02 am

Indeed, printf implementation does need a fair amount of stack to work, regardless of what the format string is. Actually if the printf statement doesn't use any format arguments, the compiler should be able to optimize it, converting it into "puts". I wonder why this hasn't happened here (possibly related to Debug/Release setting in menuconfig).

You can also choose to use "nano" implementation of formatting functions, which uses less stack space and has smaller code size. It doesn't support all C99 format string features, though.

User avatar
fly135
Posts: 606
Joined: Wed Jan 03, 2018 8:33 pm
Location: Orlando, FL

Re: Using printf inside Task

Postby fly135 » Fri Jul 19, 2019 6:33 pm

In my experience, using printf adds 1K to the stack requirement for a task.

John A

User avatar
rudi ;-)
Posts: 1730
Joined: Fri Nov 13, 2015 3:25 pm

Re: Using printf inside Task

Postby rudi ;-) » Fri Jul 19, 2019 8:39 pm

it would be almost superior to an auto mode function for that.
is it not known how much stack you will need in the moment when precompiled?
( free stack.... used stack... needed stack.. )
that's what the compiler should be able to tackle more intellectually.

does RTOS not have a compile mode supporting stack overflow detection?


btw: have not tried the code yet, just read it perhabs this helps too:
using uxTaskGetStackHighWaterMark function to determine how much stack has actually been used.. that interrupts also use the stack of the task that is interrupted


best wishes
rudi ;-)
-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪

mikemoy
Posts: 627
Joined: Fri Jan 12, 2018 9:10 pm

Re: Using printf inside Task

Postby mikemoy » Sat Jul 20, 2019 12:29 am

btw: have not tried the code yet, just read it perhabs this helps too:
using uxTaskGetStackHighWaterMark function to determine how much stack has actually been used.. that interrupts also use the stack of the task that is interrupted
I implement GetTaskHighWaterMarkPercent in every program I do. You just may never know just how close to the edge your running if you don't use this.

Example....

Code: Select all

#define STACK_SIZE_xtask1		2048
#define STACK_SIZE_xtask2		4096

TaskHandle_t TaskHandle_xtask1;
TaskHandle_t TaskHandle_xtask2;



//********************************************************************
//  	
// ********************************************************************
void xtask1(void * parameter)
{
	uint32_t x = 0;
	
	for (;;)
	{
		printf("xtask1 Running: %u\r\n", x++);
		
		vTaskDelay(250 / portTICK_PERIOD_MS);
	}
}
//********************************************************************
//  	
// ********************************************************************
void xtask2(void * parameter)
{
	uint32_t x = 0;
	
	for (;;)
	{
		printf("xtask2 Running: %u\r\n", x++);
		
		vTaskDelay(125 / portTICK_PERIOD_MS);
	}
}

/* -----------------------------------------------------------------------------
  GetTaskHighWaterMarkPercent( TaskHandle_t task_handle, uint32_t stack_allotment )

 	Input Params:
    - task_handle: The task handle name
   	- stack_allotment:  How much stack space did you allocate to it when you created it

  Returns: float with the % of stacke used
  Example:   printf("Stack Used %04.1f%%\r\n", GetTaskHighWaterMarkPercent(xTask1, 2048) );
  Notes:
 -----------------------------------------------------------------------------*/
float GetTaskHighWaterMarkPercent( TaskHandle_t task_handle, uint32_t stack_allotment )
{
  UBaseType_t uxHighWaterMark;
  uint32_t diff;
  float result;

  uxHighWaterMark = uxTaskGetStackHighWaterMark( task_handle );

  diff = stack_allotment - uxHighWaterMark;

  result = ( (float)diff / (float)stack_allotment ) * 100.0;

  return result;
}
//
//
//
void app_main()
{
	
	xTaskCreate(xTask1, "xTask1", STACK_SIZE_xtask1, NULL, 5, &TaskHandle_xtask1);	
	xTaskCreate(xTask2, "xTask2", STACK_SIZE_xtask2, NULL, 4, &TaskHandle_xtask2);	
	
	while(1)
	{
			TickType_t xTime1 = xTaskGetTickCount();
		
		
			uint8_t temp1 =  (uint8_t)GetTaskHighWaterMarkPercent(TaskHandle_xtask1, STACK_SIZE_xtask1);
			uint8_t temp2 =  (uint8_t)GetTaskHighWaterMarkPercent(TaskHandle_xtask2, STACK_SIZE_xtask2);
		
			printf("\r\n************************************************\r\n");
			printf("Tick:         %06.1f\r\n", (float)xTime1 / 100.00);
			printf("xTask1:       %03u%%\r\n", temp1);
			printf("xTask2:       %03u%%\r\n", temp1);
			
			if(temp1 > 90)
			{
				printf("!!! WARNING xTask1 Stack Useage to HIGH !!!\r\n");
			}
			
			
			vTaskDelay(250 / portTICK_PERIOD_MS);	
	}
	
}

Who is online

Users browsing this forum: No registered users and 58 guests