0

나는 단지 volatile 키워드의 개념을 살펴 보았습니다. 방금 this link을 거쳤습니다.이 링크는 인터럽트 처리기를 사용하는 프로그램의 경우 volatile 키워드를 사용해야하는 이유에 대해 알려줍니다. 그들은 하나의 예에서 언급 한 : 컴파일러 ext_rcvd 인터럽트 핸들러에서 업데이트지고 알 수없는 때문에전역 변수가 다른 스레드에 의해 변경되면 컴파일러가 어떻게 감지하지 못합니까?

int etx_rcvd = FALSE; 
void main() 
{ 
    ... 
    while (!ext_rcvd) 
    { 
     // Wait 
    } 
    ... 
} 

interrupt void rx_isr(void) 
{ 
    ... 
    if (ETX == rx_char) 
    { 
     etx_rcvd = TRUE; 
    } 
    ... 
} 

그들은 말하고있다. 따라서 컴파일러는 최적화 인텔리전스를 사용하며이 변수 값은 항상 FALSE이고 while{} 조건을 입력하지 않는다고 가정합니다. 따라서 이러한 상황을 방지하기 위해 우리는 volatile 키워드를 사용하여 컴파일러가 자체 인텔리전스를 사용하지 못하게합니다.

내 질문은 컴파일러가 어떻게하면 ext_rcvd이 인터럽트 처리기에서 업데이트되고 있는지 알 수 없다는 것입니다. 내가 그 대답을 찾을 수 있도록 도와주세요, 나는 이것에 대한 정답을 얻지 못하고 있습니다.

답변

0

CPU가 인터럽트를 받으면 더 중요한 인터럽트를 처리하지 않는 한 인터럽트를 중단하고 (더 중요한 인터럽트를 처리 할 때만 더 중요한 인터럽트를 처리 할 때만 처리합니다), 특정 매개 변수를 스택에 저장합니다 인터럽트 처리기를 호출합니다. 이는 시스템이 알 수없는 상태에 있기 때문에 인터럽트 처리기 자체에서 특정 사항을 허용하지 않음을 의미합니다. 이 문제에 대한 해결책은 인터럽트 처리기가 즉시 수행해야 할 작업을 수행하는 것입니다. 일반적으로 하드웨어에서 무언가를 읽거나 무언가를 하드웨어로 보내고 나중에 새 정보를 처리하도록 예약합니다. "bottom half")와 리턴. 그런 다음 커널은 가능한 한 빨리 하반부를 호출하도록 보장되며, 커널 모듈에 허용되는 모든 사항이 허용됩니다.

나는 인터럽트가 작동하는 모든 것이 중단되고 변수가 TRUE로 설정되어 while 조건을 만족하지 않을 때 생각합니다. 그러나 volatile 키워드를 사용하면 C가 변수 값을 다시 확인하게됩니다.

물론 나는 이것에 대해 100 % 확신 할 수는 없지만 변경 광산에 대한 답변은 공개되어 있습니다.

+0

하지만 내 질문은 어떻게 컴파일러가 변수가 interupt 처리기에 의해 업데이트되고 있는지 알 수 없습니다. 같은 일이 멀티 스레드의 경우, 컴파일러는 두 번째 스레드가이 값을 업데이 트하는 것을 알 수 없습니다. 컴파일은 CPU에서 실행되기 훨씬 전에입니다. –

1

ext_rcvd의 메모리 위치를 수정할 수있는 모든 코드 또는 실행중인 프로세스을 분석 할 수 없습니다.

예를 들어, ext_rcvd이 인터럽트 처리기에서 업데이트되고 있다고 언급했습니다. 맞아요. 인터럽트 처리기는 CPU가 인터럽트를 수신하면 운영 체제에서 시작하는 코드 조각입니다. 이 코드는 실제로 드라이버 코드입니다. 드라이버 코드에서 ext_rcvd이라는 다른 이름을 가질 수 있지만 같은 메모리 위치를 가리킬 수 있습니다.

따라서 ext_rcvd이 다른 곳에서 업데이트되었는지 확인하려면 컴파일러에서 라이브러리와 드라이버의 코드를 분석하고 코드에서 ext_rcvd과 동일한 메모리 위치를 업데이트해야합니다. 실행 시간 전에 수행 할 수 없습니다.

멀티 스레딩의 경우에도 마찬가지입니다. 컴파일러는 특정 스레드가 다른 스레드가 사용하는 정확한 메모리 위치를 업데이트하는 경우 사전에 알 수 없습니다. 예를 들어 다른 스레드가 syscall()을 만든다면 컴파일러는 syscall()을 처리하는 코드를 살펴 봐야합니다.

0

interrupt은 C 지정 키워드가 아니므로 논의 된 것은 C 지정 동작이 아닙니다. >volatile int etx_rcvd -

예 컴파일러 etx_rcvdinterrupt 루틴 내에서 수정 따라서 인터럽트 함수 외부 언제든지 변경 int etx_rcvd을 만들 수 etx_rcvd 가정되는 것을 볼 수 있었다.

이제 질문은 일까요해야합니까?

IMO : 아니요, 필요하지 않습니다.

interrupt 함수는 전역 변수를 수정할 수 있으며 코드 흐름은 비 인터럽트 함수 액세스가 인터럽트 보호 블록에서만 발생하는 것과 같습니다. 최적화 컴파일러는 int etx_rcvd으로 volatile을 암시함으로써 방해를 받게됩니다. 이제는 코드가 가 OP를 찾는 것을 막기 위해 non_volatile int etx_rcvd라고하는 방법이 필요합니다.

C는 모두 volatile 변수 (추가 volatile)와 비 휘발성 (volatile을 추가하지 않음)을 선언하는 메소드를 제공합니다. interrupt 루틴이 변수를 선언하지 않고 volatile 변수를 만들 수있는 경우 코드에 비 휘발성을 보장하는 새 키워드가 필요합니다.

관련 문제