hisi3516dv300芯片基于hwmon驱动框架的温度获取驱动源码分析

2023-11-01

1、内核hwmon驱动框架

参考博客:《内核hwmon驱动框架详解以及海思芯片温度驱动分析》

2、驱动实现的效果

/sys/devices/virtual/hwmon/hwmon0 # pwd
/sys/class/hwmon/hwmon0
/sys/devices/virtual/hwmon/hwmon0 # ls
power        subsystem    temp1_input  uevent
/sys/devices/virtual/hwmon/hwmon0 # cat temp1_input 
41
/sys/devices/virtual/hwmon/hwmon0 # 

(1)在sysfs中可以看到/sys/class/hwmon/hwmon0文件夹,里面有temp1_input文件;
(2)读取temp1_input文件,里面是芯片的温度值;
(3)文件夹名字不一定是hwmon0,如果你注册了不止一个hwmon设备,文件夹名字有可能是hwmon0或者hwmon1,看你注册hwmon设备的先后顺序;

3、获取芯片温度驱动的思路分析

(1)向内核hwmon驱动框架注册我们的驱动,在hwmon类下面创建相应的设备;
(2)填充创建的hwmon类设备的设备属性,创建保存温度值的文件,指定文件的show方法;
(3)对海思芯片温度传感器相关的寄存器进行动态映射;
(4)初始化海思芯片温度相关的寄存器,包括设置温度检测模式为循环模式、循环检测周期、使能等;
(5)应用通过读取temp1_input文件获取温度,实际就是执行temp1_input文件的show方法;
(6)在show方法中,读取温度记录值寄存器的值,计算出温度值并返回;

4、芯片自带的温度传感器

地址偏移量 寄存器编号 寄存器名字
0x00B4 MISC_CTRL45 Tsensor控制寄存器
0x00B8 MISC_CTRL46 Tsensor 状态寄存器
0x00BC MISC_CTRL47 Tsensor 温度记录值寄存器 0
0x00C0 MISC_CTRL48 Tsensor 温度记录值寄存器 1
0x00C4 MISC_CTRL49 Tsensor 温度记录值寄存器 2
0x00C8 MISC_CTRL50 Tsensor 温度记录值寄存器 3

5、寄存器功能描述

5.1、Tsensor控制寄存器

在这里插入图片描述

(1)温度检测模式:一般选择循环检测模式,不停的去检测温度;
(2)循环检测周期:当设置为循环检测模式时要设置,就是每隔多长时间去检测一次温度,注意单位是2ms;
(3)温度上/下溢值:往寄存器写入值,表示芯片温度超过这个值时会触发Tsensor 状态寄存器的温度上/下溢报警位。这几个寄存器的位不是直接写温度值,有换算关系,hisi3516dv300的数据手册没有明确写出,但是按照海思其他芯片推测,应该是(tsensor_uplimit -136)/793*165-40

5.2、Tsensor 状态寄存器

在这里插入图片描述

(1)如果在Tsensor控制寄存器寄存器中设置了温度上/下溢值,则需要检测温度下溢告警位;
(2)其他的位不用也没什么影响,不设置也是可以正常工作;

5.3、Tsensor温度记录值寄存器

在这里插入图片描述

(1)总共有4个温度记录值寄存器,每个寄存器的bit位含义都是一样的;
(2)每个温度记录值寄存器都保存了两个温度值,分别保存在[9:0]和[25:16]bit位;
(3)Soc在4个温度记录值寄存器中保存了8个温度值,我们需要读出8个温度值来计算一个平均的温度值;
(4)温度计算公式:Temprature=(tsensor_result[0:1] -136)/793*165-40(单位:度);

6、芯片内部温度检测流程

步骤 1:设置 T-Sensor 采集模式 MISC_CTRL45[30]。
步骤 2:如果设置为循环采集模式,需设置循环采集周期 MISC_CTRL45[27:20];如果设置为单次采集模式,可略过此步骤。循环采集周期计算公式为: T = N × 2(ms),其中 N=MISC_CTRL45[27:20]。
步骤 3:使能 T-Sensor MISC_CTRL45[31],开始温度采集
步骤 4:软件读取T-Sensor采集到的温度码(十六进制值)。单次采集模式下,只有 MISC_CTRL47[9:0]中记录的温度记录码0有效。
循环采集模式下,MISC_CTRL47[31:0]~MISC_CTRL50[31:0]记录了最近八次温度记录码 0~7,其中最新的温度记录值为温度记录码 0。
步骤 5:根据温度记录码计算出对应的温度值。Temprature=(T-Senso -136)/793*165-40(单位:度);

