임베디드 OS 개발 프로젝트를 읽고 작성하였습니다.
시작하기 전에
스케줄러란?
지금 실행 중인 태스크 다음에 실행할 태스크가 무엇인지 골라주는 것
효율적으로 만드는지에 따라 RTOS의 성능이 좌우될 정도로 중요함!
9장 스케줄러
9.1 간단한 스케줄러
스케줄러
: 다음에 실행할 태스크가 무엇인지 골라주는 것
가장 간단한 방법? => 라운드 로빈 (round robin) 알고리즘
현재 실행 중인 태스크 컨트롤 블록의 바로 다음 태스크 블록을 선택하는 것!추가 계산 없이 인덱스를 계속 증가시키면서 대상을 선택하는 알고리즘중요한 점은 끊임없이 증가하는 것이 아니라 정해진 최댓값에 이르면 다시 0이 된다는 것
kernel/task.c
스케줄러 역시 태스크 관련 작업이므로 kernel/task.c에서 수정
static uint32_t sCurrent_tcb_index; //현재 실행 중인 태스크의 태스크 컨텍스트 블록 인덱스를 저장
static KernelTcb_t* Scheduler_round_robin_algorithm(void);
static KernelTcb_t* Scheduler_round_robin_algorithm(void)
{
sCurrent_tcb_index++; //다음 동작할 태스크 컨트롤 블록 인덱스로 만듦
sCurrent_tcb_index %= sAllocated_tcb_index; //나머지 연산을 사용해 sAllocated_tcb_index를 넘지 않게
return &sTask_list[sCurrent_tcb_index]; //sTask_list 배열을 읽어 다음에 동작할 태스크 컨트롤 블록을 리턴
}
코드 9.1 라운드 로빈 알고리즘 task.c
이렇게 만든 알고리즘 코드를 컨텍스트 스위칭에 적용하면 끝!
9.2 우선순위 스케줄러
QEMU의 제약으로 우선순위 스케줄러 구현이 어려움!
우선순위 스케줄러
: 태스크에 우선순위(priority)가 있어서 스케줄러가 낮은 우선순위 태스크를 높은 우선순위 태스크가 동작하는 동안 다음에 동작할 태스크로 선택하지 않는 것
-> 구현하기 위해서는 태스크 컨트롤 블록에 우선순위를 부여해야 함 (개발자가 값 지정)
태스크 컨트롤 블록에 멤버 변수 추가
typedef struct KernelTcb_t
{
uint32_t sp;
uint8_t* stack_base;
uint32_t priority; //우선순위를 태스크 컨트롤 블록에 추가
} KernelTcb_t;
Kernel_task_create()
확장된 자료 구조를 사용하는 코드로 관련 함수 변경
uint32_t Kernel_task_create(KernelTaskFunc_t startFunc)
{
KernelTcb_t* new_tcb = &sTask_list[sAllocated_tcb_index++];
if (sAllocated_tcb_index > MAX_TASK_NUM)
{
return NOT_ENOUGH_TASK_NUM;
}
new_tcb->priority = priority; //우선 순위를 TCB에 등록
KernelTaskContext_t* ctx = (KernelTaskContext_t*)new_tcb->sp;
ctx->pc = (uint32_t)startFunc;
return (sAllocated_tcb_index - 1);
}
우선순위 스케줄러의 스케줄링 알고리즘
static KernelTcb_t* Scheduler_priority_algorithm(void)
{
for(unit32_t i = 0; i < sAllocated_tcb_index; i++)
{
KernelTcb_t* pNextTcb = &sTask_list[i];
if (pNextTcb != pNextTcb) //현재 동작 중인 태스크 컨트롤 블록 제외
{
if (pNextTcb->priority <= sCurrent_tcb->priority) //현재 동작 중인 태스크와 우선 순위 비교
{
return pNextTcb; //우선순위가 높으면 다음에 실행할 태스크로 선택
}
}
}
return sCurrent_tcb; //우선순위가 높은게 없으면 현재 태스크를 계속 실행
}
주의할 점!
: 작은 숫자의 우선순위 > 큰 숫자의 우선순위
⚠ 8번째 줄 수정사항 : sCurrent -> sCurrent_tcb
9.3 요약
스케줄러로 어떤 알고리즘을 쓰느냐에 따라 태스크 컨트롤 블록의 설계가 달라짐
이 책은 가장 기본적인 라운드 로빈 스케줄러로 구현
'개발 > 임베디드 os 개발 프로젝트' 카테고리의 다른 글
11장 이벤트 (1) | 2023.10.16 |
---|---|
10장 컨텍스트 스위칭 (0) | 2023.10.12 |
8장 태스크 (1) | 2023.10.09 |
7장 타이머 (1) | 2023.10.07 |
6장 인터럽트 (1) | 2023.06.17 |