3 분 소요

이 글은 ‘uC/OS-III: The Real-Time Kernel For the STM32 ARM Cortex-M3, Jean J. Labrosse, Micrium, 2009’를 번역한 글입니다. 오역이 있을 수 있으며, 발견하시면 github에 issue나 댓글 남겨주시기 바랍니다.

task는 세마포어(semaphore), mutual exclusion semaphore, event flag group, message queue 상에서 대기하고 있을 때 Pend List에 배치된다.

See For Kernel Object
231쪽 13장 “Resource Management” 참조 Semaphores, Mutual Exclusion Semaphores OS_SEM, OS_MUTEX
273쪽 14장 “Synchronization” 참조 Semaphores, Event Flags OS_SEM, OS_FLAG_GRP
309쪽 15장 “Message Passing” 참조 Message Queues OS_Q

(표 10-1 Kernel objects that have Pend Lists)

pend list는 Ready List와 유사한데, 실행 준비 상태인 작업을 추적하는 대신 pend list는 객체(object)가 post되기를 기다리는 작업을 추적한다는 점이다. 또한 pend list는 우선 순위에 따라 정렬되는데, 해당 객체에서 대기하는 가장 높은 우선순위의 task는 목록의 맨 앞에 배치되고, 해당 객체에서 대기하는 가장 낮은 우선순위의 task는 목록의 맨 끝에 배치된다.

pend list는 OS_PEND_LIST라는 타입의 자료구조이며, Figure 10-1과 같이 3개의 필드로 구성되어있다.

Figure 10-1 Pend List

.NbrEntries는 pend list의 현재 항목 수를 나타낸다. pend list의 각 항목은 커널 객체(kernel object)가 포스트(post)되기를 기다리는 task를 가리킨다.

.TailPtr은 리스트의 가장 마지막 task(즉, 가장 낮은 우선순위의 task)를 가리킨다.

.HeadPtr은 리스트의 가장 처음 task(즉, 가장 높은 우선순위의 task)를 가리킨다.

Figure 10-2는 pend list를 사용하는 각 커널 객체가 OS_PEND_OBJ라고 부르는 커널 객체의 시작 부분에 동일한 세 개의 필드를 포함하고 있음을 나타낸다. 첫 번째 필드는 항상 “Type”이므로, 커널 객체가 세마포어(semaphore)인지, event flag group인지, message queue인지 μC/OS-III가 알 수 있다.

Figure 10-2 OS_PEND_OBJ at the beginning of certain kernel objects

표 10-2는 위 각 객체의 “Type”필드가 각 객체 생성 시 4개의 ASCII 문자를 포함하도록 초기화된 것을 보여준다. 이를 통해 사용자는 디버거를 통해 메모리 덤프를 수행할 때 이러한 객체들을 식별할 수 있다.

Kernel Object Type
Semaphore ‘S’ ‘E’ ‘M’ ‘A’
Mutual Exclusion Semaphore ‘M’ ‘U’ ‘T’ ‘X’
Event Flag Group ‘F’ ‘L’ ‘A’ ‘G’
Message Queue ‘Q’ ‘U’ ‘E’ ‘U’

(표 10-2 Kernel objects with initialized “Type” field)

pend list는 task의 OS_TCB를 가리키는 것이 아니라, Figure 10-3과 같이 OS_PEND_DATA 객체를 가리킨다. 또한 task가 pend list에 놓이면 OS_PEND_DATA 구조가 현재 task의 스택에 동적으로 할당된다. 이는 task 스택이 이러한 데이터 구조를 위한 저장소를 할당할 수 있어야 함을 의미한다.

Figure 10-3 Pend Data

.PrevPtr는 pend list에 있는 OS_PEND_DATA 항목을 가리키는 포인터이다. 이 포인터는 커널 객체에서 대기하고 있는 더 높은 우선순위 또는 동등한 우선순위의 task를 가리킨다.

.NextPtr는 pend list에 있는 OS_PEND_DATA 항목을 가리키는 포인터이다. 이 포인터는 커널 객체에서 대기하고 있는 더 낮은 우선순위 또는 동등한 우선순위의 task를 가리킨다.

.TCBPtr은 해당 pend list에서 대기하고 있는 task의 OS_TCB를 가리킨다.

.PendObjPtr은 task가 대기 중인 커널 객체를 가리킨다. 즉, 이 포인터는 OS_PEND_OBJ를 공통 데이터 구조로 사용하여 OS_SEM, OS_MUTEX, OS_FLAG_GRP, 또는 OS_Q를 가리킬 수 있다.

