변수가> 1 ISR에서 액세스되지만 ISR 외부에서 공유되지 않는 경우 휘발성이 필요합니까?


9

있어 명확하게 문서화 된 글로벌 데이터가 ISR 및 메인 프로그램과 공유 될 때, 데이터 요구가 선언 할 것을 volatile보증 메모리 가시성하기 위해 (그리고 그것은 단지 1 바이트 데이터에 충분하다; 아무것도 더 큰 요구도 보장 자성 특별한 조치를) . 여기 좋은 규칙이 있습니다.

  • ISR 외부에서만 사용되는 변수는 변동성이 없어야합니다.
  • ISR 내부에서만 사용되는 변수는 변동성이 없어야합니다.
  • ISR 내부 및 외부에서 사용되는 변수는 변동성이 있어야합니다.

그러나 volatile변수가> 1 ISR에서 액세스되지만 ISR 외부에서 공유되지 않는 경우에 필요합니까? 예를 들어 static변수를 사용하여 내부 상태를 유지하는 함수가 있습니다 .

void func() {
    static volatile long counter; // volatile or not?
    // Do stuff with counter etc.
}

이 함수는 핀 인터럽트와 TimerOne 라이브러리 에서 두 가지 방법으로 호출됩니다 .

  1. attachInterrupt(0, func, CHANGE);
  2. Timer1.attachInterrupt(func);

ISR이 입력되면 인터럽트가 자동으로 비활성화 되므로 원 자성 문제는 없습니다 . 그러나 이것은 volatile캐시 된 문제와 그렇지 않은 문제에 대한 컴파일러 문제입니다.

물론 미안보다 안전합니다.

답변:


9

volatile 컴파일러의 코드 생성기에 변수가 생성되는 코드 이외의 다른 변수에 의해 수정 될 수 있음을 알려주므로 해당 복사본이 정확하다고 가정하지 마십시오.

ISR 코드는 입력시 컨텍스트가 없다는 가정하에 작성 / 생성해야하며 ISR 자체 조작에 대한 CPU 컨텍스트를 유지해야합니다. 따라서 비 원자 작업의 불가분성과 마찬가지로 변동성은 이 경우 * 인터럽트가 중첩 될 수 있는지 여부에 따라 달라집니다 . 비 중첩이 보장되면 공유 변수는 자체 실행 중에이 ISR 이외의 다른 변수로 변경할 수 없습니다. 인터럽트가 중첩 될 수있는 환경에서 언젠가 ISR을 사용할 수 있으면 해당 제약 조건이 더 이상 유지되지 않습니다.

* 이 경우 :
소프트웨어 유지 변수를 가정합니다. 하드웨어 이벤트, 예를 들어 타이머 레지스터에 의해 업데이트 될 수있는 변수에 대해 이야기하고 있다면 모든 베팅이 해제되어 있습니다.


따라서 Arduino의 기본 "인터럽트가 중첩되지 않음"동작을 변경하지 않는 한 변수는 volatile생성 될 코드 이외의 다른 것으로 수정 되지 않으므로 변수가 필요하지 않습니다 . 컴파일러는 인터럽트가 중첩되지 않는 한 ISR이 선형으로 실행된다고 가정 할 수 있습니다. 말이 되네요 감사!
Joonas Pulakka 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.