'소스코드 분석-printf와 fflush' 부분 질문이 있습니다!
467
작성한 질문수 4
"fflush 함수는 버퍼를 비우고, 이에 따라 출력장치의 동작을 야기시킵니다. 그런데 UART 장치의 동작은 매우 느리기에 예상치 못한 출력 결과를 야기시킵니다."
위와 같이 수업에서 이해를 하였습니다!
그런데 'a'를 출력하는 Task1도 'b'를 출력하는 Task2도 둘다 fflush 함수가 동작을 하는데 왜 a a a a .. a a b a a a.. 와 같이 비대칭적인 결과가 나오는 걸까요?
둘다 fflush 함수가 있기에 출력이 느려지더래도 대칭성은 유지될 것으로 예상하였었습니다.
답변 1
0
jinh2352님!
혹시 질문하신 내용이 영상 몇분 몇초 구간인지 알 수 있을까요? 3분 정도의 영상을 들여다 보았는데, 그런 상황이 없는 것 같아서 질문드립니다.
FreeRTOS 프로그래밍소스코드 분석-printf 와 fflush
vTaskDelay 가 사용되었다면 위와 같은 결과가 나올 수 있습니다.
0
근래 바빠서 잠시 공부를 놓았다 다시 보게 되어 답변이 늦었습니다 ㅠ
(비대칭적 출력 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 함수를 호출하는데 비대칭적인 출력이 발생하는 것이 이해가 잘 되지 않습니다. 똑같이 작동이 느려지기에 결국 대칭적인 출력이 나와야한다 생각되기 때문입니다!
0
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년에 한번 잡는 치명적인 문제를 해결하는 코드가 들어갔다고 가정하면
0
82
2
STM32 포팅할 때 STM32 Project가 없음
0
213
2
FreeRTOS 멀티코어 지원안됨?
0
114
2
[소스코드 분석-configUSE_TIME_SLICING] TASK1,2의 우선순위가 동일할 때, configUSE_TIME_SLICING값 변경에 따른 출력 변화
0
104
2
포팅 부탁드립니다!
0
68
1
포팅 부탁드립니다. <NUCLEO-G071RB>
0
75
2
상호배제 후 되지를 않아서 질문드립니다.
0
72
1
수료증 발급 기준 수정 요청
1
86
1
재진입가능여부에 관한 질문
1
81
1
01_TASKMAN프로젝트 디버깅 모드 실패
1
95
2
그러면 malloc/free가 아닌 동적할당자를 써서 메모리를 할당했기떄문에
1
78
2
실행순서
1
84
2
uart 전송중에는 스위칭이 금지되나요?
1
83
2
스택오버플로우 실습 중 stack size 설정 질문
0
90
2
포팅 원합니다.
2
83
2
코루틴 실습질문
1
111
2
TODO 2번 문제
1
148
4
10. 선점형 커널 그림 설명중 우선순위가 반대인 경우에도 Task B가 먼저 수행되나요?
1
94
2
디버거모드에 진입이 안됩니다.
0
188
2
prvExampleTaskHook 함수 호출 부분에 대해 문의드립니다.
0
131
2
보드 STM32H735IG와 강의 호환 여부 문의
1
161
3
[ L152RE ] 원샷 소프트타이머 실행 잘 되시나요?
1
168
2
Deferred Interrupt Processing 샘플 예제 문의 드립니다.
1
123
2
포팅 서비스 부탁드립니다
1
131
2