.RdyObjPtr은 task가 여러 커널 객체에 대기 중인 경우, 준비된 커널 객체를 가리킨다. 자세한 내용은 333페이지의 16장 “Pending On Multiple Objects”를 참조하라.

.RdyMsgPtr은 task가 여러 커널 객체에 대기 중인 경우, OSQPost()를 통해 게시된 메시지를 가리킨다. 자세한 내용은 333페이지의 16장 “Pending On Multiple Objects”를 참조하라.

.RdyTS는 커널 객체가 post된 시간의 타임스탬프이다. 이것은 333페이지의 16장 “Pending On Multiple Objects”에서 설명한 것처럼 여러 커널 객체에 작업이 대기하고 있을 때 사용됩니다.

Figure 10-4는 task가 pend list에 들어가있을 때 모든 데이터 구조가 어떻게 서로 연결되는지를 보여준다. 이 그림은 세마포어(semaphore)에 두 개의 작업이 대기하고 있다고 가정한다.

Figure 10-4 Pend Data

F10-4(1)

OS_SEM 타입은 OS_PEND_OBJ를 포함하며, 즉, OS_PEND_LIST를 포함한다. pend list의 .NbrEntries 필드는 세마포어에 2개의 task가 대기 중임을 나타낸다.

F10-4(2)

pend list의 .HeadPtr 필드는 세마포어에서 대기 중인 가장 높은 우선순위의 task 의 OS_PEND_DATA를 가리킨다.

F10-4(3)

pend list의 .TailPtr 필드는 세마포어에서 대기 중인 가장 낮은 우선순위의 task 의 OS_PEND_DATA를 가리킨다.

F10-4(4)

두 OS_PEND_DATA는 다시 OS_SEM을 가리킨다. 포인터는 OS_PEND_OBJ를 가리키고 있다고 생각한다. OS_PEND_OBJ의 .Type 필드를 조사하면 OS_PEND_OBJ가 세마포어임을 알 수 있다. .Type은 네 개의 ASCII 문자 ‘S’, ‘E’, ‘M’, ‘A’를 포함한다.

F10-4(5)

각각의 OS_PEND_DATA는 각각의 OS_TCB를 가리킨다. 즉 어떤 task가 세마포어에 대기 중인지 안다.

F10-4(6)

각 task는 OS_PEND_DATA를 가리킨다.

F10-4(7)

마지막으로, OS_PEND_DATA는 doubly linked list를 형성하여, μC/OS-III가 리스트에 쉽게 항목을 추가 또는 제거할 수 있도록 한다.

이것은 복잡해 보일 수도 있지만, 333페이지 16장 “Pending On Multiple Objects”에서 분명해질 것이다. 지금은 모든 링크가 필요하다고 가정해야한다.

표 10-3은 μC/OS-III가 pend list의 항목을 조작하기 위해 사용하는 기능을 보여준다. 이러한 기능은 μC/OS-III 내부에 있는 것들이며 애플리케이션 코드는 절대로 그것들을 호출해서는 안 된다. 코드는 os_core.c에 있다.

Function Description
OS_PendListChangePrio() pend list에 있는 task의 우선순위를 변경한다.
OS_PendListInit() pend list를 초기화한다.
OS_PendListInsertHead() pend list의 head에 OS_PEND_DATA를 넣는다.
OS_PendListInsertPrio() pend list에 OS_PEND_DATA를 우선순위에 맞게 넣는다.
OS_PendListRemove() pend list에서 여러 개의 OS_PEND_DATA를 제거한다.
OS_PendListRemove1() pend list에서 한 개의 OS_PEND_DATA를 제거한다.

(표 10-3 Pend List access functions)

Summary

μC/OS-III는 pend list를 사용하여 semaphores, mutual exclusion semaphores, event flag groups, 그리고 message queues에 대기하는 task를 추적한다.

pend list는 OS_PEND_LIST 타입의 자료구조로 구성된다. pend list는 OS_PEND_OBJ라는 또 다른 데이터 타입으로 캡슐화된다.

task는 pend list에 직접 연결되지 않고 대신 커널 객체에 대기 중인 작업의 스택에 할당된 OS_PEND_DATA라는 중간 데이터 구조를 통해 연결된다.

pend list는 μC/OS-III 내부에 있으므로, 응용 프로그램 코드는 pend list에 접근해서는 안된다.

Reference

  • uC/OS-III: The Real-Time Kernel For the STM32 ARM Cortex-M3, Jean J. Labrosse, Micrium, 2009

책 링크

댓글남기기