I'm developing and Embedded code for a Cortex-M0 MC where I declare a variable as volatile char TOS_Mins_Char[3];
to store some values during an ISR which would be periodically changed.
I want to convert these characters to an integer using the atoi()
function,
but atoi()
has its argument type as pointer to a constant string: int atoi(const char *);
This give me error unless I avoid the volatile
keyword in the variable declaration. (Faced similar situation in other std functions also)
const char TOS_Mins_Char[3];
, will it be a problem?volatile
keyword, what is its use in
contrast to an ARM MC ?Yes a C++ variable be both const and volatile. It is used in situations like a read-only hardware register, or an output of another thread. Volatile means it may be changed by something external to the current thread and Const means that you do not write to it (in that program that is using the const declaration).
Another use for a combination of const and volatile is where you have two or more processors communicating via a shared memory area and you're coding the side of this communications that will only be reading from a shared memory buffer.
Yes, a pointer can be volatile if the variable that it points to can change unexpectedly even though how this might happen is not evident from the code.
Volatile is a qualifier that is applied to a variable when it is declared. It tells the compiler that the value of the variable may change at any time-without any action being taken by the code the compiler finds nearby.
The volatile
keyword is necessary to tell the compiler to reload the characters from memory for each access.
If you know the array will not be modified during the conversion, you can use a cast to silence the warning:
int value = atoi((const char*)TOS_Mins_Char);
Note that the value returned by atoi()
might be completely bogus if the interrupt routine modifies the array in the middle of the conversion. You can prevent this by disabling the interrupts around accesses to the array. To minimize the duration of processing with disabled interrupts, you might want to copy the array to a local array this way:
char buf[sizeof TOS_Mins_Char];
CLI; // whatever macro use to disable interrupts
memcpy(buf, TOS_Mins_Char, sizeof TOS_Mins_Char);
STI; // enable interrupts
int value = atoi(buf);
The problem with this approach is the non reentrency of the interrupt disable/enable mechanism: if interrupts are already disabled when entering the code, they will be enabled upon leaving, which is probably not intended and a likely cause of bugs in the calling code.
Another quick and dirty trick can be used to lower the likelihood of an interrupt clash:
int value, last = atoi((const char*)TOS_Mins_Char);
while ((value = atoi((const char*)TOS_Mins_Char)) != last) {
last = value;
}
If the buffer was modified by the ISR during the conversion, the next conversion would produce a different result. The is a remove possibility that the next conversion also be interrupted by the ISR, but in a non life critical system, you might want to ignore this possibility.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With