inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

FreeRTOS 프로그래밍

소스코드 분석-configUSE_PREEMPTION

TASKMAN 실습 중 이해가 안되는 것이 있습니다.

해결된 질문

308

김상현

작성한 질문수 62

1

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.

안녕하세요. TASKMAN 프로젝트 실습 중 이해가 안되는 내용이 있어서 질문 올립니다.

동일한 Priority를 가지는 Task1과 Task2 생성하고 3초 딜레이 후에 Task2의 Priority를 올리는 코드를 작성하여 결과를 보았습니다.

configUSE_TIME_SLICING 은 1, configUSE_PREEPTION 은 1로 설정해놓은 상태여서, 예상되는 결과로는 약 3초정도 Task1과 Task2가 스위칭되면서 실행되다가 3초후엔 Task2만 실행될 것으로 예상을 하였습니다. 그런데 예상과 다르게 3초정도 지나니까 아예 정지를 해버리더군요.

FreeRTOS 매뉴얼을 읽어보아도 별 문제 없이 제가 예상한대로 돌아가야할 것 같은데, 왜 이러는지 이해가 안됩니다.

사진은 01_TASKMAN 프로젝트의 TaskMain 함수의 내용 일부입니다. 확인 부탁 드립니다. 감사합니다.

임베디드 운영체제 FreeRTOS

답변 2

0

홍영기

김상현님!

(ANS) 아! 원인을 찾은 것 같습니다.

fflush(stdout) 함수를 주석처리해보시죠. 이제 예상하신 것처럼 잘 동작하는 것을 볼 수 있어요.

printf 나 관련함수(fflush 와 같은)는 thread safe 하지 않아요.

해당 함수 내부적으로 임계구역이 존재한다는 뜻입니다(안전하지 않음).

그러면, 이 함수를 상호배제해서 사용해야 하는 것인가라는 질문만 남습니다.

하지만, 여기 딜레마가 있습니다.

우리가 printf 를 사용하는 이유는 보통 코드 실행을 추적하기 위한 것이죠. printf 는 디버깅 도구라는 말이죠.

디버깅 도구의 가장 이상적인 모습은

첫째, 이 함수 자체의 오버헤드(성능)가 크지 않아야 하죠. 

둘째, 실시간이면 좋겠죠.

셋째, 쓰레드 쉐이프해야 합니다.

그런데, 문제는 여기서 발생합니다. THREAD SAFE 와 오버헤드는 서로 모순관계에 있습니다.

THREAD SAFE 하게 처리하자면 오버헤드가 커지고, 오버헤드를 줄이거나 없애자면 위험을 감수해야 하는 겁니다.

그렇다고 printf 를 THREAD SAFE 하게 만들어 사용하는 것은 추천하지 않습니다. printf 함수내부적으로 사용한 인터럽트금지나 세마포어가 실시간을 중시하는 시스템의 실행 상태를 왜곡하거나 디버깅을 어렵게 만들 수 있습니다.

설명이 길어졌습니다만, 결론적으로 말씀드리자면, 

printf 함수나 관련 함수는 THREAD SAFE 않기 때문에, 디버깅하실 때 항상 주의를 기울이셔야 한다는 것입니다.

이와 관련된 추가 정보가 필요하시면 이 글을 참고해주세요.

0

김상현

감사합니다.

0

홍영기

김상현님!

잘 구현하셨지만 한 가지를 놓치신 것 같네요.

수퍼 태스크(일명 사자태스크)에 해당하는 taskMain 이 실행중일때는 task1 도 task2 도, 그 어떤 것도 실행될 수 없죠.

이런 방법으로 구현해보시죠.

task1()

{

3초 시간지연;

task2 의 우선순위를 높여준다;

...

}

이와 관련된 내용의 영상을 시청하시려면 클릭

추가 문의사항 있으시면 다시 질문 남겨주세요.

감사합니다.

0

김상현

답변 감사합니다. 그런데 여전히 이해가 안되서 다시 질문 드립니다.

(TaskMain 함수 내에서)

Task1 생성

Taks2 생성       -> Task1과 Task2의 Priority는 동일

위의 상황에서 TaskMain이 계속 돌아가다가 vTaskDelay(pdMS_TO_TICKS(3000)) 함수 호출로 약 3초간 TaskMain이 Block 상태로 진입

TaskMain이 Block 상태에 있을 동안 Task1과 Task2가 번갈아가면서 실행

약 3초 후 TaskMain이 Ready 상태로 진입

스케쥴러가 Ready 상태에 있는 TaskMain 실행(우선순위가 높으므로)

TaskMain에서 Task2의 Priority를 높여줌

TaskMain 삭제

그렇다면 스케쥴러는 생성된 Task1과 Task2 둘 중에서 우선순위가 높은 Task2를 실행해야할 것으로 예상이 되는데... 제가 무엇을 놓치고 있는건가요?

만약에 포팅을 할때 1년에 한번 잡는 치명적인 문제를 해결하는 코드가 들어갔다고 가정하면

0

57

2

STM32 포팅할 때 STM32 Project가 없음

0

148

2

FreeRTOS 멀티코어 지원안됨?

0

83

2

[소스코드 분석-configUSE_TIME_SLICING] TASK1,2의 우선순위가 동일할 때, configUSE_TIME_SLICING값 변경에 따른 출력 변화

0

82

2

포팅 부탁드립니다!

0

57

1

포팅 부탁드립니다. <NUCLEO-G071RB>

0

64

2

상호배제 후 되지를 않아서 질문드립니다.

0

59

1

수료증 발급 기준 수정 요청

1

69

1

재진입가능여부에 관한 질문

1

66

1

01_TASKMAN프로젝트 디버깅 모드 실패

1

76

2

그러면 malloc/free가 아닌 동적할당자를 써서 메모리를 할당했기떄문에

1

69

2

실행순서

1

74

2

uart 전송중에는 스위칭이 금지되나요?

1

71

2

스택오버플로우 실습 중 stack size 설정 질문

0

79

2

포팅 원합니다.

2

75

2

코루틴 실습질문

1

99

2

TODO 2번 문제

1

140

4

10. 선점형 커널 그림 설명중 우선순위가 반대인 경우에도 Task B가 먼저 수행되나요?

1

80

2

디버거모드에 진입이 안됩니다.

0

175

2

prvExampleTaskHook 함수 호출 부분에 대해 문의드립니다.

0

119

2

보드 STM32H735IG와 강의 호환 여부 문의

1

151

3

[ L152RE ] 원샷 소프트타이머 실행 잘 되시나요?

1

157

2

Deferred Interrupt Processing 샘플 예제 문의 드립니다.

1

119

2

포팅 서비스 부탁드립니다

1

122

2