AVR SEI 명령


13

AVR SEI 명령어 ( http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_SEI.html )는 인터럽트를 활성화하기 전에 다음 명령어가 완료되기를 기다립니다.

SREG에서 다른 플래그를 사용하여 I 플래그를 설정하면 1 개의 명령도 대기합니까?

다시 말해 : 대기는 SEI 명령 또는 상태 레지스터의 기능입니까?

SEI 명령어의 기능인 경우 SEI를 실행하는주기 또는 다음 명령어와 함께 플래그가 실제로 어느 시점에 설정됩니까?


이것은 좋은 질문이지만 테스트하고 확인하기가 너무 어렵지 않아야합니다.
Vorac

1
@Vorac 어떻게 테스트 할 수 있는지 예를 들어 주시겠습니까? 그것은 내가 받아 들인 대답이 될 것입니다.
jayjay

1
AVR 아키텍처 구현 및 인터럽트를 처리 할 수있는 기능 일 수 있습니다. AVR 아키텍처 인 IIRC는 3 단계 파이프 라인을 사용했습니다. 따라서 다음 플래그는 I 플래그 변경을 사용하여 인터럽트를 확인하기 전에 이미 '비행 중'(즉, 파이프 라인 1 단계 이상) 일 수 있습니다. 나는 오랫동안 찾지 않았지만 AVR 아키텍처의 설계자가 자신을 과도하게 구속했을 것이라고 생각하지 않습니다. 그래서, 파이프 라인의 1 단계에서 명령에 대한 인터럽트를 테스트하고, 하지 (2 단계에서) 다음 명령하기 전에 그들에게 약간의 유연성을 제공합니다.
gbulmer

답변:


8

실험 결과!

다른 답변은 사려 깊고 잘 추론되지만 모두 불완전하거나 추측입니다. 문서가 모호한 경우에는 모든 경우를 실험하고 테스트해야합니다.

이 질문은 결정적인 답변이 필요하므로 AVR을 꺼내어 약간의 비트 설정을 시작하십시오!

순서

테스트하기 위해 작은 Arduino (ATMEGA328P) 프로그램을 만들었습니다 ...

  1. 절대 반환하지 않는 ISR 설정 ( while (1))
  2. 소프트웨어에서 트리거 할 수있는 소스에 ISR 할당 ( INT0낮음)
  3. 비활성화 된 인터럽트
  4. 인터럽트를 활성화하고 트리거하여 보류 중

인터럽트가 활성화 된 후 단일 명령으로 LED를 켜는 테스트 베드를 사용했습니다. 테스트 베드에서 인터럽트를 활성화하고 LED를 확인하는 다른 방법을 시도함으로써 활성화 명령어 이후의 명령어가 실행되었는지 여부를 알 수있었습니다.

LED가 켜지지 않으면 인터럽트가 활성화 된 직후 ISR이 실행 (및 잠금) 된 것입니다.

LED가 켜지면 ISR이 호출되기 전에 다음 명령이 실행될 수 있음을 알고 있습니다.

결과

SEI 교육 (기본 사례)

암호:

sei

결과 : LED가 켜집니다. 다음 명령이 실행되었습니다.

OUT 교수

암호:

in  r16,0x3f   // Get SREG
ori r16,128    // Set I bit 
out 0x3f,r16   // Save back to SREG

결과:

LED가 켜집니다. 다음 명령이 실행되었습니다.

ST 교수

암호:

   clr r29        // Clear Y high byte
   ldi r28,0x5f   // Set Y low byte to point to SREG
   ld r16, Y      // Get SREG
   ori r16,128    // Set I bit 
   st Y,r16       // Put SREG

결과:

LED가 켜집니다. 다음 명령이 실행되었습니다.

결론!

Q : 대기는 SEI 명령어 또는 상태 레지스터의 기능입니까?

A : I비트를 SREGa에서 a 0로 변경하면 비트 1를 설정하는 데 사용되는 명령에 관계없이 보류중인 인터럽트가 있어도 다음 명령을 다음에 실행할 수 있습니다.

노트

이것은 실제로 많은 합병증으로 매우 흥미로운 질문으로 바뀌 었습니다. 당신이 그가 세부 사항에 관심이 있다면, 체크 아웃 ...

http://wp.josh.com/2016/01/05/different-ways-to-set-i-bit-in-avr-sreg-besides-sei/


2
사양이 모호한 경우 "실증 결과"에 문제가 있습니다. 테스트 한 특정 하드웨어가 특정 방식으로 작동한다고해서 다른 부품이 그렇게 작동하는 것은 아닙니다. Atmel은 사양을 변경하지 않는 한 구현을 변경할 자유가 있습니다. 따라서 "문서가 모호한 곳이라면 ..."은 실험과 테스트 후에도 여전히 모호한 것으로 남아 있습니다.
gbulmer

