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

时间:2016-09-19 12:33:11

标签: c arm embedded

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

  1. 除了编写用户定义之外,还有其他方法吗? 功能?
  2. 如果我使用const char TOS_Mins_Char[3];,会不会有问题?
  3. 是否必须使用volatile关键字,它的用途是什么 与ARM MC形成对比?

1 个答案:

答案 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中断,但在非生命关键系统中,您可能希望忽略这种可能性。