const와 const volatile의 차이
변수를 다음과 같이 선언하면volatile새로운 값이 갱신될 때마다
변수를 다음과 같이 선언하면const그러면 해당 변수의 값은 변경되지 않습니다.
그리고나서const volatile int temp;
변수를 선언하는 것이 무슨 소용입니까?temp위와 같이요?
라고 선언하면 어떻게 됩니까?const int temp?
마크가 붙은 오브젝트const volatile코드에 의한 변경이 허가되지 않습니다(이 때문에 에러가 발생합니다).const한정자) - 적어도 그 특정 이름 또는 이름을 사용합니다.
그volatile한정자의 일부는 컴파일러가 오브젝트에 대한 접근을 최적화하거나 순서를 변경할 수 없음을 의미합니다.
임베디드 시스템에서는 일반적으로 하드웨어 레지스터에 액세스하기 위해 사용됩니다.이 레지스터는 하드웨어에 의해 읽혀지고 갱신되지만 쓰기에는 의미가 없습니다(또는 쓰기 오류일 수 있습니다).
예를 들어 시리얼 포트의 상태 레지스터를 들 수 있습니다.다양한 비트는 문자가 읽기 대기 중인지 또는 전송 레지스터가 새 문자를 수신할 준비가 되었는지(즉, 비어 있음)를 나타냅니다.이 상태 레지스터를 읽을 때마다 시리얼 포트 하드웨어에서 발생한 다른 작업에 따라 값이 달라질 수 있습니다.
상태 레지스터에 쓰는 것은 의미가 없지만(특정 하드웨어 사양에 따라 다름), 레지스터를 읽을 때마다 실제 하드웨어 읽기가 이루어지도록 해야 합니다.이전에 읽은 캐시 값을 사용하면 하드웨어 상태 변경에 대해 알 수 없습니다.
간단한 예:
unsigned int const volatile *status_reg; // assume these are assigned to point to the
unsigned char const volatile *recv_reg; // correct hardware addresses
#define UART_CHAR_READY 0x00000001
int get_next_char()
{
while ((*status_reg & UART_CHAR_READY) == 0) {
// do nothing but spin
}
return *recv_reg;
}
이러한 포인터가 존재로 표시되지 않은 경우volatile, 몇 가지 문제가 발생할 수 있습니다.
- while loop test는 상태 레지스터를 한 번만 읽을 수 있습니다.왜냐하면 컴파일러는 이 레지스터가 무엇을 가리키든 절대 변경되지 않을 것이라고 가정할 수 있기 때문입니다(while loop test 또는 루프 자체에는 그것을 변경할 수 있는 것이 없습니다).UART 하드웨어에서 대기 중인 문자가 없을 때 함수를 입력하면 문자가 수신되어도 멈추지 않는 무한 루프가 발생할 수 있습니다.
- 수신 레지스터의 읽기는 컴파일러에 의해 while loop 이전으로 이동될 수 있습니다.이것도 함수에 다음과 같은 것을 나타내는 것은 없기 때문입니다.
*recv_reg루프에 의해 변경되므로 루프에 들어가기 전에 읽을 수 없는 이유는 없습니다.
그volatile한정자는 이러한 최적화가 컴파일러에 의해 수행되지 않음을 보증합니다.
volatile는 컴파일러에 변수와 관련된 코드를 최적화하지 않도록 지시합니다.보통 다른 스레드에 의해 변수가 변경될 수 있다는 것을 알고 있을 때 입니다.const는 컴파일러에게 프로그램이 변수 값을 수정하는 것을 금지한다고 알려줍니다.const volatile는 매우 특별한 것입니다.인생에서 딱 0번 사용되는 것을 알 수 있습니다(tm).예상대로, 프로그램은 변수 값을 수정할 수 없지만 외부에서 값을 수정할 수 있으므로 변수에 대한 최적화는 수행되지 않습니다.
주식회사,const그리고.volatile는 유형 한정자이며 이 두 가지는 독립적입니다.
기본적으로는const프로그램에 의해 값이 수정되지 않음을 의미합니다.
그리고.volatile값이 갑자기 변경될 수 있음을 의미합니다(프로그램 외부에서 변경됨).
사실, C 기준서는 다음과 같은 유효한 선언의 예를 제시한다.const그리고.volatile예를 들어 다음과 같습니다.
extern const volatile int real_time_clock;
어디에real_time_clock는 하드웨어로 변경할 수 있지만 할당, 증가 또는 감소는 할 수 없습니다.
그래서 우리는 이미 치료해야 한다.const그리고.volatile따로따로이러한 유형 한정자를 적용할 수 있습니다.struct,union,enum그리고.typedef뿐만 아니라.
변수가 일정하기 때문에 두 시퀀스 포인트 간에 변경되지 않았을 수 있습니다.
일관성은 값을 변경하지 않겠다는 약속이지, 값이 변경되지 않는다는 약속은 아닙니다.
사용할 수 있습니다.const그리고.volatile함께.예를 들어,0x30는 외부 조건에 의해서만 변경되는 포토의 값으로 간주됩니다.다음 선언은 우발적인 부작용의 가능성을 방지합니다.
const volatile char *port = (const volatile char *)0x30;
const변수는 C 코드로 변경할 수 없는 것이지 변경할 수 없는 것은 아닙니다.즉, 어떤 명령도 변수에 쓸 수 없지만 값이 변경될 수 있습니다.
volatile변수는 언제든지 변경될 수 있으므로 캐시된 값은 사용할 수 없습니다.변수에 대한 각 액세스는 해당 메모리주소에 대해 실행해야 합니다.
에는 "태그가 있고 "embedded"라고 temp레지스터가 이들은
휘발성 읽기/쓰기 데이터 메모리(RAM)와 비휘발성 읽기 전용 데이터 메모리(예를 들어 von-Neumann 아키텍처의 FLASH 메모리)를 모두 갖춘 임베디드 프로세서. 여기서 데이터와 프로그램 공간은 공통 데이터 및 주소 버스를 공유한다.
「 」라고 선언했을 const temp값을 가지기 위해(적어도0과 다른 경우), 컴파일러는 변수를 플래시 공간 내의 주소에 할당합니다.이는 RAM 주소가 RAM 주소에 할당되어 있어도 변수의 초기값을 저장하기 위해 플래시 메모리가 필요하기 때문에 모든 조작이 읽기 전용이기 때문에 RAM 주소는 공간 낭비가 되기 때문입니다.
그 결과:
int temp;는 RAM에 저장되는 변수이며 시작 시(cstart)에 0으로 초기화되어 캐시된 값을 사용할 수 있습니다.
const int temp;는 (되어 있는 변수입니다.FLASH는 컴파일러 시 0으로 초기화되며 캐시된 값을 사용할 수 있습니다.
volatile int temp;는 RAM에 저장된 변수이며 시작 시(cstart) 0으로 초기화되어 캐시된 값은 사용되지 않습니다.
const volatile int temp;는 (되어 있는 변수입니다.시 을 사용하지.FLASH는 0으로 설정되어 .
다음은 유용한 부분입니다.
의 Embedded 는 특수한 모듈을 하여 읽기 할 수 .이, 「」는 「비휘발성 메모리」를 사용합니다.const int temp실행 시 변경할 수 있지만 직접 변경할 수는 없습니다.할 수 .temp장됩니니다다
, 예를 들면 ' 낫다'를 들 수 있습니다.temp이치노되었을 때, 「」는 「 」temp는 0는 이 하여 생산 할 수 하면, 해, 의 변경을 .함수는 이 사실을 사용하여 실제 가동 중에 테스트를 실행할 수 있습니다.이것에 성공하면, 시리얼 번호를 할당해, 값을 변경하도록 요구해 주세요.temp는 OTP( 있습니다.일부 프로세서는, 이것만을 위해서, OTP(One-Time Programmable) 메모리를 사용하는 특수한 주소 범위를 가지고 있습니다.
하지만 여기 차이점이 있습니다.
ifconst int temp는 원타임 이며, declared 1로 있지 않습니다.volatile캐시된 값은 다음 부팅까지 사용될 수 있습니다.즉, 새로운 ID는 다음 재부팅까지 유효하지 않을 수 있습니다.또한 일부 함수는 새로운 값을 사용하는 반면 다른 함수는 재부팅할 때까지 오래된 캐시된 값을 사용할 수 있습니다. ifconst int temp가 IS로 선언되었습니다.voltaile아이디 변경은 유효합니다.
간단히 말해, '계속 휘발성' 변수의 값은 프로그래밍 방식으로 수정할 수 없지만 하드웨어에 의해 수정할 수 있습니다.여기서 휘발성은 컴파일러 최적화를 방지하기 위한 것입니다.
일부 구성 변수가 부트 로더에서 업데이트할 수 있는 플래시 메모리 영역에 있는 임베디드 애플리케이션에서 이 기능을 사용해야 했습니다.이러한 구성 변수는 런타임 동안 '일정'하지만 휘발성 수식자가 없으면 컴파일러는 다음과 같은 것을 최적화합니다.
cantx.id = 0x10<<24 | CANID<<12 | 0;
...정수값을 미리 계산하여 즉시 어셈블리 명령을 사용하거나 가까운 위치에서 정수를 로드하여 설정 플래시 영역의 원래 CANID 값에 대한 업데이트를 무시합니다.CANID는 항상 휘발성이 있어야 합니다.
이 문서에서는 const 수식자와 volatile 수식자를 조합하는 시나리오에 대해 설명합니다.
http://embeddedgurus.com/barr-code/2012/01/combining-cs-volatile-and-const-keywords/
프로그램에서 변수를 변경하지 않으려는 경우 변수에 대해 'const' 키워드를 사용합니다.변수 '계속 휘발성'을 선언할 때, 우리는 프로그램과 컴파일러에게 이 변수가 외부로부터의 입력으로부터 예기치 않게 변경될 수 있다고 말하고 있습니다.
언급URL : https://stackoverflow.com/questions/4592762/difference-between-const-const-volatile
'itsource' 카테고리의 다른 글
| vs omp simd의 병렬: 각각 언제 사용합니까? (0) | 2022.08.14 |
|---|---|
| Vue js의 인스턴스 외부에서 데이터에 액세스하는 방법이중 값을 소수점 2자리로 포맷하는 가장 좋은 방법 (0) | 2022.08.14 |
| 사전 로드된 상태의 사용자 지정 nuxt 500 오류 페이지 (0) | 2022.07.21 |
| VueJ는 데이터를 개체로 가져옵니다. (0) | 2022.07.21 |
| 어레이의 개체를 변경하고 반응성을 트리거합니다. (0) | 2022.07.21 |