[FreeRTOS] 문맥전환

seopppio·2024년 11월 1일

FreeRTOS

목록 보기
4/14

스택 포인터 레지스터(SP)

현재 실행 중인 태스크의 스택 메모리의 위치를 가르키는 레지스터

컨택스트

프로세서가 태스크의 현재 상태를 나타내기 위해 사용하는 모든 정보

  • 레지스터 상태 : CPUU 레지스터에 저장된 값들
  • PC
  • xPSR : 프로세서 상태 레지스터
  • 스택 정보

TCB(Task Control Block) 메모리

각 태스크의 메타 데이터 저장

  • 스택 포인터
  • 태스크 상태
  • 우선순위
  • 태스크 이름
  • 스택 메모리 시작 위치 및 크기
  • 레지스터 정보
  • 프로세서 상태 레지스터(PSR)

문맥, CONTEXT

모든 CPU의 레지스터를 문맥이라 한다. 문맥 전화은, 선점된 태스크의 모든 레지스터 값을 스택에 저장한 뒤, 전에 저장했던 레지스터 값을 CPU로 복구하여 새로운 태스크를 실행하는 것

  • vPortYieldProcessor() 이용해서 문맥 전환 수행

    이 함수는, 우선순위가 가장 높은 태스크를 찾아서, 문맥전환을 시킨다

문맥 저장

  1. 인터럽트 발생, 태스크 스위칭 요청
  2. CPU에서 작동 중인 태스크의 레지스터 값들 태스크 스택에 저장
  3. 모든 레지스터 값 스택에 저장되고, SP는 현재 스택 마지막 위치를 가르키게 된다
  4. CPU에 있는 업데이트된 SP값 태스크를 TCB에 업데이트

문맥 복원


1. TCB에 있는 SP를 받아오면, 태스크의 context에 접근이 가능하다
2. 그 모든 context를 CPU로 읽어오면 문맥 복원 종료

FreeRTOS 문맥 전환 방법

1. 커널 API

vTaskDelay 같은 함 수 안에 문맥 전환 코드 있다


이게 문맥전환 발생하는 API, 이 API는 portYIELD() 함수를 사용한다


이 함수 내부를 보면 NVIC를 사용한다. NVIC가 PenSV 인터럽트를 펜딩 상태로 만들어, 문맥전환을 유도한다

NVIC

ARM Cortex-M 프로세서에서 인터럽트를 관리하고 우선순위를 제어하는 하드웨어 모듈이다

  1. portYIELD()에서, NVIC PenSV 설정 비트 1로 바꾼다
  2. PendSV 인터럽트가 대기 되었다가, CPU가 모든 다른 인터럽트 처리 후 PendSV 인터럽트 처리
  3. PendSV 인터럽트가 처리될 때 PendSV_Handler 호출
  4. PendSV_Handler 내부에 문맥전환 코드가 존재하여 문맥전환 실행

xPortPednSVHHandler 함수 내부에 문맥 전환 코드 있다

2. 인터럽트 핸들러

타이머 인터럽트인 SysTick_Handler 내부에


  • portYIELD() 함수 내부에 있는 것과 동일

여기서도 이제 NVIC 이용해서, PenSV 인터럽트 펜딩상태로 전환하고, 인터럽트 순서 와서 처리되면서 문맥전환 코드 사용되면서 문맥전환 일어나는 것

테스크 작성법

  1. void 테스크이름(파라미터)

IDLE 테스크

우선 순위 0
삭제할 수 없는 테스크
Hook 함수 존재(콜백 함수)

  • 콜백 함수 : 우리가 커널 API를 부르는게 아니라, 커널 API가 부르는 함수

xTickCount

타이머 인터럽트가 들어올 때 마다 xTickCount가 증가한다

0개의 댓글