美文网首页js css html
Linux内核Thermal Sensor

Linux内核Thermal Sensor

作者: 小田BSP | 来源:发表于2022-12-17 21:34 被阅读0次

    Linux内核中,可用Thermal Sensor(如:RK3399 TS-ADC(Temperature-Sensor ADC))获取温度。

    本文介绍RK3399 TS-ADC控制器驱动和调试方法。

    一、TSADC驱动

    1、TS-ADC控制器

    RK3399 TS-ADC(Temperature-Sensor ADC)控制器模块支持用户自定义模式和自动模式。

    1)用户自定义模式

    TS-ADC所有的控制信号完全由软件写入寄存器直接控制。

    2)自动模式

    模块自动轮询TS-ADC输出并检查结果。

    如果在一段时间内发现温度过高,会产生一个停机措施的中断;如果温度超过一段时间高,生成TSHUTCRU(Clock & Reset Unit)模块,让他复位整个芯片,或者通过GPIOPMIC

    RK3399 TSADC控制器特性如下:

    1)、支持用户自定义模式和自动模式。

    2)、在用户自定义模式下,start_of_conversion可以完全由软件控制,也可以由硬件生成。

    3)、在自动模式下,可配置报警(高温/低温)中断的温度。

    4)、在自动模式下,可配置系统复位的温度。

    5)、支持2通道TS-ADC,每个通道的温度标准可配置。

    6)、在自动模式下,可配置温度检测的时间间隔。

    7)、在自动模式下,当检测到高温时,可配置温度检测的时间间隔。

    8)、可配置高温防抖。

    9)、温度范围:-40 ~ 125°C,温度精度:5°C

    10)、10bit SARADC,采样率50KS/s

    注:1KS/s = 1KHz,即每秒采样1000个点。

    RK3399 TS-ADC控制器框图如下:

    image.png
    2、TS-ADC配置

    RK3399 TS-ADC配置文件:

    1)arch/arm64/boot/dts/rockchip/rk3399.dtsi

    TS-ADC属性配置如下:

    tsadc: tsadc@ff260000 {
            compatible = "rockchip,rk3399-tsadc"; ## TS-ADC驱动加载的标志字符串
            reg = <0x0 0xff260000 0x0 0x100>;     ## TS-ADC寄存器基地址和寄存器地址长度
            interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH 0>; ## TS-ADC中断
            assigned-clocks = <&cru SCLK_TSADC>;  
            assigned-clock-rates = <750000>;     ## TS-ADC工作时钟为750000
            clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; 
            clock-names = "tsadc", "apb_pclk";  ## TS-ADC模块的两个时钟:工作时钟和配置时钟
            resets = <&cru SRST_TSADC>;
            reset-names = "tsadc-apb";
            rockchip,grf = <&grf>;              ## TS-ADC引用grf模块
            rockchip,hw-tshut-temp = <120000>;  ## TS-ADC设置的关机温度120度
            pinctrl-names = "init", "default", "sleep"; ## TS-ADC工作的GPIO配置,初始化init和休眠sleep时gpio,默认                                                      ## default是输出功能。
            pinctrl-0 = <&otp_gpio>;
            pinctrl-1 = <&otp_out>;
            pinctrl-2 = <&otp_gpio>;
            #thermal-sensor-cells = <1>;
            status = "disabled";
    };
    

    TS-ADC引脚配置如下:

    tsadc {
            otp_gpio: otp-gpio {
                    rockchip,pins = <1 6 RK_FUNC_GPIO &pcfg_pull_none>;
            };
    
            otp_out: otp-out {
                    rockchip,pins = <1 6 RK_FUNC_1 &pcfg_pull_none>;
            };
    };
    

    2)arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi

    使能TS-ADC配置如下:

    &tsadc {
            /* tshut mode 0:CRU 1:GPIO */
            rockchip,hw-tshut-mode = <1>;      ## 温度超过关机温度的复位方式:0:通过CRU模块复位;1:通过GPIO连接PMIC复位                                           ## 引脚进行复位。
            /* tshut polarity 0:LOW 1:HIGH */
            rockchip,hw-tshut-polarity = <1>;  ## 关机极性:0:低;1:高
            rockchip,hw-tshut-temp = <110000>; ## 关机温度:110度
            status = "okay";        ## 使能TS-ADC驱动
    };
    

    3、TS-ADC驱动

    RK3399 TS-ADC驱动文件:drivers/thermal/rockchip_thermal.c,主要关注:

    static const struct rockchip_tsadc_chip rk3399_tsadc_data = {
        .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */   ## TS-ADC通道0监控CPU温度
        .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */   ## TS-ADC通道1监控GPU温度
        .chn_num = 2, /* two channels for tsadc */               ## TS-ADC通道个数
    
        .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ ## TS-ADC关机模式(GPIO)
        .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */    ## TS-ADC关机极性(低有效)
        .tshut_temp = 95000,                                                  ## TS-ADC关机温度(95)
        ## 如果dts中没有配置上面三个属性,则使用上面三个默认值,否则使用dts中的值。
    
        .initialize = rk_tsadcv3_initialize,     ## 初始化TS-ADC控制器
        .irq_ack = rk_tsadcv3_irq_ack,
        .control = rk_tsadcv3_control,           ## 使能和禁止TS-ADC控制器
        .get_temp = rk_tsadcv2_get_temp,         ## 获取温度 
        .set_alarm_temp = rk_tsadcv2_alarm_temp, ## 设置报警温度并使能对应中断
        .set_tshut_temp = rk_tsadcv2_tshut_temp, ## 设置关机温度并使能对应中断
        .set_tshut_mode = rk_tsadcv2_tshut_mode, ## 设置关机模式
    
        .table = {
            .id = rk3399_code_table,
            .length = ARRAY_SIZE(rk3399_code_table),
            .data_mask = TSADCV3_DATA_MASK,
            .mode = ADC_INCREMENT,
        },
    };
    
    ##注册thermal sensor设备驱动实现函数
    static const struct thermal_zone_of_device_ops rockchip_of_thermal_ops = {
        .get_temp = rockchip_thermal_get_temp,   ## 获取温度,调用rk_tsadcv2_get_temp()
        .set_trips = rockchip_thermal_set_trips, ## 设置报警温度,调用rk_tsadcv2_alarm_temp()
    };
    

    二、TS-ADC调试

    下面基于RockPI 4A单板查看RK3399 CPU和GPU的温度,方法如下:

    ## CPU温度
    root@xiaotianbsp:/# cat /sys/class/thermal/thermal_zone0/temp
    36875
    ## GPU温度
    root@xiaotianbsp:/# cat /sys/class/thermal/thermal_zone1/temp
    38750
    

    可以使用watch命令,动态监控CPUGPU温度,方法如下:

    ## 每隔1秒显示一次CPU温度
    root@xiaotianbsp:/# watch -n 1 cat /sys/class/thermal/thermal_zone0/temp
    Every 1.0s: cat /sys/class/thermal/the...  linaro-alip: Mon Aug 16 14:46:38 2021
    
    36875
    
    ## 每隔1秒显示一次GPU温度
    root@xiaotianbsp:/# watch -n 1 cat /sys/class/thermal/thermal_zone1/temp
    Every 1.0s: cat /sys/class/thermal/the...  linaro-alip: Mon Aug 16 14:48:41 2021
    
    38750
    

    注:转载请注明作者。

    相关文章

      网友评论

        本文标题:Linux内核Thermal Sensor

        本文链接:https://www.haomeiwen.com/subject/nbljqdtx.html