Don't think! Just do it!

종합 IT 기술 정체성 카오스 블로그! 이... 이곳은 어디지?

임베디드 소프트웨어/FreeRTOS

vApplicationStackOverflowHook()

방피터 2023. 2. 18. 21:52

스택 오버플로우는...

많은 도움을 받고 있는 곳(사이트)이지만 ㅋㅋㅋ

내 프로그램에서 발생한다면 지옥인거지 ㅋㅋ

임베디드에서는 딱히 볼일이 없었는데

요즘은 RTOS 때문에 신경써야 할 부분이 되었어 ㅋㅋ

일부는 RTOS를 사용하더라도 malloc, free는 절대 사용안하고

task의 stack을 과도하게 설정한다던지 하는 방법으로 스택 오버플로우를 피해왔지만

그건 근본적인 해결책이 아니지 ㅋㅋㅋ

어차피 고급 라이브러리들

(lwip, usb stack, mbed tls, file system 같은 고귀한 분들)

은 malloc, free를 사용하고 있어서 Stack overflow를 피할수가 없어 ㅎ

그러니까 괜히 쓸데없는 노력하지 말고 malloc, free 그리고 heap과 stack 구조를 받아들이고 익숙해지는게 좋아 ㅋㅋ

내가 사용중인 FreeRTOS

나는 프로젝트에서 FreeRTOS + lwip를 사용해야 하는데

STM Cube IDE에서 클릭 몇번으로 손쉽게 import 할 수 있었어.

DHCP도 잘 동작하고 핑도 잘 동작하더라구.

 

그래서 그 위에다가 어플리케이션을 짜야하는 동료에게

패스했는데 핑 동작하다가 뻗는다는 피드백을 받았지 뭐야 ㅋㅋㅋ

그래 FreeRTOS에서 이렇게 뻗으면 대부분 stack overflow야.

테스크에 할당된 메모리 양을 넘어서 다른 영역에 침범하는 걸 말하는 거지.

이런 경우 task에 할당된 stack 사이즈를 늘려주는 것으로 해결돼.

그런데 어떤 Task에서 Stack overflow가 발생했는지 알아야 하잖아?

그걸 위한 hook이 바로

vApplicationStackOverflowHook()

이건 stack overflow가 발생하면 호출되는 콜백 함수인데.

STM Cube IDE ioc 설정 ->

FreeRTOS ->

Config parameters 탭 ->

hook function related definitions 항목 ->

CHECK_FOR_STACK_OVERFLOW를 enable

하는 것으로 설정할 수 있어.

stack overflow hook

이렇게 설정하고 나면 freertos.c라는 파일 안에 vApplicationStackOverflowHook 함수를 정의할 수 있게 되어 있지.

👇👇

이게 호출된다는 것은 stack overflow가 발생한다는 뜻이니까

(잠재적으로 시스템이 뻗을 수 있다는 것)

꼭 해당 옵션을 켜놓고 개발하도록 하자!

 

여기서 option 1과 2가 있는데 자세히 알 필요는 없는데

option2가 stack overflow를 더 잘 캐치한다고 해.

그러니 이왕이면 option2로 ㅋㅋ

freertos.c

근데 stackoverflow hook은

task switching에 overhead를 발생시킬 수 있으니까

개발이나 테스트 할 때만 켜 놓는 걸 추천한다고 해.

이건 내가 괜히 하는 소리가 아니라 실제로 문서에 나와 있어.

👇👇

관심있는 사람들은 천천히 읽어보자.

https://www.freertos.org/Stacks-and-stack-overflow-checking.html

 

FreeRTOS - stacks and stack overflow checking

FreeRTOS is a portable, open source, mini Real Time kernel. A free RTOS for small embedded systems

www.freertos.org

암튼 저기에서 LED를 깜빡이는 코드를 삽입한다던지 하고,

개발할 때는 break point 걸어두고 테스트하면 되겠지?

break point 걸리면 pcTaskName이나 xTask 내용을 확인하는 것으로 어떤 Task에서 발생하는지 확인할 수 있으니까.

printf로 내용을 찍어도 되구,

그런데 이 함수는 task switching 도중에 걸리는 함수.

그러니까 인터럽트 도중에 수행되는 함수라서

다른 테스크에서 printf 사용하는 도중에 호출되면 뻗을거야 아마. ㅋㅋ

그런데 뭐 어차피 vApplicationStackOverflowHook에 걸리면 망하는 거니

printf던 뭐던 맘껏 사용하도록!


기본적인 설명은 여기까지 하기로 하고 실제 내 프로젝트에서는 EthIf라는 task에서 오버플로우가 계속 발생하더라고..

이름이 보나마나 LWIP야 그치?

그래서 LWIP 관련된 stack을 무지성으로 올려봤지.

👇👇

DEFAULT_THREAD_STACKSIZE 같은거 말이야 ㅋ

LWIP Stacksize 설정

음.. 증상이 호전되지 않더라구.

ㅋㅋㅋㅋ 그래서 lwip에서 사용하는 많은 task 들 중 하나에서 문제가 발생한거겠거니 하고

FreeRTOS의 MINIMAL_STACK_SIZE를 128에서 256으로 두배 올려봤지.

역시 무지성! ㅋㅋ

Task 스택 사이즈 최소값 설정

응? 증상이 똑같네..

역시 무지성으로 행동하면 답이 없어 ㅋㅋㅋ

이건 무슨 안알려진 버근가? 하고 한참을 똥통에 빠져있었어.

한참을 똥통에 빠져서 헤매다가

ㅋㅋ 에라 모르겠다

하면서 그 유명하다는 chatGPT한테 물어봤음 ㅋㅋㅋㅋㅋ

ㅋㅋㅋㅋㅋ 뭐 답변을 보면 별게 없어 configMINIMAL_STACK_SIZE를 늘리던지 아니면 거기에 "+ 512" 하라고 ㅋㅋ

👇👇

chatGPT도 별 도움이 안되는 구만~~

하면서 가만히 보다가... 

설마...

lwip 라이브러리에서

configMINIMAL_STACK_SIZE를 사용안하고 있나?

chatGPT의 답변

그래서 EthIf라는 Task를 찾아가봤더니

진짜로

configMINIMAL_STACK_SIZE를 안쓰고

그냥 Define문에서 350 byte를 때려박고 있더라고;;; 헐...

configMINIMAL_STACK_SIZE를 사용하지 않고 있다;;;
Stack size define

그래서 이걸 512로 증가시켜주니 모든 문제가 해결되었어.

음.. 기본 설정이 stack overflow를 발생시킨다니....

일종의 라이브러리 버그로 봐야하나? ㅋㅋㅋ

 

암튼 무지성으로 configMINIMAL_STACK_SIZE를 증가시킨다거나 ㅋㅋ

아무 관련 없는 Task의 Stack size를 늘리는 걸로 해결하려고 하지말고 ㅋㅋㅋ

찬찬히 코드를 보자고 ㅋ

기본이잖아?

잊지말자구 ㅋㅋㅋ

안녕!

👋👋👋

반응형

'임베디드 소프트웨어 > FreeRTOS' 카테고리의 다른 글

FreeRTOS + Lwip socket 갯수 조정  (1) 2023.08.01
LWIP TCP Send가 느릴 때  (0) 2023.03.09
STM32 MCU를 또 만지네...  (0) 2023.02.18