임베디드 OS 개발 프로젝트 CH8 -1

유형주·2022년 1월 9일
0

CH8에서는 태스크를 다룰 코드를 작성한다.

태스크란 쉽게 말하면 동작하고 있는(혹은 대기하고 있는) 프로그램을 의미한다.

멀티쓰레드/멀티프로세스 운영체제는 여러 태스크를 concurrent하게 실행할 수 있어야 하고 이것을 멀티태스킹이라고 부른다.

여러 태스크를 다루기 위해서는 태스크도 추상화하여 하나의 자료구조로서 다뤄야 하고 자료구조에는 태스크를 전환(switch)해도 이전 상태로 복구할 수 있을만한 데이터를 가지고 있어야 한다.


task.h

typedef struct KernelTaskContex_t{
	uint32_t spsr; 
	uint32_t r0_r12[13]; 
	uint32_t pc; 

}KernelTaskContext_t;

typedef struct KernelTcb_t{
	uint32_t sp;
	uint8_t* stack_base;

}KernelTcb_t;

task.c

void Kernel_task_init(){
	sAllocated_tcb_index = 0;
	for(uint32_t i=0; i<MAX_TASK_NUM; i++){
		sTask_list[i].stack_base = (uint8_t*)(TASK_STACK_START + i*USR_TASK_STACK_SIZE);
		sTask_list[i].sp =(uint32_t)sTask_list[i].stack_base + USR_TASK_STACK_SIZE;
		sTask_list[i].sp-=sizeof(KernelTaskContext_t);
		KernelTaskContext_t* ctx = (KernelTaskContext_t*)sTask_list[i].sp;
		ctx->pc= 0;
		ctx->spsr = ARM_MODE_BIT_SYS;
	}

}

task.c에서는 추상화한 태스크를 초기화하는 Kernel_task_init()함수를 정의한다.
추상화 된 태스크 구조체를 보면 알 수 있듯이, 태스크정보는 하나의 스택으로 정의된다. 스택을 할당 받고, 스택의 top에 레지스터 정보를 저장하면 해당 태스크의 switch을 위한 정보 저장은 끝이다.


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;
	KernelTaskContext_t* ctx = (KernelTaskContext_t*)new_tcb->sp;

	ctx->pc =(uint32_t)startFunc; 
	return (sAllocated_tcb_index-1);
}

task.c에서 정의된 다른 함수인 Kernel_task_create()이다.
추상화 된 태스크의 리스트를 초기화 한 후에 각 태크스가 할 일을 알려주는 함수이다. 현재 사용중이지 않은 태스크의 pc필드에 실행 할 함수의 주소를 저장하고 return으로 몇 개의 태스크를 사용중인지 알려준다.

다음 포스팅에서 계속..

0개의 댓글