7、驱动源码分析

7.1、驱动的注册函数

static int hisi3516d_hwmon_init(void)
{
	int ret;

	//向hwmon驱动框架注册我们的驱动
	hisi3516d_hwmon_dev = hwmon_device_register(NULL);
	if(IS_ERR(hisi3516d_hwmon_dev)){
		
		printk(KERN_ERR "hwmod device register faild\n");
		ret = PTR_ERR((void *)hisi3516d_hwmon_dev);
		goto err_exit_3;
	}

	//填充hwmon驱动框架返回的设备,也就是创建设备下面的文件以及show、store方法
	ret = sysfs_create_group(&hisi3516d_hwmon_dev->kobj,
                                &hisi3516d_hwmon_attribute_group);
	if(ret){

		printk(KERN_ERR "create sysfs group faild\n");
		goto err_exit_2;
	}

	//映射芯片温度相关寄存器的地址
	ret = reg_remap();
	if(ret){
		printk(KERN_ERR "hi3559a hwmon ioremap faild\n");
		goto err_exit_1;
	}

	//初始化海思芯片的Tsensor寄存器
	hisi3516d_temp_init();

	return 0;
	
err_exit_1:
	sysfs_remove_group(&hisi3516d_hwmon_dev->kobj,&hisi3516d_hwmon_attribute_group);
err_exit_2:
	hwmon_device_unregister(hisi3516d_hwmon_dev);
err_exit_3:
	return ret;
	
}

module_init(hisi3516d_hwmon_init);

(1)向hwmon驱动框架注册我们的驱动,得到一个设备结构体;
(2)填充设备结构体,给设备创建文件以及show、store方法;
(3)映射芯片温度相关寄存器的地址,这里采用的动态映射;
(4)初始化海思芯片的Tsensor寄存器,设置温度检测模式为循环模式、循环检测周期、使能等;

7.2、驱动的卸载函数

static void hisi3516d_hwmon_exit(void)
{
	//解除寄存器的映射
	reg_unmap();
	
	//注销设备下的文件
	sysfs_remove_group(&hisi3516d_hwmon_dev->kobj,&hisi3516d_hwmon_attribute_group);
	
	//从hwmon驱动框架中注销驱动
	hwmon_device_unregister(hisi3516d_hwmon_dev);
}

module_exit(hisi3516d_hwmon_exit);

就是注册函数的逆过程,释放资源,删除sysfs中创建的文件,从hwmon驱动框架中注销驱动;

7.3、创建temp1_input文件

struct device *hisi3516d_hwmon_dev;

static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1_input, NULL, 0);

static struct attribute *hisi3516d_hwmon_attributes[] = {
	&sensor_dev_attr_temp1_input.dev_attr.attr,
	NULL,
};

static struct attribute_group hisi3516d_hwmon_attribute_group = {
	.attrs = hisi3516d_hwmon_attributes,
};

(1)hisi3516d_hwmon_attribute_group变量是用来创建设备下的文件以及文件show、store方法的;
(2)文件名字是temp1_input,show方法是show_temp1_input()函数;
(3)SENSOR_DEVICE_ATTR宏的分析参考博客:https://blog.csdn.net/weixin_42031299/article/details/124890370;

7.4、读取Tsensor寄存器温度的函数

static ssize_t show_temp1_input(struct device *dev,
		struct device_attribute *da, char *buf)
{
	volatile unsigned int reg_val = 0;
	unsigned int tmp_val = 0;
	int32_t temperature_val = 0;
	int32_t i = 0;

	//获取温度记录值寄存器0寄存器中保存的两个温度值
    reg_val = ioread32((void __iomem *)tsensorviraddr + T_SENSOR_RESULT0);
    for(i = 0; i < 2; i++)
    {
        tmp_val = (reg_val >> (16*i)) & 0x3ff;
        temperature_val += (tmp_val - 136)/793*165 - 40;
    }

