在函数中将volatile变量作为常量参数传递

问题描述:

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

  1. 是否有比写一本用户以外的任何解决方案定义 功能?
  2. 如果我用const char TOS_Mins_Char[3];,会不会是一个问题?
  3. 是否必须使用volatile关键字,与ARM MC对比 有何用处?
+0

'volatile'在你的情况下是强制性的:它告诉编译器不对访问这个变量进行优化(你需要它,因为你在正常模式和中断模式下访问它)。我认为,最好的办法是将你的易失性缓冲区本地复制到一个标准的缓冲区,并使用标准的 – Garf365

+0

@ Garf365:任何提议准确*如何*以保存方式执行“复制”? – alk

+0

仅仅因为您在中断处理程序中使用变量并不意味着它必须是volatile,您是否需要'volatile'还不清楚。请为[mcve]提供**所有**相关信息(它不必是可运行的,但应代表该变量的所有用途。您还应首先了解变量的volatile和const限定符的含义,以及一个函数参数声明。你的问题表明缺乏知识 - 没有冒犯。 – Olaf

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); 

这种方法的问题是中断禁止的非reentrency /使能机制:如果中断在输入代码时已被禁用,它们将在离开时启用,这可能不是有意的,并且可能是调用代码中的错误的原因。

另一个快速和肮脏的特技可以用来降低一个中断冲突的可能性:

int value, last = atoi((const char*)TOS_Mins_Char); 
while ((value = atoi((const char*)TOS_Mins_Char)) != last) { 
    last = value; 
} 

如果将缓冲液通过ISR中的转换期间被修改,下一次转换会产生不同的结果。下一次转换可能会被ISR中断,但在非生命关键系统中,您可能会忽略这种可能性。

+0

问题是,在哪里使用'atoi'。演员阵容可能非常错误。 – Olaf

+2

最后的想法是有问题的,因为空字符可能会消失(在'atoi()'中间字符串变得更短)。 'memcpy()'主意不错,但建议改进'SAVE_ENABLE(); CLI();的memcpy(); RESTORE_ENABLE();'来处理重新加入。 – chux

+0

@chux:很好的解决方案!我懒得查找适当的宏。谢谢。 – chqrlie