Type qualifiers
According to the C standard, volatile and const are type qualifiers.
Declaring objects volatile
By declaring an object volatile, the compiler is informed that the value of the object can change beyond the compiler’s control. The compiler must also assume that any accesses can have side effects—therefore all accesses to the volatile object must be preserved.
There are three main reasons for declaring an object volatile:
Shared access—the object is shared between several tasks in a multitasking environment
Trigger access—as for a memory-mapped SFR where the fact that an access occurs has an effect
Modified access—where the contents of the object can change in ways not known to the compiler.
Definition of access to volatile objects
The C standard defines an abstract machine, which governs the behavior of accesses to volatile declared objects. In general and in accordance to the abstract machine:
The compiler considers each read and write access to an object declared
volatileas an accessThe unit for the access is either the entire object or, for accesses to an element in a composite object—such as an array, struct, class, or union—the element. For example:
char volatile a; a = 5; /* A write access */ a += 6; /* First a read then a write access */
An access to a bitfield is treated as an access to the underlying type
Adding a
constqualifier to avolatileobject will make write accesses to the object impossible. However, the object will be placed in RAM as specified by the C standard.
However, these rules are not detailed enough to handle the hardware-related requirements. The rules specific to the IAR C/C++ Compiler for RISC-V are described below.
Rules for accesses
In the IAR C/C++ Compiler for RISC-V, accesses to volatile declared objects are always preserved. In addition, for accesses to all 8-, 16-, and 32-bit (and 64-bit on RV64) scalar types, except for accesses to unaligned 16- and 32-bit fields in packed structures:
All accesses are complete, that is, the whole object is accessed
All accesses are performed in the same order as given in the abstract machine
All accesses are atomic, that is, they cannot be interrupted.
Declaring objects volatile and const
If you declare a volatile object const, it will be write-protected but it will still be stored in RAM memory as the C standard specifies.
To store the object in read-only memory instead, but still make it possible to access it as a const volatile object, declare it with the __ro_placement attribute. See __ro_placement.
Declaring objects const
The const type qualifier is used for indicating that a data object, accessed directly or via a pointer, is non-writable. A pointer to const declared data can point to both constant and non-constant objects. It is good programming practice to use const declared pointers whenever possible because this improves the compiler’s possibilities to optimize the generated code and reduces the risk of application failure due to erroneously modified data.
Static and global objects declared constare allocated in ROM.
In C++, objects that require runtime initialization cannot be placed in ROM.