可以参考下面的code拿到cpu的电压和频率
static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device,u32 capacitance)
{struct power_table *power_table;struct dev_pm_opp *opp;struct device *dev = NULL;int num_opps = 0, cpu, i, ret = 0;unsigned long freq;for_each_cpu(cpu, &cpufreq_device->allowed_cpus) {
//在kernel中每个cpu 对应一个device,这里就得到代表当前cpu的devicedev = get_cpu_device(cpu);if (!dev) {dev_warn(&cpufreq_device->cool_dev->device,"No cpu device for cpu %d\n", cpu);continue;}
//电压和频率等的值都存在struct dev_pm_opp *opp; 中,所以这里得到有几组opps.num_opps = dev_pm_opp_get_opp_count(dev);if (num_opps > 0)break;else if (num_opps < 0)return num_opps;}if (num_opps == 0)return -EINVAL;power_table = kcalloc(num_opps, sizeof(*power_table), GFP_KERNEL);if (!power_table)return -ENOMEM;
//通过dev_pm_opp_find_freq_ceil来得到频率for (freq = 0, i = 0;opp = dev_pm_opp_find_freq_ceil(dev, &freq), !IS_ERR(opp);freq++, i++) {u32 freq_mhz, voltage_mv;u64 power;if (i >= num_opps) {ret = -EAGAIN;goto free_power_table;}
//频率是MHZ,所以这里要除以1000000freq_mhz = freq / 1000000;
//通过dev_pm_opp_get_voltage得到电压voltage_mv = dev_pm_opp_get_voltage(opp) / 1000;dev_pm_opp_put(opp);/** Do the multiplication with MHz and millivolt so as* to not overflow.*/
//计算cpu的功率,等于电压×电流×时间power = (u64)capacitance * freq_mhz * voltage_mv * voltage_mv;do_div(power, 1000000000);/* frequency is stored in power_table in KHz */power_table[i].frequency = freq / 1000;/* power is stored in mW */power_table[i].power = power;}}
我们继续看看dev_pm_opp_find_freq_ceil(dev, &freq)是如何得到频率的
struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev,unsigned long *freq)
{struct opp_table *opp_table;struct dev_pm_opp *opp;if (!dev || !freq) {dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq);return ERR_PTR(-EINVAL);}
//找到对应的opp_table.然后从opp_table 中得到频率opp_table = _find_opp_table(dev);if (IS_ERR(opp_table))return ERR_CAST(opp_table);opp = _find_freq_ceil(opp_table, freq);dev_pm_opp_put_opp_table(opp_table);return opp;
}
_find_opp_table->_find_opp_table_unlocked->_find_opp_dev
static struct opp_device *_find_opp_dev(const struct device *dev,struct opp_table *opp_table)
{struct opp_device *opp_dev;list_for_each_entry(opp_dev, &opp_table->dev_list, node)if (opp_dev->dev == dev)return opp_dev;return NULL;
}
这里可以知道所以的opp_tables 都是放在opp_tables 这个全局变量中,然后看opp_tables中device和代表当前cpu的device是否相等
回到dev_pm_opp_find_freq_ceil 中继续看看_find_freq_ceil如何从opp_table 中得到频率
static noinline struct dev_pm_opp *_find_freq_ceil(struct opp_table *opp_table,unsigned long *freq)
{struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE);mutex_lock(&opp_table->lock);list_for_each_entry(temp_opp, &opp_table->opp_list, node) {
//这里就得到频率的,判断标准就是下面这个ifif (temp_opp->available && temp_opp->rate >= *freq) {opp = temp_opp;*freq = opp->rate;/* Increment the reference count of OPP */dev_pm_opp_get(opp);break;}}mutex_unlock(&opp_table->lock);return opp;
}回到build_dyn_power_table 中由于opp = dev_pm_opp_find_freq_ceil(dev, &freq) 已经返回了opp_table.因此电压就很容易得到
unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp)
{if (IS_ERR_OR_NULL(opp)) {pr_err("%s: Invalid parameters\n", __func__);return 0;}return opp->supplies[0].u_volt;
}
除了电压频率,从opp_table 中还可以得到下面的值
unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev);
unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev);
unsigned long dev_pm_opp_get_max_transition_latency(struct device *dev);
unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev);
这些接口都定义在drivers/base/power/opp/pm_opp.h

