我正在为Cortex-M0 MC开发和嵌入代码,其中我声明了一个变量,volatile char TOS_Mins_Char[3];
以便在ISR期间存储一些值,这些值会定期更改.我想使用atoi()函数将这些字符转换为整数,但atoi()将其参数类型作为指向常量字符串的指针:int atoi(const char *);除非我volatile在变量声明中避免使用关键字,否则这会给出错误.(在其他std函数中也面临类似的情况)
const char TOS_Mins_Char[3];,它会有问题吗?volatile关键字,与ARM MC相比,它的用途是什么?volatile必须使用关键字来告诉编译器为每次访问从内存中重新加载字符。
如果您知道在转换过程中不会修改数组,则可以使用强制转换来消除警告:
int value = atoi((const char*)TOS_Mins_Char);
Run Code Online (Sandbox Code Playgroud)
请注意,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);
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是中断禁用/启用机制的不可重入性:如果在输入代码时中断已经被禁用,它们将在离开时启用,这可能不是故意的,并且可能是调用代码中错误的原因。
另一个快速而肮脏的技巧可用于降低中断冲突的可能性:
int value, last = atoi((const char*)TOS_Mins_Char);
while ((value = atoi((const char*)TOS_Mins_Char)) != last) {
last = value;
}
Run Code Online (Sandbox Code Playgroud)
如果在转换期间 ISR 修改了缓冲区,则下一次转换将产生不同的结果。下一次转换也有可能被 ISR 中断,但在非生命攸关的系统中,您可能希望忽略这种可能性。