我正在为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
关键字,它在
与手臂的mc形成对比?
最佳答案
必须使用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中断,但在非生命关键型系统中,您可能希望忽略这种可能性。
关于c - 将volatile变量作为函数中的常量参数传递,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39573299/