Files
Power-off-analysis/温控与EC传感器分析笔记.md
2026-04-04 15:32:51 +08:00

36 KiB
Executable File
Raw Permalink Blame History

1. 背景与现象

  • 设备Google KaisaAcer CXI4 Chromebox基于 Puff baseboard
  • 固件coreboot + Chrome EC
  • 主要问题
    • Windows 下曾出现热事件关机;
    • EC 控扇仅依赖一颗板载热敏电阻,温度响应滞后于 CPU风扇启动与拉满偏晚。

本文整理 Puff/Kaisa 上 温度传感器、EC 温控、DPTF 控扇 的整体路径,并记录调试 DPTF FAND/_FSL 时的关键发现。


2. 温度与 EC 的关系概览

  • CPU/主机侧温度

    • Linux/sys/class/thermal/thermal_zone* 中的 TCPUx86_pkg_temp 等,由 CPU/PCH 提供,不经过 EC。
    • WindowsDPTF 通过 ACPI 热区(如 \_SB.PCI0.TCPU)取 CPU 温度。
  • EC 侧温度Puff/Kaisa

    • 只有 1 路板载 thermistor
      • ADCADC_TEMP_SENSOR_1NPCX_ADC_CH0
      • 逻辑 IDTEMP_SENSOR_CORE
      • 读函数:get_temp_3v3_30k9_47k_4050b
    • EC 每秒读这路 ADC写入 EC memory map对外通过 ACPI 暴露为 TSR0

结论
目前板上可用的温感来源只有两类CPU 自身温度 + EC 的一颗板载 thermistor没有额外硬件温感。


3. EC 控扇链路Puff/Kaisa

