【问题标题】:Passing volatile variable as constant argument in a function在函数中将 volatile 变量作为常量参数传递
【发布时间】:2016-09-19 12:33:10
【问题描述】:

我正在为 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 对比?

【问题讨论】:

  • volatile 在您的情况下是强制性的:它告诉编译器不对访问此变量执行任何优化(您需要它,因为您在正常模式和中断模式下访问它)。我认为,最好的方法是将您的 volatile 缓冲区本地复制到标准缓冲区,并使用标准
  • @Garf365:有什么建议可以准确地如何以保存方式执行“复制”?
  • 不清楚您是否需要volatile,仅仅因为您在中断处理程序中使用该变量并不意味着它必须是volatile。请提供带有所有相关信息的minimal reproducible example(它不需要是可运行的,但应该代表该变量的所有用途。您还应该首先了解限定符volatile和const的含义一个变量和一个函数参数声明。您的问题表明缺乏知识 - 没有冒犯。
  • 我将字符从一个主数组存储到另一个数组以进行一些数学计算,确切地说,我在从设备获取的时间添加了一个常量偏移量,所以我需要提取代表小时的字符(存储在此变量中),以便将其转换为分钟。分钟被单独提取和转换并添加到此,然后是 5 小时偏移量的常量。 (那里没有更多的卡路里)。

标签: c arm embedded


【解决方案1】:

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

【讨论】:

  • 问题是,在哪里使用atoi。演员阵容可能非常错误。
  • 最后一个想法是有问题的,因为空字符可能会消失(字符串在atoi() 中间变短了)。 memcpy() 的想法很好,但建议改进 SAVE_ENABLE(); CLI(); memcpy(); RESTORE_ENABLE(); 以处理重入。
  • @chux:很好的解决方案!我懒得查找正确的宏。谢谢。
  • @chqrlie SAVE_ENABLE(); CLI(); RESTORE_ENABLE(); 只是用于表达概念功能的占位符名称。不确定适用于 ARM 的内容。抱歉,如果不清楚。
  • 一个更脏(但理论上更健壮)的技巧涉及union {uint32_t, char[3]} 和架构保证的对齐 32 位负载的固有原子性...
猜你喜欢
  • 2011-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多