@gbulmer 100 % 동의합니다. 프로덕션에서 문서화되지 않은 기능을 사용하는 사람은 슬프게됩니다. 여전히 흥미로운 경험적 질문과 대답이며, 일회성 개인 프로젝트에 의존하는 것이 좋습니다.
bigjosh

예, 당신은 매혹적인 조사를했습니다.
gbulmer

4

sei지시 사항 을 수행하는 것이 SREG의 1 비트에 1 비트를 직접 쓰는 것과 다르지 않다는 것을 문서에서 이해 합니다. 이 명령의 장점은 1<<ISREG를 변경하기 위해 먼저 작업 레지스터에 값을로드 할 필요가 없으므로 시간이 절약된다는 것입니다.

다음을 사용하여 자세히 설명하십시오 sei.

sei ; One cycle

비트를 사용하여 설정 sbi(SREG가 레지스터 맵의 하위 32 바이트에있는 경우에만 작동하지만 대부분은 그렇지 않은 것 같습니다.)

sbi SREG,7 ; Two cycles

SREG에서 직접 작성 :

in  r24,SREG ;
ori r24,0x80 ;
out SREG,r24 ; Three cycles

I비트는 즉시 SREG 설정해야 sei명령 (또는 sbiout) 완료한다. 그러나 보류중인 인터럽트는 다음 명령어가 완료 될 때까지 처리되지 않습니다 . 비트가 설정되지만 인터럽트가 활성화 되려면 추가주기가 필요합니다. 인터럽트는 명령어 중간에 처리 할 수없고 일부 명령어는 실행하는 데 두 번 이상의주기가 걸리므로 하나의 명령어로 활성화되는 데 걸리는 시간을 지정합니다. 이것은 모든 버전의 코드에 해당됩니다. 즉, 위의 각 코드는 명령 지연을 유발합니다.


약간의 검색 결과 , Arduino 포럼 에서이 스레드를 발견했습니다. 스레드에서는 동작을 확인하기 위해 여러 가지 다른 테스트가 수행되었습니다. 내가 위에서 말한 것에 동의하는 것 같습니다.

또한 해당 스레드에 따라 I플래그가 이미 설정된 경우 지연된 응답에 대한 지연된 응답이 없으므로 지연된 응답은 sei명령 자체가 아니라 I플래그에 의해 제어되는 내부 하드웨어에 의해 발생합니다. SREG에서 플래그를 변경하는 모든 작업, 그래서 그것을 수 sei또는 out또는 sts것입니다 정확히 동일한 동작을.


따라서 SEI에만 해당하지만 OUT이 아닌 작동 지연의 측면이 없어서 다음 명령을 완료 할 수 있습니까?
Brian Drummond

두 번째 예의 경우 보류중인 인터럽트는 언제 처리됩니까? 첫 번째와 같은 사이클 지연이 있습니까?
jayjay

@jayjay 내 업데이트를 참조하십시오.
Tom Carpenter

1
참고 SBI세트에 사용할 수 없습니다 I에 조금 SREG조차 조립하지 않기 때문에이 가능성이 실제로 현실에서 테스트되지 않는 코드 때문에. 32 개의 하위 레지스터SBI 에서만 작동 할 수 있으며 SREG는 슬롯 63에 있습니다.
bigjosh

@bigjosh SBI 예제는 내가 나중에 생각했던 것입니다- out원래 사용했던 것입니다. 나는 32 개의 하위 레지스터에 SREG가있는 AVR (ATTIy 일 수 있음)을 보게 될 것이라고 생각했지만 상상할 수도 있습니다.
톰 카펜터

1

IMHO는 SREG에 쓰기를 여전히 지연 1 명령은 다음과 같이 테스트 할 수 있습니다 (의사 코드).

ISR() { PORTA = 0; while(1); }
main() 
{
    cli();
    DDRA = 0xff;
    configure_isr_for_level_interrupt_that_will_trigger_immediately();
    SREG = 0xff;
    cli();
    PORTA = 0xff;
    while(1);
}

불행히도 나는 그것을 할 시간이 없다 :(


0

그것은 그것이 말하는 것이 아닙니다. 설명서에 따르면

SEI 다음의 명령어는 보류중인 인터럽트 전에 실행됩니다.

다음 명령을 기다리는 것이 아닙니다. 플래그가 즉시 설정되었지만이 명령을 읽었지만 활성화되었지만 다음 명령이 실행될 때까지 인터럽트가 처리되지 않습니다.


이것은 모두 사실이지만 제 질문은이 행동이 SEI에만 해당됩니까?
jayjay

@jayjay 나는 이것이 명령 파이프 라인 길이 때문이라고 생각합니다.
crasic
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.