타이머 인터럽트 (재)
개요
이전에 타이머 인터럽트가 실현되었지만 인터럽트 전, 인터럽트 처리 및 인터럽트 후 컨텍스트 정보는 전혀 고려하지 않았습니다. 즉, 인터럽트가 들어간 후 인터럽트 처리로 레지스터가 파괴 될 가능성이있었습니다. 이전의 예에서는, 거의 타이머 인터럽트의 처리 밖에 없었기 때문에 파괴되는 일도 없고, 파손된 곳에서 어떻게 하지 않았지만, 향후 이 타이머 인터럽트로 thread를 전환하는 것을 생각하면, 문맥을 보존해 둘 필요가 있다.
따라서 컨텍스트를 저장하도록 타이머 인터럽트를 개선합니다. 또한 인터럽트 처리는 다른 스택을 사용하는 개선도 수행합니다.
컨텍스트 저장
컨텍스트 저장은 레지스터 값을 저장하는 것을 의미합니다. atmega328p에는
r0 ~ r31의 32 개의 레지스터가 있습니다. 또한, SREG라는 플래그 레지스터로 상태를 관리하고 있으므로, 어떻게 하면 된다.이 처리는 인터럽트 벡터에 등록 된 함수로 수행됩니다.
인터럽트 벡터 개선 1
컨텍스트를 저장하도록 인터럽트 벡터의 함수를 변경합니다. 이전에는
start.s에 함수를 정의했지만 인터럽트 전용 파일 (intr.s)을 준비합니다.intr.s
.global intr_time
.type   intr_time, @function
intr_time:
    cli
    push r31
    push r30
    push r29
    push r28
    push r27
    push r26
    push r25
    push r24
    push r23
    push r22
    push r21
    push r20
    push r19
    push r18
    push r17
    push r16
    push r15
    push r14
    push r13
    push r12
    push r11
    push r10
    push r9
    push r8
    push r7
    push r6
    push r5
    push r4
    push r3
    push r2
    push r1
    push r0
    in r31, 0x3f ; save SREG to r31
    push r31     ; push SREG
    rcall t0a    ; t0aの呼び出し
    pop r31        ; pop SREG to r31
    out 0x3f, r31  ; set SREG
    pop r0
    pop r1
    pop r2
    pop r3
    pop r4
    pop r5
    pop r6
    pop r7
    pop r8
    pop r9
    pop r10
    pop r11
    pop r12
    pop r13
    pop r14
    pop r15
    pop r16
    pop r17
    pop r18
    pop r19
    pop r20
    pop r21
    pop r22
    pop r23
    pop r24
    pop r25
    pop r26
    pop r27
    pop r28
    pop r29
    pop r30
    pop r31
    reti
앞에서 설명한 것처럼 r31에서 r0까지 SREG (플래그 레지스터) 스택에 쌓인 다음 t0a를 호출하고 반환되면 쌓인 순서와 반대로 스택에서 POP합니다. SREG는 메모리 0x3f에 존재합니다 (사양서에서).
이 때의 스택의 모습은 다음과 같습니다.

이와 같이, 인터럽트 처리를 하기 위해, 직전까지 실행하고 있던 메인의 스택을 그대로 이용하고 있다.
인터럽트 벡터 개선 2
위에서 설명한 것처럼 작동하지만 향후 스레드를 구현하는 것을 고려할 때 인터럽트 프로세스는 항상 스레드의 스택을 사용합니다. 실해는 없지만 인터럽트 처리는 전용 스택을 사용하고 싶다. 구체적으로는 다음과 같이 스택을 전환하여 사용하고 싶습니다.

이 예에서는
t0a를 호출하기 전에 스택을 전환 (intstack)하고 t0a를 처리 한 후 다시 원래의 스택으로 되돌려 인터럽트 처리를 완료합니다. 이렇게하려면 intrstack를 링커 스크립트로 정의하십시오.ld.scr
MEMORY{ 
(略)
    ram(rwx)        : o = 0x800100, l = 0x800600 - 0x800100
    userstack(rw)   : o = 0x800600, l = 0x000000
    intrstack(rw)   : o = 0x800700, l = 0x000000 ; 割り込み用スタック
    bootstack(rw)   : o = 0x8007fc, l = 0x000000
}
SECTIONS
{
(略)
    . = ALIGN(4);
    _end = . ;
    .userstack : {
        _userstack = .;
    } > userstack
    .intrstack : {
        _intrstack = .;
    } > intrstack
  .bootstack : {
        _bootstack = .;
    } > bootstack
}
그런 다음 그림과 같이 처리를 수행하기 위해
intr_time를 다시 씁니다.intr.s
intr_time:
        cli
        push r31
(略)
        push r0
        in   r31, 0x3f ; SREG
        push r31
        in   r24, 0x3d ; save current sp low  to r22
        in   r25, 0x3e ; save current sp high to r23
        ldi  r28, lo8(_intrstack) ; save intrrstack lo byte to r28
        ldi  r29, hi8(_intrstack) ; save intrstack hi byte to r29
        out  0x3d, r28 ; save intrstack low   ; change sp to intrstack
        out  0x3e, r29 ; save intrstack high
        push r24       ; 旧SPのlowをintrstackに積む
        push r25       ; 旧SPのhiをintrstackに積む
        eor  r1, r1
        rcall t0a
        pop r29        ; pop old sp hi  from intrstack
        pop r28        ; pop old sp low from intrstack
        out 0x3d, r28  ; set sp low
        out 0x3e, r29  ; set sp high   -> change sp to original
        pop r31        ; restore SREG to r31
        out 0x3f, r31  ; set SREG
        pop r0
(略)
        pop r31
        reti
이 구현은 다음 명령으로 시도 할 수 있습니다.
>git clone https://github.com/hiro4669/iosv.git
>cd iosv
>git branch interpt_ver1 origin/interpt_ver1
>git checkout interpt_ver1
>cd interpt
>make
>make write
Reference
이 문제에 관하여(타이머 인터럽트 (재)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/hiro4669/items/f48835d8178176953660텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)