	//获取温度记录值寄存器1寄存器中保存的两个温度值
    reg_val = ioread32((void __iomem *)tsensorviraddr + T_SENSOR_RESULT1);
    for(i = 0; i < 2; i++)
    {
        tmp_val = (reg_val >> (16*i)) & 0x3ff;
        temperature_val += (tmp_val - 136)/793*165 - 40;
    }

	//获取温度记录值寄存器2寄存器中保存的两个温度值
    reg_val = ioread32((void __iomem *)tsensorviraddr + T_SENSOR_RESULT2);
    for(i = 0; i < 2; i++)
    {
        tmp_val = (reg_val >> (16*i)) & 0x3ff;
        temperature_val += (tmp_val - 136)/793*165 - 40;
    }

	//获取温度记录值寄存器3寄存器中保存的两个温度值
    reg_val = ioread32((void __iomem *)tsensorviraddr + T_SENSOR_RESULT3);
    for(i = 0; i < 2; i++)
    {
        tmp_val = (reg_val >> (16*i)) & 0x3ff;
        temperature_val += (tmp_val - 136)/793*165 - 40;
    }

	//温度值除以8,获取平均值
	temperature_val = temperature_val >> 3;
	
	sprintf(buf, "%d", temperature_val);
	return strlen(buf);
}

(1)tsensorviraddr:温度相关寄存器动态映射后得到的基地址;
(2)获取8个温度值,然后再返回温度的平均值;
(3)当我们用"cat /sys/class/hwmon/hwmon0/temp1_input"命令读取temp1_input文件时,驱动里就调用show_temp1_input()函数,这是temp1_input文件的show方法;

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

hisi3516dv300芯片基于hwmon驱动框架的温度获取驱动源码分析 的相关文章

  • mysql视图的作用(详细)

    MySQL视图是一个虚拟表 其内容由查询定义 同真实的表一样 视图包含一系列带有名称的列和行数据 但是 视图并不在数据库中以存储的数据值集形式存在 行和列数据来自由定义视图的查询所引用的表 并且在引用视图时动态生成 对其中所引用的基础表来说
  • Centos7 网卡无法连接

    借用一下某个博主的图 因为我忘记截图了 礼貌附上链接 错误信息应该是这样的 大家可以先去看一下这个博主的错误 如果不行的话可以再换这种方法 在确认了ONBOOT的属性设置为 yes的情况下我进行了 网络重启 service network
  • Imagination在GDC 2022上推出下一代移动游戏解决方案

    借助于O3DE引擎展示采用硬件加速的全域光照光线追踪解决方案 英国伦敦 2022年3月23日 Imagination Technologies在 2022游戏开发者大会 GDC 2022 上推出了其下一代移动游戏图形处理解决方案 借助于Op

