The Wayback Machine - https://web.archive.org/web/20201224190132/https://github.com/stm32duino/STM32FreeRTOS/issues/14
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

Comments

@nopnop2002
Copy link

@nopnop2002 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 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

@nopnop2002 nopnop2002 commented Mar 22, 2019

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 fpistm commented Mar 22, 2019

@nopnop2002
Copy link
Author

@nopnop2002 nopnop2002 commented Mar 22, 2019

I understood what is PR.

@fpistm fpistm changed the title printf() dont correspond to multitask environment. Request printf() to multitask environment Apr 15, 2019
@fpistm fpistm added this to To do in STM32duino libraries via automation May 23, 2019
@ppescher
Copy link

@ppescher ppescher commented Jul 18, 2019

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 nopnop2002 commented Jul 18, 2019

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

@fpistm
Copy link
Member

@fpistm fpistm commented Jul 18, 2019

Yes but ESP is RTOS oriented while STM32 core not

@nopnop2002
Copy link
Author

@nopnop2002 nopnop2002 commented Jul 19, 2019

Thanks.
I understood.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.