Microcontroller Embedded C Programming Lecture 143: Usage of const and volatile together

  • Post author:
  • Post category:Blog

 

Usage of ‘const’ and ‘volatile’ together

 

Usage of ‘const‘ and ‘volatile‘ together 

  • You can also use both ‘const’ and ‘volatile’ qualifiers in a variable declaration as per your goal.

Some people think that ‘const’ is the opposite of ‘volatile’. There is nothing like that. So, ‘const’ and ‘volatile’ are entirely different. Don’t try to compare them. If you think const is the opposite of volatile, then it is wrong. So, you should not assume like that. Both are entirely different type qualifiers.

 

Example

uint8_t volatile *const pReg = (uint8_t*)0x40000000; 

This is a case of constant pointer and volatile data.

How do you read this?

pReg is a const pointer pointing to volatile data of type uint8.

Here ‘const’ is used with a pointer, just to guard a pReg pointer from unexpected changes from the programmer. This is just a case of defensive programming here, so, where we are guarding pReg is using const.

And we are telling the compiler that, the data present at 0x40000000(this address) may undergo unexpected changes, so not to optimize any read and write operations on this pointer by using volatile.

 

Consider the below statement. 

uint8_t const volatile *const pReg = (uint8_t*)0x40000000; 

How do you read this? 

pReg is a const pointer pointing to volatile const data of type uint8. 

Here, volatile const may be confusing.

The meaning of const volatile is, the data pointed by this address(0x40000000)is volatile. That is, it is subjected to unexpected changes, but the programmer must not change the data present at this address(0x40000000). That’s the meaning of const volatile.

Here ‘const’ is for the programmer not to change the value present at 0x40000000 this address. And volatile is for the compiler not to optimize the read and write operation on that address. 

 

Let’s understand the case of reading from a read-only buffer or address which is prone to unexpected change.

Figure 1. Case of reading from read-only address which is prone to unexpected change
Figure 1. Case of reading from read-only address which is prone to unexpected change

If you are reading from a read-only buffer or address like in the case of an input data register, so the input data register is read-only, you should only read from that, you should not modify that. 

So, in that case, you can use the below statement.

uint8_t const volatile *const pReg = (uint8_t*) 0x40000000; 

In this statement, the data at this address location(0x40000000) should not be modified by the programmer, because it is const. But the data at this address may get changed by the data coming from the external world. The data may come into the input data register, let’s say from an external world like from the protocols, or the network, or the user pressing the button, etc. So, the address can still undergo unexpected change, but the programmer should not modify it. In that case, you can use const volatile.

I hope you understood about using ‘const’ and ‘volatile’ together. 

 

In the pin_read example, let’s see whether we can use const volatile together here.

It is not actually required, but still, if you want to guard those pointers, then you can convert that into const pointers here. So, you can convert all these into const pointers. And after that, pPortInReg is actually a Port A input data register, and for the input data register programmer should not write anything. That’s why you can even make this const volatile. So, that’s the only change I would like to make.

int main(void)
{
uint32_t volatile *const pClkCtrlReg       = (uint32_t*)0x40023830;
uint32_t volatile *const pPortDModeReg     = (uint32_t*)0x40020C00;
uint32_t volatile *const pPortDOutReg      = (uint32_t*)0x40020C14;
uint32_t volatile *const pPortAModeReg     = (uint32_t*)0x40020000;
uint32_t const volatile *const pPortAInReg = (uint32_t*)0x40020010;

 

That’s how you can use const and volatile together. 

But you cannot make those statements as const, as shown in Figure 2. That is wrong.

If you do this, what happens? The compiler will throw some errors. You are trying to change the read-only location, so you cannot do this. 

  • Use const volatile only for read-only memory addresses. 
Usage of const and volatile
Figure 2. Exercise

 

FastBit Embedded Brain Academy Courses

Click here: https://fastbitlab.com/course1

 

FastBitLab

The FastBit Embedded Brain Academy uses the power of internet to bring the online courses related to the field of embedded system programming, Real time operating system, Embedded Linux systems, etc at your finger tip with very low cost. Backed with strong experience of industry, we have produced lots of courses with the customer enrolment over 3000+ across 100+ countries.