인프런 커뮤니티 질문&답변
'소스코드 분석-printf와 fflush' 부분 질문이 있습니다!
작성
·
458
답변 1
0
jinh2352님!
혹시 질문하신 내용이 영상 몇분 몇초 구간인지 알 수 있을까요? 3분 정도의 영상을 들여다 보았는데, 그런 상황이 없는 것 같아서 질문드립니다.
FreeRTOS 프로그래밍소스코드 분석-printf 와 fflush
vTaskDelay 가 사용되었다면 위와 같은 결과가 나올 수 있습니다.
jinh2352님! 반갑습니다:)
두 개의 태스크가 같은 우선순위를 사용하며, fflush 을 사용하는 경우를 말씀하시는 것이군요.
기본적으로 화면에 출력되는 내용만 그렇게 보이는 것일뿐 실제적으로는 jinh2352님 표현대로 대칭적인 모습으로 실행(라운드로빈)되고 있을 것입니다.
다양한 방법으로 그 것을 확인하실 수 있을터인데, 그 중 간단한 방법 하나를 알려드릴게요.
각각의 태스크를 이런식으로 코드 수정후 실행해보시죠.
#if 1 // No comment
//vTaskDelay (pdMS_TO_TICKS (1000));
i++;
if((i%100)==0){
printf("b"); fflush(stdout); // 문자 'b' 출력
}
#endif // TODO #3
실행 결과는 다음과 같은 것일텐데요.
bbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbba
그럼 과거에 실행 결과가 a a a a .. a a a b a a a a... a a a b
이런 식으로 나왔던 이유는 fflush 나 printf 함수 자체가 재진입(reentrant) 함수가 아니라는 점과 __io_putchar 함수내에서 사용하는 HAL_UART_Transmit 함수의 구현 방법 때문으로 보실 수 있어요.
int __io_putchar(int ch)
{
if ( ch == '\n' )
HAL_UART_Transmit(&huart2, (uint8_t*)&"\r", 1, HAL_MAX_DELAY);
HAL_UART_Transmit(&huart2, (uint8_t*)&ch, 1, HAL_MAX_DELAY);
return ch;
}
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
uint8_t *pdata8bits;
uint16_t *pdata16bits;
uint32_t tickstart = 0U;
/* Check that a Tx process is not already ongoing */
if (huart->gState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
... 중략
printf 사용하시면서 이러한 출력이 나온걸 보신적 있을 수 있습니다.
Hello, Wo다른문자열rld
이것은 printf가 재진입 함수가 아니라는 것을 잘 보여줍니다
이것만 기억하시면 될 것 같아요.
fflush 함수를 이용할 때는 출력 결과를 맹신하지 말자.
이 함수는 꼭 필요한 경우외엔 가급적이면 사용하지 않는 것이 좋다.
궁극적인 해결 방법은 printf, fflush 을 재진입 함수로 만드는 것일텐데요.
재진입 함수로 만드는 것은 상호배제를 통해 실제 가능은 합니다. 하지만 상호배제에는 비용(오버헤드)이 발생하기 때문에 즐겨 사용되지 않습니다. 또한 이 함수가 상호배제를 내장하고 있는 경우 함수 내부에서도 문맥 전환이 발생하게 됨으로써 테스트 환경을 왜곡시킬 위험 또한 있습니다.






근래 바빠서 잠시 공부를 놓았다 다시 보게 되어 답변이 늦었습니다 ㅠ
(비대칭적 출력 1분 10초대)
https://www.inflearn.com/course/freertos-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/lecture/82500?tab=curriculum
(비대칭적 출력에 대한 해설, fflush 동작으로 인한)
FreeRTOS 프로그래밍소스코드 분석-printf 와 fflush
위 회차 수업에서 동일한 우선순위를 가지는 Task1, Task2가 작동함에도 불구하고 a a a a .. a a a b a a a a... a a a b 와 같이 비대칭적으로 출력되는 부분이 fflush 함수의 작동으로 느린 UART 장치가 작동되기에 그런 것이다 라 설명해주셨고,
Task1, Task2 에서 모두 fflush를 주석처리하면 대칭적인 출력이 나옵니다.
이 점이 그냥 궁금했던 것입니다! 동일한 우선순위 Task1, Task2 둘다 fflush 함수를 호출하는데 비대칭적인 출력이 발생하는 것이 이해가 잘 되지 않습니다. 똑같이 작동이 느려지기에 결국 대칭적인 출력이 나와야한다 생각되기 때문입니다!