Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request printf() to multitask environment #14

Open
nopnop2002 opened this issue Mar 22, 2019 · 8 comments
Open

Request printf() to multitask environment #14

nopnop2002 opened this issue Mar 22, 2019 · 8 comments
Labels
enhancement New feature or request

Comments

@nopnop2002
Copy link

nopnop2002 commented Mar 22, 2019

My environment:
Arduino-IDE(Ver1.8.5) + stm32duino + nucleo F103RB

Source code:

	#include <STM32FreeRTOS.h>
	#include <stdarg.h>

	SemaphoreHandle_t xSemaphore;

	void _printf(const char *format, ...) {
	    xSemaphoreTake(xSemaphore, portMAX_DELAY);
	    va_list va;
	    va_start(va, format);
	//    TickType_t _nowTick = xTaskGetTickCount();
	//    char * _taskName = pcTaskGetTaskName( NULL );
	//    printf("[%s:%d] ",_taskName, _nowTick);    
	    vprintf(format, va); 
	    va_end(va);
	    xSemaphoreGive(xSemaphore);
	}

	// 時間稼ぎ(Gain time)
	void ConsumptionTick(int delay) {
	    TickType_t startTick;
	    TickType_t endTick;
	    TickType_t nowTick;
	    startTick = xTaskGetTickCount();
	    endTick = startTick + delay;
	    //printf("startTick=%d endTick=%d\n",startTick,endTick);
	    while(1) {
	      nowTick = xTaskGetTickCount();
	      if (nowTick > endTick) break;
	    }
	}

	// Task Body
	void task(void *pvParameters)
	{
	    UBaseType_t prio;
	    TickType_t nowTick;

	    prio = uxTaskPriorityGet( NULL );
	    nowTick = xTaskGetTickCount();
	    printf("[%s:%d] start Priority=%d\n",pcTaskGetName(0),nowTick,(int)prio);
	//    _printf("[%s:%d] start Priority=%d\n",pcTaskGetName(0),nowTick,(int)prio);
	    ConsumptionTick(200);
	    nowTick = xTaskGetTickCount();
	    printf("[%s:%d] end\n",pcTaskGetName(0),nowTick);
	//    _printf("[%s:%d] end\n",pcTaskGetName(0),nowTick);
	    vTaskDelete( NULL );
	}


	//------------------------------------------------------------------------------
	void setup() {
	  portBASE_TYPE xTask1, xTask2, xTask3, xTask4;

	  Serial.begin(115200);
	  Serial.println("setup() start");
	  Serial.print("configTICK_RATE_HZ:");
	  Serial.println(configTICK_RATE_HZ);
	  Serial.print("portTICK_PERIOD_MS:");
	  Serial.println(portTICK_PERIOD_MS);
	  Serial.print("freeRTOS version:");
	  Serial.println(tskKERNEL_VERSION_NUMBER);

	#if 1
	// Task1 is started in priority=2
	// Task2 is started in priority=2
	// Task3 is started in priority=2
	// Task4 is started in priority=2
	  xTask1 = xTaskCreate(task, "Task1", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
	  xTask2 = xTaskCreate(task, "Task2", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
	  xTask3 = xTaskCreate(task, "Task3", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
	  xTask4 = xTaskCreate(task, "Task4", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
	#endif

	#if 0
	// Task1 is started in priority=2
	// Task2 is started in priority=3
	// Task3 is started in priority=4
	// Task4 is started in priority=5
	  xTask1 = xTaskCreate(task, "Task1", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
	  xTask2 = xTaskCreate(task, "Task2", configMINIMAL_STACK_SIZE, NULL, 3, NULL);
	  xTask3 = xTaskCreate(task, "Task3", configMINIMAL_STACK_SIZE, NULL, 4, NULL);
	  xTask4 = xTaskCreate(task, "Task4", configMINIMAL_STACK_SIZE, NULL, 5, NULL);
	#endif

	  /* Check everything was created. */
	  configASSERT( xTask1 );
	  configASSERT( xTask2 );
	  configASSERT( xTask3 );
	  configASSERT( xTask4 );

	  /* Create Mutex for printf */
	  xSemaphore = xSemaphoreCreateMutex();
	  /* Check everything was created. */
	  configASSERT( xSemaphore );
	  
	  // start scheduler
	  Serial.println("Start Scheduler.....");
	  vTaskStartScheduler();

	#if 1
	  while (1) {
	    Serial.println("setup alive...");
	    delay(1000);
	  }
	#endif
	}

	//------------------------------------------------------------------------------
	// WARNING loop() called from vApplicationIdleHook(), so don't use this function.
	// loop must never block
	void loop() {
	  // Not used.
	}

When i used prinf(),Indication is confused.

setup() start
configTICK_RATE_HZ:1000
portTICK_PERIOD_MS:1
freeRTOS version:V9.0.0
Start Scheduler.....
0] start Priority=2
rity=2
0] start Priority=2
rity=2
0] start Priority=2
0] start Priority=2
rity=2
rity=2
[Task3:218] end
[Task4:225] end
[Task1:230] end
[Task2:238] end

When i used _print(),Indication is not confused.

setup() start
configTICK_RATE_HZ=1000
portTICK_PERIOD_MS=1
Start Scheduler.....
[Task1:0] start Priority=2
[Task2:1] start Priority=2
[Task3:1] start Priority=2
[Task4:1] start Priority=2
[Task1:211] end
[Task2:214] end
[Task3:222] end
[Task4:233] end

@fpistm fpistm changed the title Your printf() dont correspond to multitask environment. printf() dont correspond to multitask environment. Mar 22, 2019
@fpistm
Copy link
Member

fpistm commented Mar 22, 2019

Hi @nopnop2002
I guess it could be redefined for FreeRTOS.
The used one is the one from newlib nano.
Do not hesitate to provide a PR.

@nopnop2002
Copy link
Author

Thank you for reply.
I can't understand your English correctly,cause i'm not native.
What is PR??
What shall i do??

@fpistm
Copy link
Member

fpistm commented Mar 22, 2019

@nopnop2002
Copy link
Author

I understood what is PR.

@fpistm fpistm changed the title printf() dont correspond to multitask environment. Request printf() to multitask environment Apr 15, 2019
@ppescher
Copy link

Actually the C runtime library is not "thread-safe". When you use a shared resource, like the serial interface you use for printf() output, you have to provide your own locking/mutex mechanism to prevent this kind of issues.

And I think it might go even worse than that when multiple tasks use an MCU peripheral: the HAL framework has its "lock" mechanism but I don't know how it performs with an RTOS.

@nopnop2002
Copy link
Author

nopnop2002 commented Jul 18, 2019

Thanks comment.
With esp-idf,printf look like "thread-safe".

@fpistm
Copy link
Member

fpistm commented Jul 18, 2019

Yes but ESP is RTOS oriented while STM32 core not

@nopnop2002
Copy link
Author

Thanks.
I understood.

@fpistm fpistm added the enhancement New feature or request label Apr 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants