imx93和imx91的CPU温度采集

说明

板子做高低温测试

步骤

把板子放进高低温箱之后的,运行以下脚本,采集CPU温度和频率。

while true
do
    timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    cpu_temp=$(cat /sys/class/thermal/thermal_zone0/temp)
    cpu_temp=$(echo "$cpu_temp")
    cpu_freq=$(mhz)
    cpu_freq=$(echo "$cpu_freq")

    echo "[$timestamp] CPU Temp: $cpu_temp°C, CPU Freq: $cpu_freq MHz"

    echo "$timestamp, $cpu_temp °C, $cpu_freq MHz" >> IMX93_monitor.log

    sleep 5
done

调用流程

  1. 通过 cat /sys/class/thermal/thermal_zone0/temp 访问该节点.

  2. sysfs 接口处理:
    系统调用 temp_show 函数(定义在 thermal_sysfs.c 中)
    该函数通过 to_thermal_zone(dev) 获取对应的 thermal_zone_device 结构体
    调用 thermal_zone_get_temp(tz, &temperature) 函数获取温度

  3. 温度获取核心函数:
    thermal_zone_get_temp 函数(定义在 thermal_helpers.c 中)
    检查 tz 是否有效
    获取互斥锁保护:mutex_lock(&tz->lock)
    调用 __thermal_zone_get_temp(tz, temp) 获取实际温度
    释放互斥锁:mutex_unlock(&tz->lock)

  4. 实际温度读取:
    __thermal_zone_get_temp 函数调用具体硬件的温度读取回调:tz->ops->get_temp(tz, temp)
    如果启用了温度模拟功能,会根据条件决定是否使用模拟温度

  5. 硬件驱动实现(以 IMX91 平台为例):
    具体实现为 imx91_tmu_get_temp 函数(定义在 imx91_thermal.c 中)
    轮询 STAT0 寄存器,等待温度数据准备就绪:readl_relaxed_poll_timeout(tmu->base + STAT0, val, val & STAT0_DRDY0_IF_MASK, 1000, 40000)
    从 DATA0 寄存器读取温度原始数据:val = readl_relaxed(tmu->base + DATA0) & 0xffffU
    将原始数据转换为实际温度值:*temp = (int)val * 1000LL / 64LL(转换为 m°C)
    检查温度是否在有效范围内(-40°C 到 125°C)

  6. 结果返回:
    温度值逐层返回,最终由 temp_show 函数转换为字符串格式:sprintf(buf, "%d\n", temperature)
    返回给用户空间显示

完整调用链: 用户读取操作 → sysfs temp_showthermal_zone_get_temp__thermal_zone_get_temptz->ops->get_temp(硬件特定实现,如 imx91_tmu_get_temp)。

函数分析

static int imx91_tmu_get_temp(struct thermal_zone_device *tz, int *temp)
{
	struct tmu_sensor *sensor = thermal_zone_device_priv(tz);
	struct imx91_tmu *tmu = sensor->priv;
	u32 val;
	int ret;
    // 轮询等待温度数据就绪
	ret = readl_relaxed_poll_timeout(tmu->base + STAT0, val,
					 val & STAT0_DRDY0_IF_MASK, 1000,
					 40000);
	if (ret)
		return -EAGAIN;
    // 读取温度原始数据
	val = readl_relaxed(tmu->base + DATA0) & 0xffffU;
	printk(KERN_INFO "IMX91 TMU: Raw sensor data: 0x%04x\n", val);
    // 转换为实际温度值
	*temp = (int)val * 1000LL / 64LL;
	if (*temp < TMU_TEMP_LOW_LIMIT || *temp > TMU_TEMP_HIGH_LIMIT)
		return -EAGAIN;
	printk("yx ------- temp: %d\n", *temp);
	return 0;
}

问题

IMX91用上面的脚本高低温测试过程中,发现温度采集有问题,到零下就不显示了。

从高到低测试,温度采集正常,到零下就不显示了。

alt text

从低到高测试,零下不正常,零上温度采集正常。

alt text

芯片型号是:PIMX9131CVVXJAA

里面的C应该是工业级的版本,支持-40°C到125°C的温度范围。

alt text

IMX93的零下测试是正常的,但是IMX91的不显示0°C以下的温度,很奇怪。

posted @ 2025-12-11 11:26  杨旭0324  阅读(7)  评论(0)    收藏  举报