3.1 板级配置(ec/board/puff/board.c & board.h

  • 温度枚举:
enum temp_sensor_id {
	TEMP_SENSOR_CORE,
	TEMP_SENSOR_COUNT
};
  • ADC 与 temp_sensors[]
[ADC_TEMP_SENSOR_1] = {
	.name = "TEMP_SENSOR_1",
	.input_ch = NPCX_ADC_CH0,
	.factor_mul = ADC_MAX_VOLT,
	.factor_div = ADC_READ_MAX + 1,
},

const struct temp_sensor_t temp_sensors[] = {
	[TEMP_SENSOR_CORE] = {
		.name = "Core",
		.type = TEMP_SENSOR_TYPE_BOARD,
		.read = get_temp_3v3_30k9_47k_4050b,
		.idx = ADC_TEMP_SENSOR_1,
	},
};
  • EC 的温阈值与风扇曲线(thermal_params[]
const static struct ec_thermal_config thermal_a = {
	.temp_host = {
		[EC_TEMP_THRESH_WARN] = 0,
		[EC_TEMP_THRESH_HIGH] = C_TO_K(68),
		[EC_TEMP_THRESH_HALT] = C_TO_K(78),
	},
	.temp_host_release = {
		[EC_TEMP_THRESH_WARN] = 0,
		[EC_TEMP_THRESH_HIGH] = C_TO_K(58),
		[EC_TEMP_THRESH_HALT] = 0,
	},
	.temp_fan_off = C_TO_K(40),  // <40℃ 关风扇
	.temp_fan_max = C_TO_K(60),  // ≥60℃ 满速
};

struct ec_thermal_config thermal_params[] = {
	[TEMP_SENSOR_CORE] = thermal_a,
};

3.2 通用 thermal 引擎(ec/common/thermal.c

  • 每秒执行一次 thermal_control()

    1. 遍历所有温度传感器(这里只读 TEMP_SENSOR_CORE
      for (i = 0; i < TEMP_SENSOR_COUNT; ++i)
          rv = temp_sensor_read(i, &t);
      
    2. 根据 thermal_params[i].temp_host[]temp_host_release[] 统计 WARN/HIGH/HALT触发
      • chipset_force_shutdown(CHIPSET_SHUTDOWN_THERMAL);
      • throttle_ap(THROTTLE_ON, THROTTLE_HARD/SOFT, THROTTLE_SRC_THERMAL);
    3. 根据 temp_fan_offtemp_fan_max 计算该传感器需要的风扇百分比:
      f = thermal_fan_percent(thermal_params[i].temp_fan_off,
                              thermal_params[i].temp_fan_max,
                              t);
      fmax = max(fmax, f);
      
    4. 对所有风扇设置统一需求:
      for (i = 0; i < fan_get_count(); i++)
          fan_set_percent_needed(i, fmax);
      

结论
在 “EC 自动控扇” 模式下,风扇完全由 EC 根据这路 thermistor + thermal_a 曲线驱动。


4. DPTF 与 EC 的桥接ACPI/DPTF 侧)

4.1 温度TSR0..TSR4

  • coreboot 的 ec_dptf_helpers.c 为 DPTF temp participants 生成 _TMP
/* TSRx._TMP = EC0.TSRD(x) */
acpigen_write_method_serialized("_TMP", 0);
acpigen_emit_byte(RETURN_OP);
acpigen_emit_namestring(acpi_device_path_join(ec, "TSRD"));
acpigen_write_integer(tsr_index);  // 0..4
  • ec.asl 中:
Method (TINS, 1, Serialized)
{
	Switch (ToInteger (Arg0)) {
		Case (0) { Return (TIN0) }
		Case (1) { Return (TIN1) }
		...
		Default  { Return (TIN0) }
	}
}

Method (TSRD, 1, Serialized)
{
	Local0 = \_SB.PCI0.LPCB.EC0.TINS (Arg0)
	/* 检查 TNCA/TNPR/TNOP/TBAD 省略 */
	Local0 += \_SB.PCI0.LPCB.EC0.TOFS
	Local0 *= 10     // 转为 1/10 K
	Return (Local0)
}
  • Puff 上:只有 TEMP_SENSOR_CORETIN0TSR0,其它 TSR1..TSR4 基本为空。

4.2 风扇TFN1 + FST/FSL + FAND

根据 DPTF 规范FAN participantTFN1)需要提供:

  • _FST:返回 { Revision, Control, Speed }
  • _FSL(level):设置 fan level/duty。

Chrome EC 路径(ec_dptf_helpers.c

  • 写回包 TFST
/* TFST = { Revision, Control, Speed } */
acpigen_write_name("TFST");
acpigen_write_package(3);
acpigen_write_integer(0); /* Revision */
acpigen_write_integer(0); /* Control */
acpigen_write_integer(0); /* Speed */
acpigen_pop_len();        /* Package */
  • _FST 实现大致为:
/* _FST: TFST[1] = EC0.FAND; TFST[2] = FANx_RPM; return TFST */
acpigen_write_method_serialized("_FST", 0);
acpigen_write_store();
acpigen_emit_namestring(acpi_device_path_join(ec, "FAND"));
acpigen_emit_byte(INDEX_OP);
acpigen_emit_namestring("TFST");
acpigen_write_integer(1);  // Control
...
acpigen_write_store();
acpigen_emit_namestring(acpi_device_path_join(ec, "FAN0")); // 实际 RPM 来源
acpigen_emit_byte(INDEX_OP);
acpigen_emit_namestring("TFST");
acpigen_write_integer(2);  // Speed
...
acpigen_emit_byte(RETURN_OP);
acpigen_emit_namestring("TFST");
acpigen_pop_len();
  • _FSL(level) 实现:
/* _FSL(Arg0): Store(Arg0, EC0.FAND) */
acpigen_write_method_serialized("_FSL", 1);
acpigen_write_store();
acpigen_emit_byte(ARG0_OP);
acpigen_emit_namestring(acpi_device_path_join(ec, "FAND"));
acpigen_pop_len();

其中 FAND 对应 EC ACPI RAM 中地址 0x04EC_ACPI_MEM_FAN_DUTY),在 ec_commands.h 定义为:

/* DPTF Target Fan Duty (0-100, 0xff for auto/none) */
#define EC_ACPI_MEM_FAN_DUTY 0x04

ACPI 通过 EC_ACPI_MEM_FAN_DUTY 写入后EC C 侧(ec/common/acpi.c)处理:

case EC_ACPI_MEM_FAN_DUTY:
	dptf_set_fan_duty_target(data);
	break;

dptf_set_fan_duty_target() 实现(ec/common/fan.c

/* 0-100% sets duty, out of range means let the EC drive */
void dptf_set_fan_duty_target(int pct)
{
	int fan;

	if (pct < 0 || pct > 100) {
		/* 超出范围:交回 EC 自动控扇 */
		for (fan = 0; fan < fan_count; fan++)
			set_thermal_control_enabled(fan, 1);
	} else {
		/* 合法 0-100按 duty 控扇,关闭 thermal 自动控扇 */
		for (fan = 0; fan < fan_count; fan++)
			set_duty_cycle(fan, pct);
	}
}

读取时,若处于 duty 模式,dptf_get_fan_duty_target() 返回 0100否则返回 -1对应 FAND=0xff。

结论(非常重要)

  • 写入 0100DPTF 接管风扇EC 用该 duty 控扇thermal 自动模式被关闭;
  • 写入 0xff 或越界值(<0 或 >100例如 0x80:退回 EC 自动控扇模式FAND 对外显示为 0xff。

5. 模式选择EC 控扇 vs Windows DPTF 控扇

5.1 EC 控扇模式(稳定默认)

coreboot defconfig 中:

CONFIG_MINIPC_EC_FULL_FAN_CONTROL=y
CONFIG_DRIVERS_INTEL_DPTF_DISABLE_ACTIVE_FAN=y
  • DPTF 风扇参与者被隐藏/禁用 Active Policy
  • EC 在 _REG 时写 FAND=0xFF,明确进入自动模式;
  • 风扇完全由 EC thermal 引擎(第 3 节)驱动。

适用:

  • 无 Windows DPTF 驱动或不希望依赖 DPTF
  • 简化行为,只调一条 EC 曲线。

5.2 Windows DPTF 控扇模式(实验/优化)

coreboot defconfig 中:

# CONFIG_MINIPC_EC_FULL_FAN_CONTROL is not set
# CONFIG_DRIVERS_INTEL_DPTF_DISABLE_ACTIVE_FAN is not set
CONFIG_DRIVERS_INTEL_DPTF_ECTST_FAND_DEBUG=y
  • DPTF FANTFN1暴露给 Windows
  • Active Policy 启用DPTF 根据 CPU 温度 + TSR0 等决定何时 _FSL(level)
  • EC 通过 dptf_set_fan_duty_target(level) 接收 duty
    • 0100DPTF 覆盖;
    • 0xff/越界:交回 EC 自动。

前提
Windows 中必须安装并启用 Intel DPTF 驱动INT3400/INT3404 等设备正常工作),否则不会按策略调用 _FSL()


6. ECT0 调试:为什么 _FSL(0x80) 后 FAND 一直是 0xff

在 Windows 下,使用 ECT0._FST/_FSL 调试 FANDlogs.txt

[1] Current FAND from _FST:
  FAND = 0x46          # 70%,说明曾经处于 duty 模式

[2] Writing FAND via _FSL(0x80) ...

[3] Read-back FAND after _FSL:
  FAND = 0xff

[4] 继续监视 _FST:
  FAND 始终是 0xff

结合第 4 节的实现:

  • 0x80 = 128 > 100 → 按 dptf_set_fan_duty_target() 的语义,这是“越界值”:
    • 进入 pct < 0 || pct > 100 分支;
    • 调用 set_thermal_control_enabled(fan, 1)恢复 EC 自动控扇
    • dptf_get_fan_duty_target() 返回 -1对 ACPI 显示为 FAND=0xff。

正确结论

  • FSL/FST → EC 的链路是通的,只是你写入的是一个“退回自动”的值(>100EC 正确地退出了 DPTF duty 模式;
  • _FST 一直看到 FAND=0xff说明当前处于 “auto/none” 状态,而不是链路失效。

正确的测试方式

  • 要验证 DPTF/ECT0 控扇是否生效,应使用 0100 的值:

    ectest -acpi \_SB.ECT0._FSL 50   # 50%
    ectest -acpi \_SB.ECT0._FST      # FAND 应为 0x32且风扇转速有变化
    
  • 要主动退回 EC 自动控扇,可以写 0xff 或 >100(例如 0x80

13.7 用其他方法监控 DPTF 是否发送风扇控制信号

除轮询 \_SB.ECT0._FST 看 FAND 是否随温度变化外,可用脚本 Monitor_DPTF_Fan.ps1 做两类监控需管理员、ectest 可用):

模式 说明
check 检查本机是否有 DPTF/ESIF 服务、ACPI 设备 INT3404/INT3400、相关驱动判断 DPTF 栈是否加载。
poll 高频率轮询 _FST(默认每 200ms将时间戳与 FAND 写入 CSV持续一段时间默认 60s。对 CPU 加压时若 CSV 中 FAND 始终不变,可判断 DPTF 未通过 _FSL 写 FAND。
watch 专用于监控 INT3404 是否发送控扇信号:轮询 _FST,仅在 FAND 发生变化时在控制台打印(并写 CSV。若加压过程中出现 “FAND changed: 0xff -> 0x50” 等,说明有对象(多为 INT3404/DPTF写入了 _FSL若始终无输出则 INT3404 未写 _FSL 或 EC 覆盖了写入。
etw 用 logman 采集 DPTF/ESIF 的 ETWEsifLfEtwProvider 等),记录一段时间后 tracerpt 转 CSV。若已装 Intel DPTF 驱动,可查看是否有风扇/ACPI 相关事件。
all 先 check再运行 etw按提示加压后回车停止最后做 poll 并落盘。

用法示例:

.\Monitor_DPTF_Fan.ps1 -Mode check
.\Monitor_DPTF_Fan.ps1 -Mode watch -PollSeconds 120 -PollIntervalMs 150   # 监控 INT3404 是否发控扇
.\Monitor_DPTF_Fan.ps1 -Mode poll -PollSeconds 120 -PollIntervalMs 150
.\Monitor_DPTF_Fan.ps1 -Mode etw
.\Monitor_DPTF_Fan.ps1 -Mode all

结论解读:若 poll 阶段在负载下 FAND 始终不变,且 check 未见 DPTF 设备/服务,则当前系统未通过 DPTF 发送风扇控制信号;若 ETW 中有相关事件,可进一步对照 DPTF 文档看是否包含 _FSL 调用。

  • 要主动退回 EC 自动控扇,可以写 0xff 或 >100(例如 0x80
    ectest -acpi \_SB.ECT0._FSL 0xff # 或 0x80 等 >100
    ectest -acpi \_SB.ECT0._FST      # FAND 应回到 0xff
    

7. 总结

  1. Puff/Kaisa 的 EC 只有一颗板载 thermistorTEMP_SENSOR_CORE),所有 EC 自动温控与关机/限频都基于这一路。
  2. coreboot + Chrome EC 已经在 ACPI/DPTF 层实现了完整的 FAN 接口TFN1._FST/_FSL
    • _FSL(level) → 写入 EC_ACPI_MEM_FAN_DUTYdptf_set_fan_duty_target(level)
    • _FST() → 回读当前 FAND 与实际 RPM。
  3. EC 明确定义了 fan duty 的语义:
    • 0100DPTF 直接指定 dutyEC 关闭 thermal 自动控扇;
    • 0xff 或越界:退出 DPTF duty 模式,交回 EC 自动控扇FAND 显示为 0xff。
  4. Windows 下已枚举到 INT3400/INT3404在设备管理器中分别显示为 Intel(R) Dynamic Tuning ManagerINT3400Intel(R) Dynamic Tuning Fan ParticipantINT3404设备实例路径为 ACPI\INT3400\0ACPI\INT3404\0,说明 DPTF 风扇控制器栈与 ACPI 风扇设备都是存在的
  5. 实测轮询 \_SB.ECT0._FSTFAND 只在手动 _FSL(x) 时改变,负载/温度变化本身并不会让 DPTF 自动写入 FAND结合 INT3404 存在但 FAND 不随温度变化,可以判断:当前固件/策略仍以 EC 自动曲线为主控DPTF 风扇参与者更多处于观察/可选控制状态
  6. _FSL(0x80) 后 FAND 一直 0xff” 是因为 0x80>100被 EC 解读为 “放弃 DPTF 覆盖、恢复 EC 自动”,而非链路未接通。
  7. 选择 EC 控扇还是 DPTF 控扇,只需在 coreboot defconfig 中切换:
    • EC 控扇:CONFIG_MINIPC_EC_FULL_FAN_CONTROL=y + CONFIG_DRIVERS_INTEL_DPTF_DISABLE_ACTIVE_FAN=y
    • DPTF 控扇:两者都不设,并确保 Windows 中 DPTF 驱动工作正常。

7.1 固件 20260224034907 配置确认DPTF 控扇固件)

  • 固件20260224034907 目录下为 coreboot_edk2-kaisa-mrchromebox_20260224.rom 的构建产物,含 .configbuild.log
  • .config 中与风扇控制相关的项
    • # CONFIG_MINIPC_EC_FULL_FAN_CONTROL is not set → EC 全权控扇,主机可写 FAND
    • # CONFIG_DRIVERS_INTEL_DPTF_DISABLE_ACTIVE_FAN is not set → DPTF 主动风扇策略开启
    • CONFIG_DRIVERS_INTEL_DPTF_ECTST_FAND_DEBUG=y → 暴露 ECT0 调试设备,可读/写 FAND。
  • 结论:该固件为 DPTF 控扇 配置,风扇应由 DPTF 通过 _FSL 写 FANDEC 按 FAND 执行。
  • 与实测的差异:在 Windows 下用 Monitor_DPTF_Fan.ps1 -Mode watch 观察CPU 升温时 FAND 从未变化(无 “FAND changed”说明 DPTF 驱动/策略没有在按温度调用 _FSL。问题在 Windows/DPTF 侧,不在固件是否为 DPTF 控扇。
  • 建议:在 Windows 中检查电源/热管理是否有 “Intel DPTF” 或 “平台热管理” 并确认已启用;从 Microsoft Update Catalog 或 OEM 安装/更新 “Intel Dynamic Platform and Thermal Framework” 驱动后,再以 watch 模式观察负载下 FAND 是否变化。

7.2 Windows 电源/热管理检查步骤(驱动已确认时)

硬件与 DPTF 驱动INT3400/INT3404、esifsvc已确认正常时若 FAND 仍不随温度变化,可逐项检查电源与热管理是否“关掉”了 DPTF 控扇:

步骤 位置 检查内容
1 设置 → 系统 → 电源 查看当前“电源模式”(平衡/最佳性能等部分机型在此有“热管理”或“Intel 图形/平台”相关项,确认未选“静音/省电”导致不拉高风扇。
2 控制面板 → 电源选项 → 更改计划设置 → 更改高级电源设置 在列表中查找 处理器电源管理IntelThermal平台热管理 或 OEM如 Acer提供的“风扇/热管理”子项。若有“最大处理器状态”“散热方式”等,可先选“主动/积极散热”或提高最大状态,排除因电源计划限制导致 DPTF 不写 _FSL。
3 设备管理器 → 系统设备 → Intel(R) Dynamic Tuning Fan Participant 属性 → 驱动程序:确认设备已启用、无感叹号;若有“电源管理”选项卡,可取消勾选“允许计算机关闭此设备以节约电源”(若存在),避免被省电关闭。
4 OEM 自带软件 若装有 Acer Care、Lenovo Vantage、Dell Power Manager 等,在“性能/散热/风扇”类设置中查看是否有“静音模式”“禁用 DPTF”“自定义风扇曲线”等若有且设为静音或禁用 DPTF改为平衡/性能或启用 DPTF 后再用 watch 观察。
5 当前电源方案 管理员 PowerShellpowercfg /getactivescheme 查看当前方案;必要时切换为“高性能”或“卓越性能”后再次运行 Monitor_DPTF_Fan.ps1 -Mode watch,看负载下是否出现 “FAND changed”。

脚本 Monitor_DPTF_Fan.ps1 -Mode check 会输出当前电源方案及上述 14 的手动检查提示,便于逐项核对。

这份笔记即为当前 Puff/Kaisa 上温控与 EC/DPTF 行为的整理,可作为后续调整 EC 曲线或 DPTF 策略时的参考。

温控与 EC 传感器分析笔记

本文档记录 Chromebox 刷 coreboot 后Windows 热关机、Linux 温控、EC 温度源及 I2C 设备识别相关的有用信息。


1. 问题背景

  • 现象Windows 下出现热事件关机EC 控扇仅依赖板载温度传感器,延迟与偏差大,导致风扇响应滞后。
  • 根因EC 只有一路 ADC 热敏电阻“Core”且该点滞后于 CPU 实际温度Windows 负载/功耗较高时易触发过热关机。

2. 热区与 EC 的关系Linux 视角)

  • thermal_zone(如 TCPU、x86_pkg_temp内核/CPU 热区,数据不经过 EC。
  • EC 获取 CPU trip 的方式
    • 硬件THERMTRIP#、PROCHOT# 等引脚由 CPU 拉低EC 直接检测。
    • 软件ACPI Notifythermal zone critical 等)可通知 EC。
  • 直接连到 EC 的温度cros_ec 上报的 “Core” = EC 自己读的 ADC 热敏电阻INT3400 与 EC 策略/关机链路相关。

3. Linux 温控 vs Windows DPTF

项目 Linux 温控 Windows DPTF
策略 内核 governor / thermald OEM 策略引擎 + ACPI
应用感知 一般无 有(游戏/办公等不同策略)
风扇 内核 cooling 或 fancontrol 常由 EC 独管DPTF 不控扇

DPTF 未真正控扇常见原因:风扇权在 EC或 OEM 未把风扇暴露给 DPTF或 Windows 无 EC 风扇驱动。


4. EC 温度源(以 Puff 板为例)

  • 当前:仅 1 路 温度 —— ADC 热敏电阻(ADC_TEMP_SENSOR_1TEMP_SENSOR_CORE),读函数 get_temp_3v3_30k9_47k_4050b
  • 无 I2C 温度传感器board.c 里 temp_sensors[] 只有上述 ADC 项EC 的 I2C 上接的是 INA3221、PPC、TCPC、POWER、EEPROM 等,无温感芯片。
  • 增加温度源的可能:若硬件有预留(空余 ADC 通道或 EC I2C 上接温感),可在 EC 源码里加 temp_sensor 配置;否则需改硬件。

5. 主机 I2C 与 EC I2C 是两套总线

  • 主机侧i2cdetect -l 的 i2c-0i2c-11CPU/PCH 的 SMBus、i915 等,由 Linux 枚举;扫描用 i2c_scan.sh(调用 i2cdetect
  • EC 侧EC 固件里 i2c_ports[] 定义的 GPIO_I2C0I2C7设备在 board.c 中定义。
  • 结论:主机 I2C 扫描到的地址(如 0x08、0x44、0x52…不会出现在 EC 的 board.c 里EC 能扫的只是自己那几条总线。

6. 本机 EC I2C 扫描结果ectool-cec i2cxfer

EC Port 扫到地址 用途/推断
1 0x40 电流/功率类,非标准 INA3221
3 0x2c 0x38 0x39 0x3d 0x3f 0x42 见下表
5 0x20 EEPROM (24cxx)

Port 3 各地址识别摘要

Addr reg 0x00 / 0x80 等 可能型号/类型
0x2c 0x77 0x79…index/data 访问 Nuvoton Super I/O / I2C 多功能(如 NCT5532D、NCT5577D、NCT38xx可能带温度,需 index/data 读
0x38 0x30 0x30 (ASCII) 等 GPIO/IO 扩展或显示
0x39 全 0 未初始化或空
0x3d 全 0 可能 SSD1306 或未初始化
0x3f 0x80 = 0x5A 0x5E 某 PMIC/传感器厂商 Device ID可能带温度,需查 datasheet
0x42 全 0 可能 INA3221 未使能或它用

7. 常见芯片 ID 参考(用于 ec_i2c_identify

  • 0x80 = 0x54 0x49TI INA3221/INA219电流/功率)。
  • 0x80 = 0x5A 0x5E:某厂商 Device ID多见于 PMIC/传感器,具体型号需查该厂商手册。
  • 0x2c 总线、首字节 0x77 等Nuvoton NCT55xx/NCT5577D/NCT38xx 等;访问多为 index/data直接读“reg 0”未必对应真实寄存器。
  • 0x20 + 数据区大段 0xff:常见 EEPROM (24c02 等)。
  • 0x38 读得 0x30 0x30:常见 GPIO/IO 扩展(如 PCA9555
  • 0x3c/0x3d 全 0:常见 SSD1306 等 OLED 未初始化。

8. 哪个可能是我们要找的温度传感器?

  • 首选候选Port 3, 0x2c
    Nuvoton NCT 系常带硬件监控温度;需在 EC 内按 index/data 协议和该芯片 datasheet 的温度寄存器 index 读取。

  • 次选候选Port 3, 0x3f (0x5A5E)
    可能是带温度通道的 PMIC/传感器;需找到对应 datasheet 确认是否有温度寄存器及地址/格式。

  • 其余0x40/0x42 INA 类、0x38 GPIO、0x39/0x3d、0x20 EEPROM不视为温度传感器


9. 脚本与工具

脚本/命令 作用
linux_collect_sensors.sh 收集 Linux 下 thermal zone、hwmon、lm-sensors、ectool temps、dmesg、CPU 信息;报告存当前目录或 /tmp。
i2c_scan.sh 主机侧 I2C 扫描i2cdetect扫 i2c-0i2c-N。
ec_i2c_scan.sh EC 侧 I2C 扫描,用 ectool-cec 的 i2cxfer 对指定 port 扫 0x080x77。须用 ectool-cec,系统 ectool 无 i2cxfer。
ec_i2c_identify.sh 对指定 port:addr 读 reg 0x00/0x80/0xFE/0xFF/0x0F并给出可能型号推断。

使用注意

  • 脚本行尾须为 LF;若出现 $'\r': 未找到命令 等,执行:sed -i 's/\r$//' 脚本名.sh
  • EC 扫描/识别需 sudo,且 ECTOOL 指向 ectool-cec例如
    ECTOOL=/home/jack/bin/ectool-cec sudo ./ec_i2c_scan.sh

10. 后续可做

  • 在 EC 源码中查 0x2c 对应芯片的 datasheetindex/data 读温度寄存器,并在 temp_sensor/thermal 里增加一路。
  • 若有 0x5A5E 对应型号的 datasheet确认是否带温度通道及寄存器再在 EC 中实现读取。
  • Windows 侧可先通过限 CPU 功耗/电源计划降低热负载,减轻 EC 单路温控滞后带来的热关机。

11. Puff/Kaisa 上增加一路温度传感器的可行性

11.1 地址与硬件对应关系Puff

  • I2C Port 3TCPC0上的 0x2c:在 Puff 板为 AN7447 TCPCAN7447_TCPC0_I2C_ADDR_FLAGS = 0x2C),不是独立温感芯片,不能当第二路温度源使用。
  • 0x3f:同颗 AN7447 的 SPI 转 I2C 接口(AN7447_SPI0_I2C_ADDR_FLAGS = 0x3F),读到的 0x5A5E 等为 AN7447 相关,不是独立 I2C 温度传感器。
  • 结论:当前 Puff 板 EC 可见的 I2C 总线上,没有空闲的、可用的 I2C 温度传感器芯片笔记中“Port 3 的 0x2c/0x3f 可能是温感”的推断在本板不成立。

11.2 可行方向

方向 说明
A. 第二路 ADC 热敏电阻 若原理图有未用的 ADC 通道 + 热敏电阻,在 board.h 增加 ADC_TEMP_SENSOR_2 与对应 enum,在 board.cadc_channels[]temp_sensors[]thermal_params[] 各加一项,并用现有 get_temp_3v3_30k9_47k_4050b 或对应 thermistor 读函数。
B. 新增 I2C 温感芯片 若硬件在某一 I2C 总线上新接温感(如 TMP112/TMP432 等),需:该总线在 i2c_ports[] 中、地址不与现有设备冲突;在 EC 中启用对应 driverCONFIG_TEMP_SENSOR_TMP112)、在 board.h 增加 TEMP_SENSOR_xxxTEMP_SENSOR_COUNT,在 board.c 中增加 temp_sensors[]thermal_params[]
C. 确认 0x5A5E 芯片 若某板型在其它 I2C 端口上有独立 0x5A5E 芯片且 datasheet 标明带温度寄存器,可为该芯片写专用 driverindex/data 或普通 I2C 读),再按 B 的方式挂到 temp_sensors[]

11.3 EC 侧增加一路温度传感器的实现步骤(通用)

  1. board.h

    • 增加 enum adc_channel 或 I2C 温感用的 enum(若用现有 driver通常只需 temp_sensor_id)。
    • enum temp_sensor_id 中增加新 IDTEMP_SENSOR_BOARD2),并保证 TEMP_SENSOR_COUNT 正确。
  2. board.c

    • ADC 热敏电阻:在 adc_channels[] 增加一路 ADCtemp_sensors[] 增加一项(nametypereadidx);在 thermal_params[] 增加对应 ec_thermal_config
    • I2C 温感:若为现有 driver如 TMP112temp_sensors[] 增加一项,read 指向 driver 的 get_validx 为 channel/index同样在 thermal_params[] 增加一项。
    • 若需参与控扇:在 setup_thermal() 等逻辑中为新 sensor 选择/绑定 thermal table。
  3. Kconfig / 构建

    • 若用 I2C 温感 driver在对应 board 的 Kconfigboard.h 中启用 CONFIG_TEMP_SENSOR_xxx 及该 driver 所需的 I2C_PORT_xxx
  4. thermal 策略

    • 若希望新传感器参与风扇控制,需在 thermal 逻辑中把新 sensor 的读数纳入(例如与现有 TEMP_SENSOR_CORE 取 max或单独阈值并保证 thermal_params[新ID]temp_fan_off / temp_fan_max 等已配置。

11.4 小结

  • 不改硬件Puff 上仅能依赖现有 1 路 ADC 热敏电阻Core无法在现有 I2C 设备0x2c/0x3f 均为 AN7447上“多出一路”温度传感器。
  • 改硬件:增加第二路 ADC 热敏电阻,或新接 I2C 温感芯片并接在已有或新增 I2C 总线上,再按 11.3 在 EC 中增加一项 temp_sensor 与 thermal 配置即可。

12. DPTF 控制风扇的可行性Puff/Kaisa

12.1 固件侧已支持 DPTF 控扇

  • Puff 的 DPTF 设计本来就是“DPTF 控扇”
    • baseboard/acpi/dptf.asl 中定义了 DPTF_ENABLE_FAN_CONTROL、DFPSFan Performance States、DART风扇对 CPU/TSR 的影响)。
    • Kaisa 的 overridetree.cb 里配置了 Active Policypolicies.active[0] = DPTF_CPUpolicies.active[1] = DPTF_TEMP_SENSOR_0CPU 温度 + 板载温感EC 上报)共同驱动风扇;另有 controls.fan_perf[]fine_grained_controlstep_size 等。
    • 注释写明:"Active Policy: CPU drives fan (DPTF controls via FAND)"。
  • 风扇档位由 DPTF 通过 ACPI 写 FAND 下发给 ECEC 按 FAND 驱动 PWM固件表和 devicetree 已具备完整策略,从固件角度看 DPTF 控扇是可行的

12.2 当前 Kaisa 配置为何是 EC 控扇

  • 为规避“Windows 下无人写 FAND、风扇卡在固定转速”的问题当前 defconfig 改为 EC 完全控扇
    • CONFIG_MINIPC_EC_FULL_FAN_CONTROL=y:隐藏 DPTF 风扇设备EC 在 _REG 时写 FAND=0xFFEC 自动控扇)。
    • CONFIG_DRIVERS_INTEL_DPTF_DISABLE_ACTIVE_FAN=y:关闭 DPTF Active PolicyDPTF 不再写 FAND。
  • 这样 Windows 即使没有 DPTF 驱动EC 也会按自身 thermistor 控扇,避免“既不用 DPTF 也不写 0xFF”导致的卡死。

12.3 若改为 DPTF 控扇

项目 说明
固件配置 取消 EC 全权控扇、恢复 DPTF 控扇:CONFIG_MINIPC_EC_FULL_FAN_CONTROL=n(或不设),CONFIG_DRIVERS_INTEL_DPTF_DISABLE_ACTIVE_FAN=n。重新编译刷写后DPTF 风扇设备可见Active Policy 生效。
温度源 DPTF 使用 CPU 温度_SB.PCI0.TCPU+ EC 上报的板载温感TSR0 = TEMP_SENSOR_0即 Core。CPU 温度由 OS/驱动提供,响应比单路 EC thermistor 快,有利于提前拉高转速。
Windows 依赖 必须安装 Intel DPTF 相关驱动(如 INT3400、INT3404 等),否则 OS 不会根据 DPTF 表写 FAND风扇仍可能不随负载变化。驱动可从 Microsoft Update Catalog 或 OEM 包获取。
Linux 若使用内核 thermal + DPTF ACPI需相应驱动/用户态配合写 cooling_device常见做法仍是 EC 控扇或 fancontrol。

12.4 小结

  • DPTF 控扇在 Puff/Kaisa 上固件可行:表与策略已就绪,只需改 defconfig 并确保 Windows 有 DPTF 驱动。
  • EC 控扇:不依赖 Windows 驱动,适合“通用 Windows/无 DPTF”场景但仅有一路板载温感响应偏慢。
  • 二选一:要么 EC 全权控扇(当前配置),要么 DPTF 控扇(改配置 + 装 Windows DPTF 驱动不可同时“DPTF 可见但不写 FAND、EC 也不写 0xFF”否则会再现风扇卡死。

13. 监视 FAND 与“DPTF 未改变 FAND”的排查

13.1 概念DPTF 如何写风扇

  • DPTF 控扇时OS 驱动调用 ACPI 方法 _FSLFine-grained Set LevelACPI 里把参数写入 EC 的 FAND 字段EC 固件读 FAND 驱动 PWM。
  • FANDEC ACPI 中 8 位字段Fan Dutyec.asl 的 ERAM 里0xFF 表示 EC 自动控扇。
  • _FSL(Arg0)DPTF 风扇设备(如 TFN1上的方法实现为 Store(Arg0, EC0.FAND)
  • 无法直接“hook _FSL”监视 _FSL 的效果 = 轮询读取 FAND,看其是否随负载/温度变化。

13.2 如何监视 FAND

  • 固件开启 CONFIG_DRIVERS_INTEL_DPTF_ECTST_FAND_DEBUG=y 时,会暴露调试设备 \_SB.ECT0
    • \_SB.ECT0._FST():读当前 FAND与 TFN1._FST 一致);
    • \_SB.ECT0._FSL(x):写 FAND与 DPTF 写路径一致)。
  • Windows:安装 ec-test-appOpenDevicePartnership ectest在管理员 PowerShell 中轮询:
    while ($true) {
        ectest -acpi \_SB.ECT0._FST
        Start-Sleep -Seconds 1
    }
    
  • Linux:若 ectool 支持读 FAND 或 EC RAM 中对应偏移,可写脚本轮询;或通过 cros_ec 接口读 thermal/风扇相关节点(视内核暴露而定)。

13.3 “监视过 FAND但 DPTF 似乎没有改变 FAND”的排查

检查项 说明
1. 当前是否为 DPTF 控扇配置 若固件为 EC 全权控扇CONFIG_MINIPC_EC_FULL_FAN_CONTROL=yCONFIG_DRIVERS_INTEL_DPTF_DISABLE_ACTIVE_FAN=yDPTF 风扇设备被隐藏_STA=0Windows 不会调用 _FSLFAND 仅由 EC 在写 0xFF 后按自身 thermistor 变化。此时“DPTF 没改 FAND”是预期行为。若要验证 DPTF 控扇,需先改为 DPTF 控扇配置并重新刷写。
2. Windows 是否识别 DPTF 设备 设备管理器中查看是否有 Intel Dynamic Platform and Thermal Framework 或 ACPI 下的 INT3400、INT3404 等。若无 INT3404/DPTF 风扇设备,说明驱动未加载或 ACPI 未暴露DPTF 不会写 FAND。
3. 是否安装 DPTF 驱动 从 Microsoft Update Catalog 搜索 “Intel DPTF” 或 “Dynamic Platform Thermal”或从 OEM如 Acer下载该机型的 DPTF/热管理驱动并安装。未安装时 OS 不会根据 DPTF 表调用 _FSL。
4. 电源/热管理策略 Windows 电源选项中是否有“Intel DPTF”或“平台热管理”相关项部分 OEM 软件会关闭 DPTF 控扇或固定为静音策略,导致不写 FAND。可切换电源方案平衡/高性能)后再观察 FAND。
5. 负载下观察 在确认固件为 DPTF 控扇、且设备管理器中有 INT3404 的前提下,对 CPU 施加负载(如压力测试),每隔数秒读一次 \_SB.ECT0._FST。若 FAND 始终不变,可判断为 DPTF 驱动未调用 _FSL 或策略未生效。

13.4 小结

  • 监视 _FSL = 轮询读 FAND通过 ECT0._FST 或等效接口)。
  • FAND 不变时:先确认是 EC 控扇 还是 DPTF 控扇 的固件;若为 DPTF 控扇则检查 Windows 是否安装并加载 DPTF 驱动、INT3404 是否存在、电源/热管理策略是否启用 DPTF 控扇。

13.5 如何检查 _SB.ECT0._FST 是否暴露给系统

\_SB.ECT0 仅在固件开启 CONFIG_DRIVERS_INTEL_DPTF_ECTST_FAND_DEBUG=y 时存在;未开启则 ACPI 里没有该设备,无法读 _FST。

方法一:直接尝试执行(最直接)

  • Windows:安装 ec-test-appectest管理员 PowerShell 中执行:

    ectest -acpi \_SB.ECT0._FST
    
    • 若返回数值(如 FAND 0255→ 已暴露。
    • 若报错 “object not found” / “method does not exist” / 无法解析路径 → 未暴露或固件未开上述 CONFIG。
  • Linux:用 ACPI 调试接口(需 root

    # 若内核有 ACPI 调试,可尝试(部分内核未启用)
    echo '\_SB.ECT0._FST' > /sys/kernel/debug/acpi/custom_method
    cat /sys/kernel/debug/acpi/custom_method
    

    或使用 acpi_call 等模块/工具调用 ACPI 方法(若已安装)。

方法二: dump DSDT/SSDT 看是否有 ECT0 与 _FST

  • Windows

    1. SSDTTime 选 “Dump DSDT” 得到 DSDT.aml或用 ACPICA acpidumpacpidump -b -n DSDT 得到 DSDT.dat改名为 DSDT.aml
    2. iasl 反编译:iasl -d DSDT.aml,得到 DSDT.dsl。
    3. 在 DSDT.dsl 中搜索 ECT0_FST:若在 Scope (\_SB) 下存在 Device (ECT0) 且其内有 Method (_FST, ...),则固件已暴露该对象(是否可用还取决于 _STA 等)。
  • Linux

    sudo cat /sys/firmware/acpi/tables/DSDT > DSDT.aml
    iasl -d DSDT.aml
    grep -n "ECT0\|_FST" DSDT.dsl
    

方法三:设备/驱动侧(辅助)

  • Windows:设备管理器中查看 ACPI 设备列表,是否有与 “ECT” 或 “DPTF ECT” 相关的设备(名称因 OEM 而异,不一定叫 ECT0
  • 若固件未开 CONFIG_DRIVERS_INTEL_DPTF_ECTST_FAND_DEBUGDSDT 中不会出现 ECT0方法一、二都会得到“未暴露”的结论。

13.6 实测ECT0._FSL 写入未生效的情况

  • 环境:当前这台 Chromebox 刷入的 coreboot 配置为 EC 全权控扇(推测存在 CONFIG_MINIPC_EC_FULL_FAN_CONTROL=y 之类),同时打开了 DPTF ECT 调试接口(CONFIG_DRIVERS_INTEL_DPTF_ECTST_FAND_DEBUG=y)。

  • 实测命令:

    # 1读当前 FAND
    ectest -acpi \_SB.ECT0._FST
    # Argument[1] = 0xff EC 自动控扇)
    
    # 2写入 0x80
    ectest -acpi \_SB.ECT0._FSL 0x80
    
    # 3再读
    ectest -acpi \_SB.ECT0._FST
    # Argument[1] 仍为 0xff
    
  • 同样逻辑用 Test_ECT0_FST_FSL.ps1 自动化验证时,效果一致:

    • [1] Current FAND from _FST: FAND = 0xff
    • [2] Writing FAND via _FSL(0x80) ... 执行成功ACPI 返回 Arg0=0x80
    • [3] Read-back FAND after _FSL: FAND = 0xff,后续轮询 _FST 仍为 0xff。

_FST/_FSL 返回值的具体解读:

  • [1] _FST = 0xff
    • _FST 返回包里的 Argument[1] = 0xff,表示 EC 侧 当前 FAND=0xFF,即“自动控扇模式”。
  • [2] _FSL(0x80) 返回 0x80
    • 这里的 Argument[0] = 0x80 只是这次 _FSL 调用把参数“原样回显”,说明 ACPI 方法被成功执行,并不等于 EC 里的 FAND 已经变成 0x80
  • [3] 再次 _FST 仍然 0xff
    • 再读 _FSTArgument[1] 还是 0xff,说明 EC 看到的 FAND 一直没有从 0xFF 变成 0x80,要么 _FSL 根本没写到 EC.FAND要么写了但被 EC 逻辑立即覆盖回 0xFF。
  • [4] 持续监控 _FST 也一直是 0xff
    • 说明在一段时间内 FAND 从未被真正设为 0x80EC 自始至终都工作在自动控扇模式。

结论(就当前固件配置):

  1. 虽然 ACPI 中存在 \_SB.ECT0._FST / _FSL,但 _FSL 调用并没有真正改掉 EC 侧的 FAND 字段
  2. 更可能的实现是coreboot 的 ACPI 里为调试方便加了 _FST/_FSL 方法,但在 EC 全权控扇配置下,\_FSL 要么只是“回显参数”(Return(Arg0)),要么即便临时写入 FAND也被 EC 策略立即覆盖回 0xFF
  3. 因为 FAND 始终为 0xFFEC 始终工作在“自动控扇”模式DPTF/ECT0 这条路径实际处于旁路状态

文档由分析过程整理,便于后续改 EC 或排查温控时查阅。

13.6 实测ECT0._FSL 写入 0x80 后 FAND 始终为 0xFF 的根因

  • 环境:当前 Chromebox 上已启用 DPTF + ECT0CONFIG_DRIVERS_INTEL_DPTF_ECTST_FAND_DEBUG=y),通过 ECT0._FST/_FSL 读写 FAND。
  • 实测命令(节选自 logs.txt