完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
Thermal 是什么
Thermal是内核开发者定义的⼀套⽀持根据指定governor控制系统温度,以防⽌芯⽚过热的框架模型。Thermal framework由governor、core、cooling device、sensor driver组成,软件架构如下: Thermal governor:⽤于决定cooling device是否需要降频,降到什么程度。⽬前Linux4.4内核中包含了如下⼏种governor: power_allocator:引⼊PID(⽐例-积分-微分)控制,根据当前温度,动态给各cooling device分配power,并将power转换为频率,从而达到根据温度限制频率的效果。 step_wise :根据当前温度,cooling device逐级降频。 fair share :频率档位⽐较多的cooling device优先降频。 userspace:不限制频率。 Thermal core: 对thermal governors和thermal driver进⾏了封装和抽象,并定义了清晰的接口。 Thermal sensor driver:sensor驱动,⽤于获取温度,⽐如tsadc。 Thermal cooling device:发热源或者可以降温的设备,⽐如CPU、GPU、DDR等。 配置⽅法 Menuconfig配置 <*> Generic Thermal sysfs driver ---> --- Generic Thermal sysfs driver APIs to parse thermal data out of device tree Enable writable trip points Default Thermal governor ( power_allocator ) ---> /* default thermal governor */ [ ] Fair -share thermal governor [ ] Step_wise thermal governor /* step_wise governor */ [ ] Bang Bang thermal governor User_space thermal governor /* user_space governor */ -*- Power allocator thermal governor /* power_allocator governor */ generic cpu cooling support /* cooling device */ [ ] Generic clock cooling support Generic device cooling support /* cooling device */ [ ] Thermal emulation mode support < > Temperature sensor driver for Freescale i.MX SoCs <*> Rockchip thermal driver /* thermal sensor driver */ < > rk_virtual thermal driver <*> rk3368 thermal driver legacy /* thermal sensor driver */ 通过“Default Thermal governor”配置项,可以选择温控策略,开发者可以根据实际产品需求进⾏修改。 Tsadc配置 Tsadc在温控中作为thermal sensor,⽤于获取温度,通常需要在DTSI和DTS都做配置。 以RK3399为例,DTSI包括如下配置: tsadc : tsadc@ff260000 { compatible = "rockchip,rk3399-tsadc" ; reg = <0x0 0xff260000 0x0 0x100 >; /* 寄存器基地址和寄存器地址总⻓度 */ interrupts = assigned -clocks = <& cru SCLK_TSADC >; /* ⼯作时钟,750KHz */ assigned -clock -rates = <750000 >; clocks = <& cru SCLK_TSADC >, <& cru PCLK_TSADC >; /* ⼯作时钟和配置时钟 */ clock -names = "tsadc" , "apb_pclk" ; resets = <& cru SRST_TSADC >; /* 复位信号 */ reset -names = "tsadc-apb" ; rockchip ,grf = <& grf >; /* 引⽤grf 模块,部分平台需要 */ rockchip ,hw -tshut -temp = <120000 >; /* 过温重启阀值,120 摄⽒度 */ /* tsadc 输出引脚配置,⽀持两种模式:gpio 和otpout */ pinctrl -names = "gpio" , "otpout" ; pinctrl -0 = <& otp_gpio >; pinctrl -1 = <& otp_out >; /* * thermal sensor 标识,表⽰tsadc 可以作为⼀个thermal sensor , * 并指定了引⽤tsadc 节点的时候需要带⼏个参数。 * 如果SoC ⾥⾯只有⼀个tsadc ,可以设置为0,超过⼀个必须设置为1。 */ #thermal-sensor-cells = <1>; status = "disabled" ; }; /* IO 口配置 */ pinctrl : pinctrl { ... tsadc { /* 配置为gpio 模式 */ otp_gpio : otp -gpio { rockchip ,pins = <1 6 RK_FUNC_GPIO &pcfg_pull_none >; }; /* 配置为over temperature protection 模式 */ otp_out : otp -out { rockchip ,pins = <1 6 RK_FUNC_1 &pcfg_pull_none >; }; }; .... } DTS的配置,主要⽤于选择通过CRU复位还是GPIO复位,低电平复位还是⾼电平复位。需要特别注意的是如果配置成GPIO复位,硬件上需要否把tsadc输出引脚连到PMIC的复位脚,否则只能配置成CRU复位。 &tsadc { rockchip ,hw -tshut -mode = <1>; /* tshut mode 0:CRU 1:GPIO */ rockchip ,hw -tshut -polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */ status = "okay" ; }; CPU & GPU配置 CPU在温控中作为cooling device,节点中需要包含#cooling-cells、dynamic-power-coefficient属性。 以RK3399为例: cpu_l0 : cpu@0 { device_type = "cpu" ; compatible = "arm,cortex-a53" , "arm,armv8" ; reg = <0x0 0x0 >; enable -method = "psci" ; #cooling-cells = <2>; /* cooling device 标识,表⽰该设备可以作为⼀个cooling device */ clocks = <& cru ARMCLKL >; cpu -idle -states = <& CPU_SLEEP &CLUSTER_SLEEP >; dynamic -power -coefficient = <100 >; /* 动态功耗常数C,动态功耗公式为Pdyn=C*V^2*F */ }; ... cpu_b0 : cpu@100 { device_type = "cpu" ; compatible = "arm,cortex-a72" , "arm,armv8" ; reg = <0x0 0x100 >; enable -method = "psci" ; #cooling-cells = <2>; /* cooling device 标识,表⽰该设备可以作为⼀个cooling device */ clocks = <& cru ARMCLKB >; cpu -idle -states = <& CPU_SLEEP &CLUSTER_SLEEP >; dynamic -power -coefficient = <436 >; /* ⽤于计算动态功耗的参数 */ }; GPU在温控中作为cooling device,节点需要包含#cooling-cells属性和power_model⼦节点。 以RK3399为例: gpu : gpu@ff9a0000 { compatible = "arm,malit860" ,"arm,malit86x" ,"arm,malit8xx" , "arm,mali-midgard" ; reg = <0x0 0xff9a0000 0x0 0x10000 >; interrupts = interrupt -names = "GPU" , "JOB" , "MMU" ; clocks = <& cru ACLK_GPU >; clock -names = "clk_mali" ; #cooling-cells = <2>; /* cooling device 标识,表⽰该设备可以作为⼀个cooling device */ power -domains = <& power RK3399_PD_GPU >; power -off -delay -ms = <200 >; status = "disabled" ; gpu_power_model : power_model { compatible = "arm,mali-simple-power-model" ; static -coefficient = <411000 >; /* ⽤于计算静态功耗的参数 */ dynamic -coefficient = <733 >; /* ⽤于计算动态功耗的参数 */ ts = <32000 4700 ( -80 ) 2>; /* ⽤于计算静态功耗的参数 */ thermal -zone = "gpu-thermal" ; /* 从gpu-thermal 获取温度,⽤于计算静态功耗 */ }; }; Termal zone 配置 Termal zone节点主要⽤于配置温控策略相关的参数并⽣成对应的⽤⼾态接口。 以RK3399为例: thermal_zones : thermal -zones { /* ⼀个节点对应⼀个thermal zone ,并包含温控策略相关参数 */ soc_thermal : soc -thermal { /* 温度⾼于trip-point-0 指定的值,每隔20ms 获取⼀次温度 */ polling -delay -passive = <20 >; /* milliseconds */ /* 温度低于trip-point-0 指定的值,每隔1000ms 获取⼀次温度 */ polling -delay = <1000 >; /* milliseconds */ /* 温度等于trip-point-1 指定的值时,系统分配给cooling device 的能量 */ sustainable -power = <1000 >; /* milliwatts */ /* 当前thermal zone 通过tsadc0 获取温度 */ thermal -sensors = <& tsadc 0>; /* trips 包含不同温度阀值,不同的温控策略,配置不⼀定相同 */ trips { /* * 温控阀值,超过该值温控策略开始⼯作,但不⼀定⻢上限制频率, * power 小到⼀定程度才开始限制频率 */ threshold : trip -point -0 { /* 超过70 摄⽒度,温控策略开始⼯作,并且70 摄⽒度也是tsadc 触发中断的⼀个阀值 */ temperature = <70000 >; /* millicelsius */ /* 温度低于temperature-hysteresis 时触发中断,当前未实现,但是框架要求必须填 */ hysteresis = <2000 >; /* millicelsius */ type = "passive" ; /* 表⽰超过该温度值时,使⽤polling-delay-passive */ }; /* 温控⽬标温度,期望通过降频使得芯⽚不超过该值 */ target : trip -point -1 { /* 期望通过降频使得芯⽚不超过85 摄⽒度,并且85 摄⽒度也是tsadc 触发中断的⼀个阀值 */ temperature = <85000 >; /* millicelsius */ /* 温度低于temperature-hysteresis 时触发中断,当前未实现,但是框架要求必须填 */ hysteresis = <2000 >; /* millicelsius */ type = "passive" ; /* 表⽰超过该温度值时,使⽤polling-delay-passive */ }; /* 过温保护阀值,如果降频后温度仍然上升,那么超过该值后,让系统重启 */ soc_crit : soc -crit { /* 超过115 摄⽒度重启,并且115 摄⽒度也是tsadc 触发中断的⼀个阀值 */ temperature = <115000 >; /* millicelsius */ /* 温度低于temperature-hysteresis 时触发中断,当前未实现,但是框架要求必须填 */ hysteresis = <2000 >; /* millicelsius */ type = "critical" ; /* 表⽰超过该温度值时,重启 */ }; }; /* cooling device 配置节点,每个⼦节点代表⼀个cooling device */ cooling -maps { map0 { /* * 表⽰在target trip 下,该cooling device 才起作⽤, * 对于power allocater 策略必须填target */ trip = <& target >; /* A53 做为cooloing device , THERMAL_NO_LIMIT 不起作⽤,但必须填 */ cooling -device = <& cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT >; contribution = <4096 >; /* 计算功耗时乘以4096/1024 倍,⽤于调整降频顺序和尺度 */ }; map1 { /* * 表⽰在target trip 下,该cooling device 才起作⽤, * 对于power allocater 策略必须填target */ trip = <& target >; /* A72 做为cooloing device , THERMAL_NO_LIMIT 不起作⽤,但必须填 */ cooling -device = <& cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT >; contribution = <1024 >;/* 计算功耗时乘以1024/1024 倍,⽤于调整降频顺序和尺度 */ }; map2 { /* * 表⽰在target trip 下,该cooling device 才起作⽤, * 对于power allocater 策略必须填target */ trip = <& target >; /* GPU 做为cooloing device , THERMAL_NO_LIMIT 不起作⽤,但必须填 */ cooling -device = <& gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT >; contribution = <4096 >;/* 计算功耗时乘以4096/1024 倍,⽤于调整降频顺序和尺度 */ }; }; }; /* ⼀个节点对应⼀个thermal zone ,并包含温控策略相关参数,当前thermal zone 只⽤于获取温度 */ gpu_thermal : gpu -thermal { /* 包含温控策略配置的情况下才起作⽤,架要求必须填 */ polling -delay -passive = <100 >; /* milliseconds */ /* 每隔1000ms 获取⼀次温度 */ polling -delay = <1000 >; /* milliseconds */ /* 当前thermal zone 通过tsadc1 获取温度 */ thermal -sensors = <& tsadc 1>; }; }; |
|
|
|
⽤⼾态接口
⽤⼾态接口在/sys/class/thermal/⽬录下,具体内容和DTSI中thermal zone节点的配置对应。有的平台thermalzone节点下只有⼀个⼦节点,对应/sys/class/thermal/⽬录下也只有thermal_zone0⼦⽬录;有的平台有两个⼦节点,对应/sys/class/thermal/⽬录下就会有thermal_zone0和thermal_zone1⼦⽬录。通过⽤⼾态接口可以切换温控策略,查看当前温度等。 以RK3399为例⼦,/sys/class/thermal/thermal_zone0/⽬录下包含如下常⽤的信息: temp /* 当前温度 */ available_policies /* ⽀持的温控策略 */ policy /* 当前使⽤的温控策略 */ sustainable_power /* 期望的最⾼温度下对应的power 值 */ integral_cutoff /* PID 算法中I的触发条件:当前温度-期望的最⾼温度 k_i /* PID 算法中计算I的时候⽤的参数 */ k_po /* PID 算法中计算P的时候⽤的参数 */ k_pu /* PID 算法中计算P的时候⽤的参数 */ mode /* enabled :⾃带定时获取温度,判断是否需要降频。disabled 关闭该功能 */ type /* 当前thermal zone 的类型 */ /* 不同的温度阀值,对应trips 节点的配置 */ trip_point_0_hyst trip_point_0_temp trip_point_0_type trip_point_1_hyst trip_point_1_temp trip_point_1_type trip_point_2_hyst trip_point_2_temp trip_point_2_type /* 不同cooling devic 的状态,对应cooling-maps 节点的配置 */ cdev0 /* 代表⼀个cooling devic ,有的平台还有cdev1 、cdev2 等 */ cur_state /* 该cooling device 当前频率的档位 */ max_state /* 该cooling device 最多有⼏个档位 */ type /* 该cooling device 的类型 */ cdev0_weight /* 该cooling devic 在计算power 时扩⼤的倍数 */ 常用设置 获取当前温度 直接查看⽤⼾态接口thermal_zone0或者thermal_zone1⽬录下的temp节点即可。 以RK3399为例,获取CPU温度,在串口中输⼊如下命令: cat /sys /class /thermal /thermal_zone0 /temp 获取GPU温度,在串口中输⼊如下命令: cat /sys /class /thermal /thermal_zone1 /temp 关闭温度控制功能 ⽅法⼀:menuconfig中默认温控策略设置为user_space。 <*> Generic Thermal sysfs driver ---> --- Generic Thermal sysfs driver APIs to parse thermal data out of device tree Enable writable trip points Default Thermal governor ( user_space ) ---> /* power_allocator 改为user_space */ ⽅法⼆:开机后通过命令关温控。 ⾸先,把温控策略切换到user_space,即把⽤⼾态接口下的policy节点改成user_space;或者把mode设置成 disabled状态;然后,解除频率限制,即将⽤⼾态接口下的所有cdev的cur_state设置为0。 以RK3399为例,策略切换到user_space: echo user_space > /sys /class /thermal /thermal_zone0 /policy 或者把mode设置成disabled状态: echo disabled > /sys /class /thermal /thermal_zone0 /mode 解除频率限制: /* 具体有多少个cdev ,根据实际情况修改 */ echo 0 > /sys /class /thermal /thermal_zone0 /cdev0 /cur_state echo 0 > /sys /class /thermal /thermal_zone0 /cdev1 /cur_state echo 0 > /sys /class /thermal /thermal_zone0 /cdev2 /cur_state |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
基于米尔瑞芯微RK3576核心板/开发板的人脸疲劳检测应用方案
626 浏览 0 评论
887 浏览 1 评论
784 浏览 1 评论
1997 浏览 1 评论
3242 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 20:58 , Processed in 0.444152 second(s), Total 44, Slave 36 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号