지금까지 진행된 내용을 정리하면, 프로그램이 시작되어 여러가지 초기화를 진행한 후, idle task를 생성하여 실행 시키고, idle task에서는 main task를 생성, 실행 시켰다. idle task나 main task 둘 다 while(1); 로 되어 있으므로 두 타스크 모두 무한 루프 상태로 타스크가 실행된다. 하지만, 실제로는 main task가 우선 순위가 높으므로 main task만 CPU를 독점하고 idle task는 단 한 순간도 CPU를 점유하지 못하여 기아 상태에 빠지게 된다. RTOS를 사용하는 이유가 CPU를 효율적으로 이용하기 위해서이므로 어떤 이벤트가 발생하였을 때 그 이벤트를 처리하기 위한 타스크가 동작하고 다른 이벤트를 수행하기 위하여 CPU 점유권을 넘겨 주는 구조를..
앞의 글에서는 idle task의 context들을 스택메모리에 초기화 시킨 다음, arch_load_context() 함수를 불러서 스택메모리에 있던 context data들을 CPU 내부 레지스터로 복사하여 idle_task()라는 함수를 호출하는 과정에 대해서 설명하였다. 이번 글에서는 동작 중이던 어떤 타스크를 중지하고, 다른 타스크를 수행하는 과정에 대해서 설명하도록 하겠다. 이렇게 타스크를 바꾸는 동작을 task switching 또는 context switching이라고 한다. 먼저, TCB 구조체에 몇가지 필드를 추가해 보도록 하겠다. struct os_tcb { os_addr_t stack_ptr; os_addr_t stack_base; uint16_t stack_size; os_task..
이번글에서는 바로 앞의 글에서 생성한 Idle task에 대한 context를 실제로 CPU에 load 하여 예상대로 동작되는지 확인해 보도록 하겠다. 먼저 task_init() 함수에 다음과 같은 코드를 추가한다. void task_init(void) { struct os_tcb *idle_tcb = os_task_create(idle_task, 0x1234, OS_MIN_PRIORITY, OS_MIN_STACK_SIZE, "Idle"); arch_load_context(idle_tcb); } arch_load_context() 함수 호출을 추가하였는데, arch_load_context()는 어셈블러 코드로 작성된다. context.S 파일을 만들고 다음과 같은 코드를 추가한다. #include .gl..