【问题标题】:handle float value in device driver在设备驱动程序中处理浮点值
【发布时间】:2021-09-25 00:18:27
【问题描述】:

我正在编写 sysfs 相关的 Linux 设备驱动程序代码。 我对如何处理变量的浮动操作感到困惑。 是否有任何函数可用于处理浮点操作或者任何人都知道在 Linux 内核设备驱动程序中处理浮点操作的最佳方法?

我正在编写一个功率/电流/电压测量驱动程序,它在 sysfs 文件中提供输出。

代码:

  volts /= 27500.0;
  volts *= 250;
  volts /= 1000;

有这样的操作我想在内核部分处理,浮点值应该是准确的。

【问题讨论】:

  • 询问“最好的方法”将导致基于意见的答案,这将是题外话。此外,术语“处理浮点值”或“处理浮点操作”过于宽泛。您应该edit您的问题并添加有关您的特定问题的详细信息。你到底想用浮点值做什么?您指的是什么浮动操作?您具体需要哪些帮助?在设备驱动程序中添加一些你(认为你)为什么需要浮点值的背景信息也可能有助于理解你的问题。
  • 您的示例应该可以通过定点数学轻松实现。即使是 32 位值 (16.16) 也应该为您提供足够的精度来涵盖 mV 到 kV。但我猜你是在 64 位平台上工作,所以甚至加倍。
  • millivolts = volts / 110; 代替volts /= 27500.0; volts *= 250; volts /= 1000;(因为250/275000 = 1/110)然后scnprintf(buf, PAGE_SIZE, "%d.%03u", millivolts/1000, (millivolts < 0 ? (unsigned int)(-millivolts) : (unsigned int)(millivolts)) % 1000);。如果volts 永远不会是负数,那么scnprintf(buf, PAGE_SIZE, "%u.%03u", millivolts/1000, millivolts%1000); 就可以了。 (这里假设buf 是一个页面,像往常一样具有 sysfs 属性。)

标签: c linux kernel driver


【解决方案1】:

最好的办法:根本不要这样做。

几乎没有任何可以想象的原因为什么 FP 操作应该发生在内核驱动程序中。它们成本高昂,本质上不可移植到进行 FP 仿真的平台上,并且在做错时很危险(您必然会破坏完全不相关的用户任务的 FPU 上下文)。如果可以的话,尝试用定点数学代替,或者完全避免在内核中使用复杂的数学并从用户空间进行。

如果你认为你绝对必须在内核函数中使用 FP,你可能想看看 kernel_fpu_begin()kernel_fpu_end() 函数 (*),它们保存和恢复 FPU 上下文你。但是,根据平台的不同,这些可能会很昂贵,并且可能的代码路径存在某些限制(无嵌套,...)。当(仅)生成文本输出(如 sysfs)时,您只需要知道在哪里放置小数点,这可以说是太昂贵了。

(*) 据我所知,这些仅在基于 x86 的平台上可用,因此您无助于驱动程序的可移植性。

【讨论】:

  • 我只需要在内核中进行。 Reson 在进行了一些除法和乘法相关的操作后,我必须更新到 sysfs 中。
  • 如果您进行简单的除法和乘法运算,只需将 FP 运算替换为定点整数数学即可。
  • 这是个好主意,我只是这么想。但是有没有其他方法或库函数可用于执行操作?
  • @chaitanyasonagara 您应该将所有信息添加到问题中,而不是为此使用 cmets。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-13
  • 2013-10-29
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 2023-03-28
  • 1970-01-01
相关资源
最近更新 更多