如何在kernel中得到cpu的电压和频率相关推荐

  1. linux查看设备在哪个cpu上,如何在linux中查看cpu信息、机器硬件型号

    原标题:如何在linux中查看cpu信息.机器硬件型号 # cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c 8 Intel(R) Xeon( ...

  2. linux查看cpu缓存大小,如何在Linux中获取CPU Cache的大小

    对于运行Linux的ARM CPU(在具有Raspbian(32位)的Raspberry Pi 3B +上测试): "Arm®Cortex®-A53MPCore处理器技术参考手册" ...

  3. 如何在 .NET Core 中获取 CPU 使用率

    这篇文章我们分享一种如何在 .NETCore 中获取 CPU使用率的方法, 它所报告的这个值和 任务管理器 中报告的 CPU 使用值 差不多是一致的. 在 .NET Framework 中,很多人会用 ...

  4. 如何更改计算机睿频,bios中关闭cpu睿频实用方法介绍

    有网友问小编关于bios中关闭cpu睿频的方法,其实cpu是一块超大规模的集成电路,是一台计算机的运算核心(Core)和控制核心( Control Unit).它的功能主要是解释计算机指令以及处理计算 ...

  5. Android 驱动(17)---如何在linux中添加新的kernel module

    如何在linux中添加新的kernel module 该SOP针对客户如何添加一个kernel module,并把生成的.ko打包进system.img的过程. 解决方案 L版本(version> ...

  6. 如何在Python中获得当前的CPU和RAM使用率?

    本文翻译自:How to get current CPU and RAM usage in Python? What's your preferred way of getting current s ...

  7. 如何在MFC中调用CUDA

    如何在MFC中调用CUDA 有时候,我们需要在比较大的项目中调用CUDA,这就涉及到MFC+CUDA的环境配置问题,以矩阵相乘为例,在MFC中调用CUDA程序.我们参考罗振东iylzd@163.com ...

  8. s-tui:在 Linux 中监控 CPU 温度、频率、功率和使用率的终端工具

    一般每个 Linux 管理员都会使用 lm_sensors 监控 CPU 温度.lm_sensors (Linux 监控传感器)是一个自由开源程序,它提供了监控温度.电压和风扇的驱动和工具. 如果你正 ...

  9. 通过mtd读写flash_关于如何在kernel起来之后通过直接dd读写nand flash分区来更新zImage的mtd问题...

    关于如何在kernel起来之后通过直接dd读写nand flash分区来更新zImage的mtd问题 主要是设置struct mtd_partition中的mask_flags标志位 具体含义为: 1 ...

最新文章

  1. mysql利用存储过程批量插入数据
  2. 搭建WEB服务详解(二)
  3. 在Servlet中处理表单提交的数据
  4. 【中级软考】RSA、IDEA、RC4、MD5算法分别是什么?
  5. 2021中国垂类电竞KOL发展洞察行业报告
  6. linux更新驱动脚本,Linux 第一个驱动程序编写
  7. [深度学习]Python/Theano实现逻辑回归网络的代码分析
  8. cf D. Dima and Hares
  9. cocos2d for android,cocos2d jsb 打包 Android APK
  10. 6to4隧道实验(华为设备)
  11. HDU 3709 Balanced Number 枚举+数位DP
  12. Delphi基础教程第一季
  13. 信息收集--OSINT
  14. XSS、CSRF攻击以及预防手段
  15. 12-1 蓝色天空 : 创建一个背景为蓝色的Pygame窗口 12-2 游戏角色 : 找一幅你喜欢的游戏角色位图图像或将一幅图像转换为位图。 创建一个类, 将该角色绘制到屏幕中央, 并将该图像的背景色
  16. 关于用盐去黑头的亲身经历~ - 生活至上,美容至尚!
  17. 昨天玩游戏的情绪总结
  18. Realtek WiFi定频工具使用操作指南(rtl8188au/rtl8812au/rtl8192cu)
  19. Git实战技巧-比较不同分支之间的差异和代码的改动
  20. html5新特性与用法大全了解一下

热门文章

  1. 九宫幻方(C语言代码)
  2. VS2015常用快捷键
  3. 零基础学javaDay04
  4. 我们失去了,我们又没有失去什么
  5. linux删除文件的几种方法【转自微信公众号入门小站】
  6. c语言坐标画直线函数,三、Windows图像处理—画点和线(直线)
  7. source insight 常规配置以及背景配色
  8. Linux学习——进程间通信
  9. java入门-W3(K81-K143)
  10. QCY蓝牙耳机恢复双耳模式