随机推荐

  • keil mdk 常见警告解析

    1 warning Deprecated declaration 函数 give arg types 该函数如果没有参数就要在括号里加 void 例如 函数定义 void TP GetAdXY int adx ady adx Read X
  • linux qt cmake错误的解决方法

    QT错误 新建项目后显示项目未配置 在工具 选项 kits中先要把kits clone一个到Manual中 在项目中使用Clone of Desktop这一个 极其坑 安装cmake sudo apt get install cmake 编
  • python-flask-sqlalchemy

    1 flask sqlalchemy 集成的两种方式 1 通过flask app初始化 from flask sqlalchemy import SQLAlchemy flask db SQLAlchemy from flask impor
  • 安装nltk_data数据包的问题:[Errno 11004] getaddrinfo failed

    问题 安装nltk时 在python shell中输 import nltk nltk download 会出现以下问题 这是因为nltk download 下载连接不上 在C Windows System32 drivers etc中找到
  • 图解fork函数机制(简单易懂)

    fork函数机制十分难以理解 尤其涉及到循环fork时就更难搞清楚 例如 for i 0 i lt 3 i pid fork if pid gt 0 std cout lt lt pid lt
  • 经常访问的站点

    色色日语网 www qianxunjp com 日本软件 www flatworld jp
  • MySQL执行计划解读

    Explain语法 EXPLAIN SELECT 变体 1 EXPLAIN EXTENDED SELECT 将执行计划 反编译 成SELECT语句 运行SHOW WARNINGS 可得到被MySQL优化器优化后的查询语句 2 EXPLAIN
  • 首看世界杯

    首看世界杯 不谈技术 只聊自己的几点感受 纯属个人感想 今年是第一次关注世界杯 本来对足球是没有什么兴趣的 如果说对足球有什么了解的话 大部分还是来自小时候的动画片 足球小将 但是看现实中的足球比赛 半天进一个球 甚至一个球都不会进 感觉没
  • 【技术碎片】jcraft.jsch 文件传输工具与方法

    目录 前言 依赖 ChannelSftp功能 实现 JschUtil java ImageInfoService java ImageInfoServiceImpl java 参考资料 前言 SFTP相当于SSH FTP 其中FTP则协议通
  • 2023第一个重大漏洞,几乎影响所有组织

    Dark Reading 网站披露 微软修复了 Outlook 中存在的零日漏洞 漏洞被追踪为 CVE 2023 23397 是一个权限提升漏洞 攻击者可以利用该漏洞访问受害者的 Net NTLMv2 响应身份验证哈希并冒充用户 安全研究人
  • 集训一月小结

    暑假集训过了4个周了 仔细想想这4个周我都做了些什么 学到了什么 又有什么让我感到开心 有什么令我绝望 不管是谁都必须承认在板凳上每天坐上9个小时以上 学习那些算法 有时候会让我感到兴奋 有时候又会让我不愿意在电脑前坐一分钟 想想过程 究其
  • 中国智能卡车“遥遥领先”:卡车NOA落地5000万公里0事故,全球首个

    贾浩楠 发自 副驾寺智能车参考 公众号 AI4Auto 成熟的 擎天柱 已经可以自己出去赚钱了 此时此刻 遍及华东 华北 华南 西北 几乎全国所有主要货运干线上 都有智能重卡承运商单 高速路段由卡车智能驾驶系统完全承担驾驶任务 自主控制油门
  • chinesecalendar报错:no available data for year 2022, only year between [2004, 2021] supported

    Error no available data for year 2022 only year between 2004 2021 supported 解决 更新最新chinesecalendar 每年年底需更新最新版本的chineseca
  • BGP route processing

    路由协议 套用IT里面的术语 实际上就是分布式数据库系统 它包含了节点间的数据传递和节点内的数据处理 对于BGP来说 节点间基于TCP 端口179 的连接 在这个基础上 可以构建AS间的EBGP AS内的IBGP IBGP有full mes
  • python中的os.walk函数的用法

    转自http blog csdn net bagboy taobao com article details 8938126 os walk top topdown True nerr r None followlinks False 可以
  • Check failed: registry.count(t ype) == 1 (0 vs. 1) Unknown layer type: Input (known types: Input )

    自己建立一个工程 调用libcaffe lib 成功编译 但是运行就会遇到报错 F0519 14 54 12 494139 14504 layer factory hpp 77 Check failed registry count t y
  • Random类和UUID以及验证码的生成

    一 介绍与测试 Random 产生随机数 UUID 通用唯一识别码 目的是让分布式系统中的所有元素 都能有唯一的辨识信息 根据当前时间和电脑网卡 生成一段字符 Radom类 import java util public class Ran
  • 你为成为一名DBA,做好准备了吗?

    之前的文章中 我提到了 如何找到第一份DBA工作 云时代的来临 DBA该何去何从 关于从事数据库工作 需要哪些经验 那么 如果你想成为一名DBA 你为此做好准备了吗 我曾问过的一个问题是一个人应该从事DBA这样的职业么 这个问题并不容易回答
  • Android 实现隐私政策提示弹窗

    button shape xml
  • hisi3516dv300芯片基于hwmon驱动框架的温度获取驱动源码分析

    1 内核hwmon驱动框架 参考博客 内核hwmon驱动框架详解以及海思芯片温度驱动分析 2 驱动实现的效果 sys devices virtual hwmon hwmon0 pwd sys class hwmon hwmon0 sys d