Volatile. A little knowledge is dangerous

Status
Not open for further replies.

drjohnsmith

Well-known member
Have some code on teensy 3.2, duino 1.81

From what I am seeing with a scope
the first time I call this it works,
the second time, it seems to be totally ignoring the pin,

probably my code, but it struck a thought..


In my old C days, we had to define input pins as volatile,
but in arduino world we dont seem to ,

Is this taken care of when we declare a pin mode as digital input ?

For reference , SPI1_nRDY is a copy of the SPI MISO pin, wired onto teensy 3.2 pin D8 , its not the SPI pin itself.




uint8_t WaitRdyGoLow(void)
{

for ( uint8_t i = 0 ; i < 1000; i++ )
{
delay ( 1 );
if ( digitalRead( SPI1_nRDY ) == 0 )
{
Serial.println("!");
return( 0);
}
}
Serial.println (" Wait time out error" );
return( 1 ); // loop timed out , so return error

}//WaitRdyGoLow
 
For info, found my code / board bug,

But would still like to know about volatile , and why we don't need it in arduino world.
 
uint8_t < 1000 ?????
You have invented the 10 bits byte.

By the way, for instance you may need volatile if you update one variable in a ISR routine and use it outside the ISR.
 
Last edited:
For info, found my code / board bug,

But would still like to know about volatile , and why we don't need it in arduino world.

Volatile is a C/C++ keyword that says the compiler must assume that the variable is modified in ways the compiler does not know about. For example, the classic case being set in an interrupt service handler. The AVR is a much simpler 8-bit microprocessor, and so there are less places where the compiler might remember things in a register.

For example in this code, without using volatile, the compiler will likely move the value to a register to do the test to save time from reloading it from memory (which is much slower that referring to a register):

Code:
int x;

void endless (void)
{
  while (x != 0) {
    // do something
  }
}
 
thanks

yep got the unit_8 thing ,
still amazes me that the system does not chuck that sort of thing out as an error,
I come from the world of ADA etc, where that sort of stupid mistake would be found,

BUt

thats not the question,

its re volatile.

Digital inputs dont need to be described as volatile,
I guess thats handled by the magic of digitalRead , but was wondering how / where or was it some other magic in duino world.

Thanks for reminder re an ISR, and volatile, yes two bits of code that can modify a variable would need volatile ,
would the ISR pin need to be volatile though , or is that implicit some where,
 
Volatile is a C/C++ keyword that says the compiler must assume that the variable is modified in ways the compiler does not know about. For example, the classic case being set in an interrupt service handler. The AVR is a much simpler 8-bit microprocessor, and so there are less places where the compiler might remember things in a register.

For example in this code, without using volatile, the compiler will likely move the value to a register to do the test to save time from reloading it from memory (which is much slower that referring to a register):

Code:
int x;

void endless (void)
{
  while (x != 0) {
    // do something
  }
}

thank you MM
 
All hardware-registers are already volatile in the core. digitalRead is a function that reads that register.
 
All hardware-registers are already volatile in the core. digitalRead is a function that reads that register.

Unless you use LTO, digitalRead is a function not defined in the current file scope, so the compiler has to treat any global variable as being modified after the call. If you had declared the variable static and had the interrupt handler in the same scope, the compiler may optimize this without using the volatile keyword.

If you use digitalReadFast with a constant pin number, the header files will convert this to an inline function that twiddles the appropriate registers. Those should be declared volatile.
 
Unless you use LTO, digitalRead is a function not defined in the current file scope, so the compiler has to treat any global variable as being modified after the call. If you had declared the variable static and had the interrupt handler in the same scope, the compiler may optimize this without using the volatile keyword.

If you use digitalReadFast with a constant pin number, the header files will convert this to an inline function that twiddles the appropriate registers. Those should be declared volatile.
Maybe this tidbit should be mentioned in this thread also: https://forum.pjrc.com/threads/41568-Teensyduino-1-36-Beta-1-(ARM-Toolchain-Update)
 
Digital inputs dont need to be described as volatile,
I guess thats handled by the magic of digitalRead , but was wondering how / where or was it some other magic in duino world.

Indeed volatile is used by the register defs used inside digitalRead. There really isn't other magic going on. DigitalRead just accesses the hardware, and of course the hardware registers are defined with volatile. Look in kinetis.h for their defs.

But the pin number you give to digitalRead isn't supposed to be volatile. That makes no sense at all. It's just the number you typed, which never changes throughout the runtime of the program.

In terms of "other magic going on", there *is* another minor detail for digitalWrite for atomic bit changes. The hardware has 2 ways to do this. There are registers for setting and clearing bits, where writing zeros does nothing. The ARM Cortex-M4 also has a special bitband addressing mode. Both are used in different scenarios, to protect against the case where the main program and an interrupt both try to write different bits in the same register and the same time. But this doesn't apply to digitalRead.
 
Status
Not open for further replies.
Back
Top