我正在为Cortex-M0 MC开发和嵌入代码,我将变量声明为volatile char TOS_Mins_Char[3];
在ISR期间存储一些值,这些值会定期更改。
我想使用atoi()
函数将这些字符转换为整数,
但是atoi()
将其参数类型作为指向常量字符串的指针:int atoi(const char *);
除非我避免变量声明中的volatile
关键字,否则这会给我错误。 (在其他标准函数中也面临类似的情况)
const char TOS_Mins_Char[3];
,会不会有问题?volatile
关键字,它的用途是什么
与ARM MC形成对比?答案 0 :(得分:4)
必须使用volatile
关键字告诉编译器为每次访问重新加载内存中的字符。
如果您知道在转换过程中不会修改数组,您可以使用强制转换来使警告静音:
int value = atoi((const char*)TOS_Mins_Char);
请注意,如果中断例程在转换过程中修改数组,atoi()
返回的值可能完全是假的。您可以通过禁用对阵列的访问中断来防止这种情况。要最小化使用禁用中断的处理持续时间,您可能希望以这种方式将阵列复制到本地阵列:
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);
这种方法的问题在于中断禁用/启用机制的非重复性:如果在输入代码时已经禁用了中断,它们将在离开时启用,这可能不是预期的,并且可能是导致错误的原因。调用代码。
另一个快速而肮脏的技巧可用于降低中断冲突的可能性:
int value, last = atoi((const char*)TOS_Mins_Char);
while ((value = atoi((const char*)TOS_Mins_Char)) != last) {
last = value;
}
如果在转换过程中ISR修改了缓冲区,则下一次转换会产生不同的结果。下一次转换也可能被ISR中断,但在非生命关键系统中,您可能希望忽略这种可能性。