Difference between revisions of "Const and volatile type qualifiers"

From Teknologisk videncenter
Jump to: navigation, search
m (Links)
m (added Category:Embedded using HotCat)
 
(12 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
{{TOCright}}
 
=const=
 
=const=
 
''const'' means  that something is not modifiable, so a data object that is declared with const as a part of its type specification must not be assigned to in any way during the run of a program.
 
''const'' means  that something is not modifiable, so a data object that is declared with const as a part of its type specification must not be assigned to in any way during the run of a program.
 
=volatile=
 
=volatile=
 
The use of ''volatile'' ensures that the compiler always carries out the memory accesses, rather than optimizing them out (for example if the access is in a loop).
 
The use of ''volatile'' ensures that the compiler always carries out the memory accesses, rather than optimizing them out (for example if the access is in a loop).
 +
=Rules of engagement=
 +
<source lang=c>
 +
int const xxx;
 +
|    |    |
 +
|    |    +-----------------> xxx is a
 +
|    +----------------------> constant
 +
+---------------------------> integer
 +
 +
int const *ptr;
 +
|    |  | |
 +
|    |  | +----------------> ptr is a
 +
|    |  +------------------> pointer to a
 +
|    +---------------------> constant
 +
+---------------------------> integer
 +
 +
int * const ptr;
 +
|  | |    |
 +
|  | |    +---------------> ptr is a
 +
|  | +---------------------> constant
 +
|  +-----------------------> pointer to an
 +
+---------------------------> integer
 +
 +
int const * const ptr;
 +
|    |  |  |    |
 +
|    |  |  |    +---------> ptr is a
 +
|    |  |  +--------------> constant
 +
|    |  +------------------> pointer to a
 +
|    +----------------------> constant
 +
+---------------------------> integer
 +
 +
int volatile * const ptr;
 +
|    |    |  |    |
 +
|    |    |  |    +------> ptr is a
 +
|    |    |  +-----------> constant
 +
|    |    +---------------> pointer to a
 +
|    +---------------------> volatile
 +
+---------------------------> integer
 +
 +
int volatile const * ptr;
 +
|    |    |    |  |
 +
|    |    |    |  +------> ptr is a
 +
|    |    |    +---------> pointer to
 +
|    |    +---------------> constant
 +
|    +---------------------> volatile
 +
+---------------------------> integer
 +
 +
 +
 +
</source>
  
 
=Memorymapped access to a register=
 
=Memorymapped access to a register=
 
==Example 1==
 
==Example 1==
In the example below the register 32 bit register located at address 0x40000 can be accessed   
+
In the example below the register 32 bit register located in memory at address 0x40000 can be accessed through the ''uartreg'' pointer. 
 +
 
 +
 
 +
In the example below '''uartreg''' is a pointer pointing to a unsigned int 0x40000. The pointer value in memory 0x40000 is a constant not what it points to in memory. Fx. a peripheral register.
 +
<source lang=c>
 +
 
 +
unsigned int volatile * const uartreg = (unsigned int *) 0x40000;
 +
*uartreg = 0x80000000; // Assign 80000000 to the 32 bit register located at memeory address 0x40000
 +
...some code...
 +
*uartreg |= 0x1 // *uartreg's contents is OR'et to 0x1. New contents = 0x80000001
 +
</source>
 +
 
 +
==Example 2==
 +
{|
 +
|
 +
|-
 +
|From the Cortex M [[STM32F107VC]]s [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf Reference manual] - See picture below - that the size of the embedded Flash can be seen in KB from the '''Flash size register''' at memory location 0x1FFFF7E0.
 +
|-
 +
|[[image:STM32flash.png|left|500px|thum|[[STM32F107VC]] Flash size register]]
 +
|-
 +
|
 +
===Method 1: Reading the Flash size register===
 +
<source lang=c>
 +
uint16_t volatile * const flashsize = (uint16_t *) 0x1ffff7e0;
 +
 
 +
printf("Flashsize: %i KB\n\r", (int) *flashsize );
 +
</source>
 +
On the [[STM32F107VC]] the output to stdout would be '''Flashsize: 256 KB'''
 +
|-
 +
|
 +
===Method 2: Reading the Flash size register===
 +
<source lang=c>
 +
#define F_SIZE ((volatile uint16_t * const) 0x1ffff7e0) // Flash Size
 +
 
 +
printf("Flashsize: %i KB\n\r", (int) *F_SIZE );
 +
</source>
 +
On the [[STM32F107VC]] the output to stdout would be '''Flashsize: 256 KB'''
 +
===Method 3: Reading the Flash size register===
 +
 
 +
Putting the pointer in the macro
 +
<source lang=c>
 +
#define F_SIZE (*(int volatile  * const) 0x1ffff7e0) // Flash Size
 +
 
 +
printf("Flashsize: %i KB\n\r", (int) F_SIZE );
 +
</source>
 +
On the [[STM32F107VC]] the output to stdout would be '''Flashsize: 256 KB'''
 +
 
 +
|-
 +
|}
 +
 
 
=Links=
 
=Links=
 
*[http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html Const and volatile]
 
*[http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html Const and volatile]
 
*[http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3750.html armcc/tcc: Placing C variables at specific addresses - memory-mapped peripherals]
 
*[http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3750.html armcc/tcc: Placing C variables at specific addresses - memory-mapped peripherals]
 
[[Category:C]][[Category:C++]]
 
[[Category:C]][[Category:C++]]
 +
[[Category:Embedded]]
 
*[http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3736.html Use of 'const' and 'volatile']
 
*[http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3736.html Use of 'const' and 'volatile']

Latest revision as of 08:03, 5 October 2016

const

const means that something is not modifiable, so a data object that is declared with const as a part of its type specification must not be assigned to in any way during the run of a program.

volatile

The use of volatile ensures that the compiler always carries out the memory accesses, rather than optimizing them out (for example if the access is in a loop).

Rules of engagement

int const xxx;
 |    |    |
 |    |    +-----------------> xxx is a
 |    +----------------------> constant
 +---------------------------> integer

int const *ptr;
 |     |  | |
 |     |  | +----------------> ptr is a
 |     |  +------------------> pointer to a
 |     +---------------------> constant
 +---------------------------> integer

int * const ptr;
 |   | |     |
 |   | |     +---------------> ptr is a
 |   | +---------------------> constant
 |   +-----------------------> pointer to an
 +---------------------------> integer

int const * const ptr;
 |    |   |   |    |
 |    |   |   |    +---------> ptr is a
 |    |   |   +--------------> constant
 |    |   +------------------> pointer to a
 |    +----------------------> constant
 +---------------------------> integer

int volatile * const ptr;
 |     |     |   |    |
 |     |     |   |    +------> ptr is a
 |     |     |   +-----------> constant
 |     |     +---------------> pointer to a
 |     +---------------------> volatile
 +---------------------------> integer

int volatile const * ptr;
 |     |     |     |  |
 |     |     |     |  +------> ptr is a
 |     |     |     +---------> pointer to
 |     |     +---------------> constant
 |     +---------------------> volatile
 +---------------------------> integer

Memorymapped access to a register

Example 1

In the example below the register 32 bit register located in memory at address 0x40000 can be accessed through the uartreg pointer.


In the example below uartreg is a pointer pointing to a unsigned int 0x40000. The pointer value in memory 0x40000 is a constant not what it points to in memory. Fx. a peripheral register.

unsigned int volatile * const uartreg = (unsigned int *) 0x40000;
*uartreg = 0x80000000; // Assign 80000000 to the 32 bit register located at memeory address 0x40000
...some code...
*uartreg |= 0x1  // *uartreg's contents is OR'et to 0x1. New contents = 0x80000001

Example 2

From the Cortex M STM32F107VCs Reference manual - See picture below - that the size of the embedded Flash can be seen in KB from the Flash size register at memory location 0x1FFFF7E0.
STM32F107VC Flash size register

Method 1: Reading the Flash size register

 uint16_t volatile * const flashsize = (uint16_t *) 0x1ffff7e0;

 printf("Flashsize: %i KB\n\r", (int) *flashsize );

On the STM32F107VC the output to stdout would be Flashsize: 256 KB

Method 2: Reading the Flash size register

#define F_SIZE	((volatile uint16_t * const) 0x1ffff7e0)		// Flash Size 

 printf("Flashsize: %i KB\n\r", (int) *F_SIZE );

On the STM32F107VC the output to stdout would be Flashsize: 256 KB

Method 3: Reading the Flash size register

Putting the pointer in the macro

#define F_SIZE	(*(int volatile  * const) 0x1ffff7e0)		// Flash Size 

 printf("Flashsize: %i KB\n\r", (int) F_SIZE );

On the STM32F107VC the output to stdout would be Flashsize: 256 KB

Links