在函数中传递易失性变量作为常量参数



我正在为Cortex-M0 MC开发和嵌入代码,其中我将变量声明为volatile char TOS_Mins_Char[3];在ISR期间存储一些值,这些值将定期更改。我想用atoi()函数把这些字符转换成整数,但atoi()有它的参数类型作为一个常量字符串的指针:int atoi(const char *);这给我的错误,除非我避免在变量声明中的volatile关键字。(在其他std函数中也面临类似的情况)

  1. 除了编写用户定义的,还有其他解决方案吗函数?
  2. 如果我使用const char TOS_Mins_Char[3];,会有问题吗?
  3. 是否强制使用volatile关键字,它的用途是什么与ARM 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中断,但在非生命临界系统中,您可能希望忽略这种可能性。

最新更新