본문 바로가기
프로그래밍 언어/c(임베디드)

멀티 쓰레드 태스크가 안도는 버그 및 해결방법

by [Akashic Records] 개발의선지자 2025. 7. 5.

이번 포스팅에서는 멀티 쓰레드 태스크가 안도는 버그 및 해결방법에 대해 개인적으로 기록하고자 한다.

 

1.문제 증상

MCU(메가헌트48칩) 코어 수 3

증상 : 멀티 쓰레드 4개 생성 후 각 쓰레드에서 태스크가 순차적으로 동작을 설계 

-> 1,2번 태스크는 동작 X, 3번 , 4번 태스크 동작 

 

2. 원인 가능성이 있는 목록  

  1. 스케줄링 지연
  2. 우선순위 역전 
  3. 경쟁 조건 
  4. 데드락

 

3. 체크 리스트

 

  1. 태스크  생성 여부
  2. 태스크 우선순위 여부
  3. 무한루프 내 delay 호출 여부
  4. 스택 크기
  5. RTOS 메모리 크기
  6. 태스크 루틴 코드 

 

4. 원인 파악

 

1. 태스크 우선순위 역전

낮은 우선순위 태스크가 자원을 점유 중일 떄 

높은 우선순위 태스크가 그 자원을 기다리느라 막히고,

중간 우선순위 태스크가 계속 실행되면서 시스템이 교착 상태에 빠지는 현상

 

2. CPU 점유 독점

높은 우선순위 태스크가 무한 루프를 돌며 Delay 없이 CPU를 점유할 경우, 

낮은 우선순위 태스크는 전혀 실행 기회를 얻지 못함

 

5. 문제 해결  

쓰레드 생성 전 아래 함수들 호출

 

1. RTC_CLKSourceSelect(SELECT_EXT32K);

: RTC(real time clock) 클럭 선택 -> 외부 32.768kHz 크리스탈 오실레이터 세팅

vTaskDelay() 또는 osDelay() 같은 함수가 내부 RTC 기반 SysTick 타이머에 의존하고 있었다면, 정확한 타이밍 없이 스레들이 전혀 실행되지 않을 수도 있다 


2. NVIC_SetPriorityGrouping(NVIC_PriorityGroup_3);

: 인터럽트 우선순위 그룹 설정 , Preemption priority 과 Sub priority 간의 비트를 어떻게 나눌지 결정하는 설정한다.

매개변수 

NVIC_PriorityGroup : CMSIS에서 정의한 매크로 중 하나를 사용

이 매개변수는 AIRCR의 PRIGROUP 필드를 설정하여, 인터럽트 우선순위 비트를 어떻게 나눌지 정

 

ex)

PriorityGroup_3는 Preemption priority는 3비트 ,  Sub priority 1비트 사용 

 

프로젝트에서 인터럽트 우선순위를 관리해야 하는 경우, 우선순위간에 preemption이 필요한 경우 반드시 호출해야 한다.

일부 RTOS나 HAL 드라이버는 인터럽트 우선순위가 일정 그룹 설정을 요구한다.

FreeRTOS는 configMAX_SYSCALL_INTERRUPT_PRIORITY보다 높은 인터럽트 우선순위를 가진 ISR에서 FreeRTOS API를 호출하면 동작이 불안정해지거나 멈추는 버그 발생할수 있다.

또는 이 함수 호출 이전에는 인터럽트 우선순위가 잘못 설정되어 있었다먄 스케줄러가 동작을 차단할 수 있다

 

추가 설명

ARM Cortex-M 코어는 NVIC를 통해 인터럽트 관리한다.

NVIC는 코어와 연결되어 있어 우선순위가 높은 인터럽트는 낮은 우선순위 인터럽트를 중단하고 실행할수 있다.

  • Preemption priority : 높은 우선순위의 인터럽트가 실행 중인 인터럽트를 중단하고 실행될 수 있음.
  • Sub priority : 같은 Preemption priority 내에서 인터럽트가 동시에 발생했을 떄, 우선 처리할 인터럽트를 결정

일부 RTOS(예 : Free RTOS)나 HAL 드라이버는 인터럽트 우선순위가 일정 그룹 설정을 요구하기에 쓰레드 생성 전 인터럽트 우선순위를 세팅해야 한다.

만약 인터럽트 우선순위가 잘못 설정되어, 스케줄러가 동작을 차단할수 있다.

 

  • NVIC_PriorityGroup_0 : 0 bits for pre-emption  3 bits for subpriority 
  • NVIC_PriorityGroup_1 : 1 bits for pre-emption priority 2 bits for subpriority                       
  • NVIC_PriorityGroup_2 : 2 bits for pre-emption priority 1 bits for subpriority
  • NVIC_PriorityGroup_3 : 3 bits for pre-emption priority 0 bits for subpriority

 

 

 

 

 

 

 

 

'프로그래밍 언어 > c(임베디드)' 카테고리의 다른 글

콜드(cold) 리셋과 웜(warm) 리셋  (0) 2025.06.28
BCD란?  (0) 2024.12.27
.HEX 과 .ELF 파일 개념  (0) 2024.12.14
system() / sync()  (0) 2024.11.13
Wiegand 통신  (0) 2024.09.08