Task : 하나의 일 단위로 쪼갬
> 누군가가 일을 시키면 일을 하는 상태,
누구라도 기다리고 있는 상태
누군가 일을 시킨 상태
>State Transition Diagram
그렇다고.. 자기 state를 누구한테 보여주거나, 관련된 Data를 저장 > X
> 이런 일을 하는 단계들이 있다 정도
> Kernel Level에서 관리 ( Task Level : X )
: TCB 에 있음
기본적인 Task의 state, 구조.
void waiter_task()
{
waiter_task_init(); /* 여기까지 ①번 init state > 지나자 마자 ②번 wait state */
while (1)
{
wait_signal (SRV_SIGNAL); /* wait > ②번 state */
// SRV_SIGNAL 을 기다림
/* 누군가 SRV_SIGNAL > ③ Ready State
// Ready State :
Scheduler가 Task 요청 받았다는걸 알아 챌 수 있는 단계
> Scheduling할 때 순서를 줘야 하는 task 라는 걸 인식하는 단계
>> Signal을 받았다고 무작정 실행 > X */
/* ④ Scheduler : waiter_task로 Context Switching ( 상태 변환 )> 일 할 수 있게 만들어줌
현재 waiter_task가 일 하므로 > Running state. */
clear_signal (SRV_SIGNAL); /* SRV_SIGNAL을 다음번에도 받을 수 있도록 초기화 */
어서옵셔. 인사하고;
물도 갖다주고;
주문도 받아주고;
// 여러가지 동작
}
}
> 무한 loop : wait → ready → running → wait
그러면 signal을 날릴려면
void send_signal(해당task, 시킬 일);
void waiter_task()
{
waiter_task_init();
while (1)
{
wait_siganl (SRV_SIGNAL);
clear_signal (SRV_SIGNAL);
어서옵셔. 인사하고;
물도 갖다주고;
주문도 받아주고;
send_signal ( cook_task, COOK_SIGNAL); // cook_task 에게 시그널 전송
}
}
Wait State였던 cook_task() > Ready state
Scheduler : cook_task()에게 실행 순서를줌 > cook_task() : Running state > 실행 후 wait_state
task끼리 서로 일을 시킴 + 한 task가 여러 가지 일
(가정) signal : 어떤 word type의 전역변수에 각 bit 별로 할 일들이 약속되어 있음
void waiter_task()
{
waiter_task_init();
while (1)
{
wait_siganl (SRV_SIGNAL || DELIEVER_SIGNAL);
// SRV_SIGNAL 과 DELIEVER_SIGNAL 2가지 신호를 기다림
// OR 이라 하나 만들어와도 일단 준비는 됨
sig = get_signal ();
if ((sig & SRV_SIGNAL)!=0)
{
clear_signal (SRV_SIGNAL);
어서옵셔. 인사하고;
물도 갖다주고;
주문도 받아주고;
send_signal ( cook_task, COOK_SIGNAL);
}
if ((sig & DELIEVER_SIGNAL)
{
clear_signal (DELIVER_SIGNAL);
음식을 손님에게 가져다 주자 영차;
}
} /* while (1) */
}
void cook _task()
{
cook_task_init();
while (1)
{
wait_siganl (COOK_SIGNAL);
sig = get_signal ();
if ((sig & COOK_SIGNAL)!=0)
{
clear_signal (COOK_SIGNAL);
열심히 요리를 하자;
send_signal ( waiter_task, DELIVER_SIGNAL);
}
} /* while (1) */
}
waiter_task() : 두 가지 일을 할 수 있는 task가됨
cook_task() : COOK_SIGNAL > 요리 > send_signal (waiter_task, DELIEVER_SIGANL)을 waiter_task()한테 날려줌
> waiter_task() : 기다리던 DELIEVER_SIGANL 처리
Interrupt :
Hardware로 부터 전기 신호가 전달
> . Interrupt는 비 정기적으로 (Asynchronous) System에 input을 넣어줌
느닷없는 Interrupt를 통해서 waiter에게 손님이 왔을 때 알려주면?
( ARM의 Interrupt : IRQ Exception
IRQ mode 전환 > Interrupt 처리
// ISR : IRQ mode에서 Interrupt를 처리해 주는 routine
( Interrupt Service Routine)
손님이 오는것 : Interrupt
> IRQ mode 전환 > 함수실행 : customer_isr(void) 라고한다면..
// C Level의 ISR을 만드려면 > ARM : __irq 예약어 사용
void customer_isr (void)
{
send_signal (waiter_task, SRV_SIGNAL);
clear_interrupt_source (customer_coming);
}
손님 > customer_coming Interrupt > IRQ_Handler() 불려짐
> ISR : SRV_SIGNAL을 waiter_task()한테 날림
>> waiter_task() : SRV_SIGANL 받음 > Ready 상태 > Context Switch 될 때, waiter_task()로 순서가 오기만을 대기 > 순서가 오면 : 어서옵셔, 인사하고, 물 갖다 주고, 주문 받고 + ( cook한테 일 시킴)
customer_coming interrupt를 clear해 주는 code
if) 그걸 안해준다면?
customer_isr 처리 후 > 아까 customer_coming interrupt가 또 있음
> 에라이 또 customer_isr로 가자~
> System : 또 interrupt 처리 > 무한반복
// ~= heap 영역 malloc 할당해제 느낌?
'임베디드 > 임베디드 레시피' 카테고리의 다른 글
TCB - Task , CS (1) | 2024.12.17 |
---|---|
선점형 Multitasking (0) | 2024.12.14 |
Task 구조, signal (0) | 2024.12.12 |
Embedded Software는 무한 Loop (0) | 2024.12.11 |
6장) RTOS, Kernel (0) | 2024.12.11 |