여러 컴퓨터에서 유용한 것으로 밝혀진 것은 간단한 스택 스위처입니다. 실제로 PIC 용으로 작성하지는 않았지만 두 스레드 / 모든 스레드가 총 31 이하의 스택 레벨을 사용하는 경우 PIC18에서 접근 방식이 제대로 작동 할 것으로 기대합니다. 8051에서 주요 루틴은 다음과 같습니다.
_taskswitch :
xch a, SP
xch a, _altSP
xch a, SP
ret
PIC에서 스택 포인터의 이름을 잊었지만 루틴은 다음과 같습니다.
_taskswitch :
movlb _altSP >> 8
movf _altSP, w, b
movff _STKPTR, altSP
movwf _STKPTR, c
반환
프로그램 시작시, 대체 스택의 주소로 altSP를로드하고 (16은 PIC18Fxx에서 잘 작동 할 수 있음) task2 루프를 실행하는 task2 () 루틴을 호출하십시오. 이 일과는 결코 돌아 오지 않아야합니다. 대신 기본 작업에 대한 제어 권한을 원할 때마다 _taskswitch를 호출해야합니다. 그런 다음 기본 작업은 보조 작업을 수행 할 때마다 _taskswitch를 호출해야합니다. 종종 다음과 같은 귀여운 작은 루틴이 있습니다.
void delay_t1 (부호없는 짧은 값)
{
하다
taskswitch ();
while ((부호없는 짧은) (밀리 초 _ 시계-val)> 0xFF00);
}
작업 전환기에는 '조건 대기'를 수행 할 수있는 방법이 없습니다. 그것이 지원하는 것은 spinwait입니다. 반면에 작업 전환이 너무 빨라서 다른 작업이 타이머 만료를 기다리는 동안 taskswitch ()를 시도하면 다른 작업으로 전환되고 타이머를 확인한 후 일반적인 작업 전환기보다 빠르게 다시 전환됩니다. 작업 전환이 필요하지 않다고 판단합니다.
협력적인 멀티 태스킹에는 몇 가지 제한이 있지만 일시적으로 방해가되는 불변이 빠르게 재 확립 될 수있는 경우 많은 잠금 및 기타 뮤텍스 관련 코드가 필요하지 않습니다.
(편집) : 자동 변수 등에 관한 몇 가지주의 사항 :
- 작업 전환을 사용하는 루틴이 두 스레드에서 호출되는 경우 일반적으로 두 개의 루틴 사본을 컴파일해야합니다 (아마도 #define 문이 동일한 # 동일한 소스 파일을 두 번 포함). 주어진 소스 파일에는 하나의 스레드에 대한 코드 만 포함되거나 그렇지 않으면 각 스레드에 대해 두 번 컴파일되는 코드가 포함되므로 "#define delay (x) delay_t1 (x)"또는 사용중인 스레드에 따라 #define delay (x) delay_tx (x) "
- 호출되는 함수를 "볼"수없는 PIC 컴파일러는 이러한 함수가 모든 CPU 레지스터를 폐기 할 수 있다고 가정하므로 작업 스위치 루틴에서 레지스터를 저장할 필요가 없습니다. 선점 형 멀티 태스킹]. 다른 CPU에 대해 유사한 작업 전환기를 고려하는 사람은 사용중인 레지스터 규칙을 알고 있어야합니다. 적절한 스택 공간이 있다고 가정 할 때 작업 전환 전에 레지스터를 푸시하고 이후에 팝하는 것이 쉬운 방법입니다.
협동 멀티 태스킹은 잠금 문제를 완전히 피할 수는 없지만 실제로는 크게 단순화합니다. 예를 들어, 압축 가비지 수집기가있는 선점 형 RTOS에서는 개체를 고정 할 수 있어야합니다. 협동 스위처를 사용할 때 taskswitch ()가 호출 될 때마다 GC 객체가 움직일 수 있다고 가정하는 경우 필요하지 않습니다. 고정 된 물체에 대해 걱정할 필요가없는 압축 수집기는 그렇게하는 것보다 훨씬 간단 할 수 있습니다.