2023年12月13日发(作者:)

c语言查看cpu温度代码_C语言获取CPU核心温度

获取Intel CPU 信息和温度

CPU信息可以通过cpuid指令获取,在用户空间可以通过内嵌汇编代码实现,代码如下:

struct cpuid_res {

uint32_t eax;

uint32_t ebx;

uint32_t ecx;

uint32_t edx;

};

static inline struct cpuid_res cpuid(int op)

{

struct cpuid_res result;

asm volatile(

"mov %%ebx, %%edi;"

"cpuid;"

"mov %%ebx, %%esi;"

"mov %%edi, %%ebx;"

: "=a" (),

"=S" (),

"=c" (),

"=d" ()

: "0" (op)

: "edi");

return result;

}

获取CPU厂家名称

以eax=0 执行 cpuid,eax为0表示读取vendor id,一共12字节,依次在ebx、edx、ecx

result = cpuid(0);

vendor_name[0] = ( >> 0) & 0xff;

vendor_name[1] = ( >> 8) & 0xff;

...

vendor_name[11] = ( >> 24) & 0xff;

获取CPU型号用cpuid指令,eax传入分别0x80000002/0x80000003/0x80000004,读取cpu型号,每个4个寄存器,每个寄存器4字节,一共48

字节

struct cpuid_res res;

char processor_name[49];

unsigned int *cpu_type = (unsigned int *)processor_name;

for (int i = 0; i < 3; i++) {

res = cpuid(0x80000002 + i);

cpu_type[i * 4 + 0] = ;

cpu_type[i * 4 + 1] = ;

cpu_type[i * 4 + 2] = ;

cpu_type[i * 4 + 3] = ;

}

获取CPU温度

Intel和AMD的CPU中都有温度传感器(DTS),每个核心都有一个,温度就是由此获取来的。Intel对CPU温度的处理,设置了一个最高温度

Tjunction,从MSR中读取的数据为与最高温度的温差Delta,并非实际温度,实际温度为Tjunction-Delta。

检查CPU是否支持DTS

先以eax=0 执行 cpuid 检测 eax 支持的最大命令数,如果小于6就肯定不支持DTS

int level = cpuid(0).eax;

以eax=6 执行 cpuid, 然后测试 eax 第一位是否为1,如果为1表示CPU支持DTS

int val = cpuid(6).eax;

char dts = (val>>0)&0x01;

读取DTS

要获取cpu的温度可以通过汇编指令来读取。但linux环境下,msr指令必须要在内核层才能调用,这里我在驱动中中实现ioctl接口,然后返

回数据给用户层

uint32_t lo, hi;

asm volatile(

"rdmsr"

: "=a" (lo), "=d" (hi)

: "c" (op)

);

Tjunction:当核心温度达到了阀值,会通过降频、降压、风扇调节等形式调节温度

以 ecx=0x1A2 执行 rdmsr 指令,通过0x1A2来读取MSR的[16-22]位得到Tjunction

u64 __val = __rdmsr(0x1A2);//

Delta:我们从MSR读到的温度是距离Tjunction的温差,而不是实际温度

以 ecx=0x19C 执行 rdmsr 指令,通过0x19C来读取MSR的[16-22]位得到Deltau64 __val2 = __rdmsr(0x19C);

当前cpu温度 = Tjunction – Delta

核心代码如下:

u64 __val = __rdmsr(0x1A2);

printk("__val is %016llxn",__val);

u64 __val2 = __rdmsr(0x19C);

printk("__val2 is %016llxn",__val2);

u8 tjunction,delta,coretemp;

tjunction = (__val>>16)&0x7f;

delta = (__val2>>16)&0x7f;

coretemp = tjunction - delta;

printk("tjunction is %.1d°C ;delta is %.1d°C;core temp is %.1d°Cn", tjunction, delta, coretemp);

char buf_temp[30] = "CPU温度:";

char core_temp[4];

sprintf(core_temp, "%d", coretemp);

strcat(buf_temp,core_temp);

copy_to_user((char __user *)arg, buf_temp, strlen(buf_temp));

测试结果:

cpu 温度

通过对比sensors,这里获取的是CPU Core 1的温度,Core 0的温度可以通过多线程绑定核心运行来获得到