【硬件5】vr电源芯片驱动

news2024/11/18 21:29:12

文章目录

  • 1.读MPS5023芯片:0x03ff即将前6位屏蔽
  • 2.读PXE1410CDM电压和电流:一个数&0x7ff,将这个数前5位全变为0,其余位不变
    • 2.1 1ine11:先看第15和10位,e9b6是上面读出的值
    • 2.2 1ine16:PMBUS协议16bit
      • 0x20读出0x14:0x14取反加1就是-12
      • 0x20读出0x17:0x17取反加1后,十进制和十六进制都为9
  • 3. xdpe12284c读电压:https://elixir.bootlin.com/linux/v5.19/source/drivers/hwmon/pmbus/pmbus_core.c#L699,ratio
  • 4.xdpe132g5c调压:
  • 5.读ADS7830的8个channel电压:P5V0即5.0V
  • 6.读INA220电压和电流:Read_INA220_Voltage_Current.sh


1.读MPS5023芯片:0x03ff即将前6位屏蔽

在这里插入图片描述

# Read_FPGA_Power.sh  
#!/bin/bash
stop_ipmistack()
{
    cnt=0
    while true
    do
        /etc/init.d/ipmistack stop >/dev/null  2>&1
        s1=$(ps aux)
        s2="/usr/local/bin/IPMIMain"
        result=$(echo $s1 | grep "${s2}")
        if [[ "$result" == "" ]]
        then
            break
        fi
        if [ $cnt -eq 5 ]
        then
           echo "Unable to stop ipmistack !"
           exit 1
        fi
        cnt=$(($cnt+1))
        sleep 10
    done
}

delete()
{
    cnt=0
    while true
    do
        echo 0x73 > /sys/bus/i2c/devices/i2c-7/delete_device #将bus7上0x73这设备删除
        if [ $? = 0 ]
        then
            break
        fi
        if [ $cnt -eq 5 ]
        then
          echo "Unable to delete device  !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

access()
{
    cnt=0
    while true
    do
        i2c-test -b 7 -s 0x73 -w -d 0x08 >/dev/null 2>&1
        if [ $? = 0 ]
        then
            break
        fi
        if [ $cnt -eq 5 ]
        then
          echo $cnt
          echo "Unable to access 9545 !"
          exit 1
        fi
        cnt=$(($cnt+1))
        echo $cnt
    done
}

OpenChannel()
{
    cnt=0
    while true
    do
        i2c-test -b 7 -s 0x71 -w -d 0x80 >/dev/null 2>&1   #0x80打开channel8
        if [ $? = 0 ]
        then
            break
        fi
        if [ $cnt -eq 5 ]
        then
          echo "Unable to access 9548 channel8 !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

read_voltage(){
    cnt=0
    while true
    do
        val_v=$(i2c-test -b 7 -s 0x40 -m 1 -rc 2 -d 0x8b)
        if [ $? = 0 ]
        then
        hexval_v_h=${val_v:14:2}
        hexval_v_l=${val_v:17:2}
        hexval_v=${hexval_v_l}${hexval_v_h}
        #echo $hexval_v  #0183

        dec_v=$((0x$hexval_v & 0x3ff))  #&:有0为0,3ff:10个1, hex->dec
        #echo $dec_v  #388
        dec_v_wv=$((dec_v*3125))  #31.25mV/LSB
        dec_v_v=$((dec_v_wv/100000))
        #echo $dec_v_v   #12
              break
        fi
        if [ $cnt -eq 5 ]
        then
          echo "Unable to read voltage !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

read_power(){
    cnt=0
    while true
    do
        val_a=$(i2c-test -b 7 -s 0x40 -m 1 -rc 2 -d 0x8c) #电流
        if [ $? = 0 ]
        then
        hexval_a_h=${val_a:14:2}
        hexval_a_l=${val_a:17:2}
        hexval_a=${hexval_a_l}${hexval_a_h}
        #echo $hexval_a  #0054

        dec_a=$((0x$hexval_a & 0x3ff))
        dec_a_wa=$((dec_a*6250))
        dec_a_a=$((dec_a_wa/100000))
		#echo $dec_a_a
        power=$(($dec_v_v * $dec_a_a))
        echo "FPGA Power : "$power"W"
              break
        fi
        if [ $cnt -eq 5 ]
        then
          echo "Unable to read electricity !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

start_ipmistack()
{
    cnt=0
    while true
    do
        /etc/init.d/ipmistack start >/dev/null 2>&1
        s1=$(ps aux)
        s2="/usr/local/bin/IPMIMain"
        result=$(echo $s1 | grep "${s2}")
        if [[ "$result" != "" ]]
        then
            break
        fi
        if [ $cnt -eq 5 ]
        then
          echo "Unable to start ipmistack !"
          exit 1
        fi
        cnt=$(($cnt+1))
		    sleep 10
    done
}

start_ipmistack
stop_ipmistack
delete
access
OpenChannel
read_voltage
read_power
start_ipmistack

在这里插入图片描述

2.读PXE1410CDM电压和电流:一个数&0x7ff,将这个数前5位全变为0,其余位不变

ipmitool raw 0x3a 0x10 <bus id> <slave addr> <Read count> <Data to write> (00:第一个状态码不显示)
在这里插入图片描述

status , log_psu1 = run_command("sudo bash -c 'a=$(ipmitool raw 0x3a 0x10 14 0xb0 2 0x88) ; b=${a:1:2} ; c=${a:4:5} ; d=${c}${b} ; \
    f=`../utility/diag-tools/pmbus_tool/line11 0x$d` ; echo $f'")  #psu1输入电压; 输出电压0x8b,line16
status , log_psu2 = run_command("sudo bash -c 'a=$(ipmitool raw 0x3a 0x10 15 0xb0 2 0x88) ; b=${a:1:2} ; c=${a:4:5} ; d=${c}${b} ; \
    f=`../utility/diag-tools/pmbus_tool/line11 0x$d` ; echo $f'")  #psu2输入电压; 输出电压0x8b,line16
输入电压(mv):
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x60 0x88 w
0xe9b6
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x61 0x88 w
0xe9b5
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x62 0x88 w
0xe9b6
root@gnr5713bb:/var/log/abak# ./line11_arm 0xe9b6
54750

输出电压(mv):
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x60 0x8b w
0xc2ad
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x61 0x8b w
0xc395
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x62 0x8b w
0xc0f8

【VOUT_MODE】:
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x60 0x20
0x14
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x61 0x20
0x14
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x62 0x20
0x14

【输出电压(mv)】:
root@gnr5713bb:/var/log/abak# ./line16_arm 0xc2ad 0x14
12167
root@gnr5713bb:/var/log/abak# ./line16_arm 0xc395 0x14
12223
root@gnr5713bb:/var/log/abak# ./line16_arm 0xc0f8 0x14
12060

2.1 1ine11:先看第15和10位,e9b6是上面读出的值

在这里插入图片描述
如下计算机以补码形式存放负数,0010+1=0011(十进制3)。
在这里插入图片描述
438乘2的-3次方 = 54.8(V)。
在这里插入图片描述

// arm编译器arm-linux-gcc (不是x86的gcc)编译成linear11
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char ** argv)
{
    short exponent;
    int mantissa;
    int val_x;

    mantissa = ((signed short)((strtoul(argv[1],0,0) & 0x7ff) << 5)) >> 5;
    // printf("%x\n",mantissa);
    exponent = ((signed short)strtoul(argv[1],0,0))>>11;
    // printf("%d\n",exponent);
    val_x = mantissa * 1000L;  //v转为mv

    if (exponent >= 0)
        val_x <<= exponent;  // 左移:* 2的exponent次方
    else
        val_x >>= -exponent; // 右移:/ 2的exponent(正)次方  即 * 2的 - exponent(正)次方
   printf("%d\n",val_x);
   return 0;
}

在这里插入图片描述

2.2 1ine16:PMBUS协议16bit

0x20读出0x14:0x14取反加1就是-12

如下十六进制HEX为c2ad(上面读出的值) ,49837乘2的-12次方 = 12.1(A)。
在这里插入图片描述
在这里插入图片描述

0x20读出0x17:0x17取反加1后,十进制和十六进制都为9

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

// linear16
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char ** argv)
{
    short exponent;
    int mantissa;
    int val_x;

    mantissa = (signed short)strtoul(argv[1],0,0);
    exponent = ((signed short)(0x17 << 11)) >> 11 ;

    val_x = mantissa * 1000L;
    if (exponent >= 0)
        val_x <<= exponent;
    else
        val_x >>= -exponent;
   printf("%d\n",val_x);
   return 0;
}
linear16_convert()
{
    mantissa=$(printf %d "$1") # 有符号,也需像linear11_convert一样判断
    if [ $((($2 >> 4) & 0x1)) == 1 ] ; then
        exponent=$(((((($2 << 11)) >> 11)) & 0xf))
        exponent=$(($exponent ^ 0xf))
        exponent=$((~$exponent))
    else
        exponent=$(printf %d "$2")
    fi
    val_x=$((mantissa * 1000))
    if [ $exponent -ge 0 ]; then
        val_x=$(($val_x<<$exponent))
    else
        val_x=$(($val_x>>$((-$exponent))))
    fi
    echo $val_x
}

在这里插入图片描述
在这里插入图片描述

# Read_PXE1410CDM_0X62_Voltage_Current.sh
#!/bin/bash

write_ch0()
{
    cnt=0
    while true
    do
        i2c-test -b 7 -s 0x60 -w -d 0x0 0x00 >/dev/null 2>&1
        if [ $? = 0 ]
        then
            break
		    fi
        if [ $cnt -eq 5 ]
        then
          echo "Unable to write PXE CH0!"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

read_ch0_voltage(){
    cnt=0
    while true
    do
        val_v_0=$(i2c-test -b 7 -s 0x60 -m 1 -rc 2 -d 0x8b)
        if [ $? = 0 ]
        then
        hex_v_h_0=${val_v_0:14:2}
        hex_v_l_0=${val_v_0:17:2}
        hex_v_0=${hex_v_l_0}${hex_v_h_0}
        dec_v_0=$((0x$hex_v_0 & 0xff))
        #echo $dec_v_0
        dec_v_0=$(((500 + (dec_v_0 - 1) * 10)/2))
        echo  "PXE_0x60_0_P0V9_VCCH Voltage : "$dec_v_0"mV"
              break
        fi
        if [ $cnt -eq 5 ]
        then
          echo "Unable to read ch0 voltage !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

read_ch0_current(){
    cnt=0
    while true
    do
        val_a_0=$(i2c-test -b 7 -s 0x60 -m 1 -rc 2 -d 0x8c)
        if [ $? = 0 ]
        then
        hex_a_h_0=${val_a_0:14:2}
        hex_a_l_0=${val_a_0:17:2}
        hex_a_0=${hex_a_l_0}${hex_a_h_0}
        dec_a_0=$(./linear11 0x$hex_a_0)
        echo  "PXE_0x60_0 Current : "$dec_a_0"mA"
              break
        fi
        if [ $cnt -eq 5 ]
        then
          echo "Unable to read ch0 current !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}
start_ipmistack
stop_ipmistack
delete
access
OpenChannel
write_ch0
read_ch0_voltage
read_ch0_current
write_ch1
read_ch1_voltage
read_ch1_current
start_ipmistack

在这里插入图片描述

3. xdpe12284c读电压:https://elixir.bootlin.com/linux/v5.19/source/drivers/hwmon/pmbus/pmbus_core.c#L699,ratio

// linux-aspeed/drivers/hwmon/pmbus/xdpe12284.c
static int xdpe122_identify(struct i2c_client *client,
			    struct pmbus_driver_info *info)
{
	u8 vout_params;
	int i, ret;
	for (i = 0; i < XDPE122_PAGE_NUM; i++) {
		/* Read the register with VOUT scaling value.*/
		ret = pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE); // PMBUS_VOUT_MODE=0x20 , ret=0x21(page01) , ret=0x23(page00默认)
		if (ret < 0)
			return ret;
		vout_params = ret & GENMASK(4, 0);  // 0010 0011  &  0001 1111 = 0000 0011 (0x03)
		switch (vout_params) {
		case XDPE122_PROT_VR12_5_10MV:  // 0x02
			info->vrm_version[i] = vr13;
			break;
		case XDPE122_PROT_VR12_5MV:  // 0x01
			info->vrm_version[i] = vr12;
			break;
		case XDPE122_PROT_IMVP9_10MV:  // 0x03 //
			info->vrm_version[i] = imvp9;
			break;
		case XDPE122_AMD_625MV:  // 0x10
			info->vrm_version[i] = amd625mv;
			break;
		default:
			return -EINVAL;
		}
	}
	return 0;
}

在这里插入图片描述

// linux-aspeed/drivers/hwmon/pmbus/pmbus_core.c
static long pmbus_reg2data_vid(struct pmbus_data *data,
			       struct pmbus_sensor *sensor)
{
	long val = sensor->data;
	long rv = 0;

	switch (data->info->vrm_version[sensor->page]) {
	case vr11:
		if (val >= 0x02 && val <= 0xb2)
			rv = DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100);
		break;
	case vr12:
		if (val >= 0x01)
			rv = 250 + (val - 1) * 5;
		break;
	case vr13:
		if (val >= 0x01)
			rv = 500 + (val - 1) * 10;
		break;
	case imvp9:
		if (val >= 0x01)
			rv = 200 + (val - 1) * 10;  // val就是0x8b读出的值,10就是10mv步进
		break;
	case amd625mv:
		if (val >= 0x0 && val <= 0xd8)
			rv = DIV_ROUND_CLOSEST(155000 - val * 625, 100);
		break;
	}
	return rv;
}

4.xdpe132g5c调压:

如下在switch芯片手册中,查找到AVS值需要经过intel VR11.1协议进行转换。
在这里插入图片描述
如下在intel VRM11.1协议说明手册中通过Vcc_Max一列看出步长为6.25mv。Hex一列代表switch芯片传入basecpld的初始值,Hex为00的Vcc_Max的值为1.6+0.00625*2=1.6125(V),通过i2cget -f -y 0 0x0d 0x10从basecpld的10寄存器读取switch芯片传入的初始值为0x7a,所以Hex为7a的Vcc_Max值 = 1.6125 -(0.00625*122)= 0.85(V),所以0.85V为最终的XDPE132g芯片的调压显示结果值。
在这里插入图片描述
但是XDPE132g芯片内部有调压逻辑如下,所以不能将0.85直接设置进XDPE132g芯片寄存器中,厂商邮件如下:
在这里插入图片描述
通过i2cget -f -y 29 0x40 0x20命令读出XDPE132g芯片的20寄存器为0x14对应如上0.244mv step,上图第三步1000 (mv) / 1.953 = 512即0x0200(相当于3484),所以850 (mv) / 0.244 = 3484,将3484设置进21寄存器(需要先切换page),再通过8b寄存器读出对比设置进21寄存器的值是否一致。
在这里插入图片描述
关闭dcdc监控后,可以看出XDPE132g芯片的8b和21寄存器的值是一样的。
在这里插入图片描述

// cat /sys/bus/i2c/devices/i2c-29/29-0040/hwmon/hwmon20/in2_input节点后
// linux-aspeed/drivers/hwmon/pmbus/pmbus_core.c
static ssize_t pmbus_show_sensor(struct device *dev,
				 struct device_attribute *devattr, char *buf)
{
	struct pmbus_data *data = pmbus_update_device(dev);
	struct pmbus_sensor *sensor = to_pmbus_sensor(devattr);

	if (sensor->data < 0)
		return sensor->data;
	if (sensor->data == 0xffff)
		return 0;
	printk(KERN_INFO "pmbus_show_sensor, %d, %d\n", sensor->data, pmbus_reg2data(data, sensor)); /// 3282, 801
	return snprintf(buf, PAGE_SIZE, "%ld\n", pmbus_reg2data(data, sensor));
}

static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor)
{
	long val;
	switch (data->info->format[sensor->class]) {
	case direct:
		val = pmbus_reg2data_direct(data, sensor);
		break;
	case vid:
		val = pmbus_reg2data_vid(data, sensor);
		break;
	case linear:
		printk(KERN_INFO "pmbus_reg2datalinear\n"); // 会打印出
	default:
		printk(KERN_INFO "pmbus_reg2datadefault, %d, %d\n", sensor->page, sensor->reg); // 0 , 139 (8b)
		val = pmbus_reg2data_linear(data, sensor);
		break;
	}
	return val;
}

static long pmbus_reg2data_linear(struct pmbus_data *data,
				  struct pmbus_sensor *sensor)
{
	s16 exponent;
	s32 mantissa;
	long val;
	printk(KERN_INFO "pmbus_reg2datad_data, %d\n", sensor->data);   // 3282
	if (sensor->class == PSC_VOLTAGE_OUT) {	/* LINEAR16 */
		exponent = data->exponent[sensor->page];
		mantissa = (u16) sensor->data;
	} else {				/* LINEAR11 */
		exponent = ((s16)sensor->data) >> 11;
		mantissa = ((s16)((sensor->data & 0x7ff) << 5)) >> 5;
	}

	val = mantissa;

	/* scale result to milli-units for all sensors except fans */
	if (sensor->class != PSC_FAN)
		val = val * 1000L;

	/* scale result to micro-units for power sensors */
	if (sensor->class == PSC_POWER)
		val = val * 1000L;

	if (exponent >= 0)
		val <<= exponent;
	else
		val >>= -exponent;
	printk(KERN_INFO "pmbus_reg2data_val, %d\n", val);   // 801
	return val;
}

5.读ADS7830的8个channel电压:P5V0即5.0V

在这里插入图片描述
如下CH0:1000 1100为六进制0x8c,十进制140。从SD=1往下看,SD=0不用看。CH1中C2 C1 C0为1 0 0即0xcc即204。
在这里插入图片描述
cmd | (((ch >> 1) | (ch & 0x01) << 2) << 4); cmd =0x8c。
在这里插入图片描述
如下CH7竖着多出了一条。
在这里插入图片描述
在这里插入图片描述
i2c-test -b 7 -s 0x48 -rc 1 -d 0x8c #显示0x57即十进制87。如下x=87*9766,divisor=1000。

#define DIV_ROUND_CLOSEST(x, divisor)({   //C文件                                                       
        typeof(x) __x = x;                                
        typeof(divisor) __d = divisor;                       
        (((typeof(x))-1) > 0 ||                               
         ((typeof(divisor))-1) > 0 ||                       
         (((__x) > 0) == ((__d) > 0))) ?                 
                (((__x) + ((__d) / 2)) / (__d)) :         
                (((__x) - ((__d) / 2)) / (__d));         
})
# Read_ADS7830_0x48_Voltage.sh
#!/bin/bash
DIV_ROUND_CLOSEST(){
    __x=$1
    __d=$2
    A=$(((__x) > 0))
    B=$(((__d) > 0))

    C=$(($__d>>1))
    C=$(($__x+$C))
    C=$(($C/$__d))
    
    D=$(($__d>>1))
    D=$(($__x+$D))
    D=$(($D/$__d))

    E=$(($A==$B))
    echo $(($E?$C:$D))
}

OpenChannel()
{
    cnt=0
    while true
    do
        i2c-test -b 7 -s 0x71 -w -d 0x04 >/dev/null 2>&1
        if [ $? = 0 ]
        then
            break
		    fi

        if [ $cnt -eq 5 ]
        then
          echo "Unable to access 9548 channel 3 !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

read_channel0(){
    cnt=0
    while true
    do
        val_0=$(i2c-test -b 7 -s 0x48 -rc 1 -d 0x8c)  # channel1 :不是0x8c,是0xcc(204).....
        if [ $? = 0 ]
        then
        #echo $val_0
        hex_0=${val_0:34:2}
        #echo $hex_0  #57

        dec_0=$((0x$hex_0 & 0xff)) #转为十进制
        #echo $dec_0   #87
        dec_v_0=$((dec_0*9766))
        dec_v_v_0=$(DIV_ROUND_CLOSEST $dec_v_0 1000)
        echo "ADS7830 CH0:PFM8_VCC Voltage : "$dec_v_v_0"mV"
              break
        fi

        if [ $cnt -eq 5 ]
        then
          echo "Unable to read channel0 voltage !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

read_channel7(){
    cnt=0
    while true
    do
        val_7=$(i2c-test -b 7 -s 0x48 -rc 1 -d 0xfc)
        if [ $? = 0 ]
        then
        #echo $val_7
        hex_7=${val_7:34:2}
        #echo $hex_7   #57

        dec_7=$((0x$hex_7 & 0xff))
        #echo $dec_7  #

        dec_v_7=$((dec_7*9766))
        dec_v_v_7=$(($(DIV_ROUND_CLOSEST $dec_v_7 1000)*2))  # 多出一条
        echo "ADS7830 CH7:P3V3_EARLY Voltage : "$dec_v_v_7"mV"
              break
        fi

        if [ $cnt -eq 5 ]
        then
          echo "Unable to read channel7 voltage !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

start_ipmistack
stop_ipmistack
delete
access
OpenChannel
read_channel0
...
read_channel7
start_ipmistack

在这里插入图片描述
在这里插入图片描述

# Read_ADS7830_0X49_Voltage.sh
#!/bin/bash

read_channel0(){
    cnt=0
    while true
    do
        val_0=$(i2c-test -b 7 -s 0x49 -rc 1 -d 0x8c)
        if [ $? = 0 ]
        then
        #echo $val_0

        hex_0=${val_0:34:2}
        #echo $hex_0  #57

        dec_0=$((0x$hex_0 & 0xff))
        #echo $dec_0   #87

        dec_v_0=$((dec_0*9766))
        dec_v_v_0=$(($(DIV_ROUND_CLOSEST $dec_v_0 1000)*2))
        echo "ADS7830 CH0:P2V5_VPP_CH01 Voltage : "$dec_v_v_0"mV"
              break
        fi

        if [ $cnt -eq 5 ]
        then
          echo "Unable to read channel0 voltage !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

read_channel6(){
    cnt=0
    while true
    do
        val_6=$(i2c-test -b 7 -s 0x49 -rc 1 -d 0xbc)
        if [ $? = 0 ]
        then
        #echo 6
        hex_6=${val_6:34:2}
        #echo $hex_6  #57

        dec_6=$((0x$hex_6 & 0xff))
        #echo $dec_6  #

        dec_v_6=$((dec_6*9766))
        dec_v_v_6=$(($(DIV_ROUND_CLOSEST $dec_v_6 1000)*349/100))
        echo "ADS7830 CH6:P5V0 Voltage : "$dec_v_v_6"mV"
              break
        fi

        if [ $cnt -eq 5 ]
        then
          echo "Unable to read channel6 voltage !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

read_channel7(){
    cnt=0
    while true
    do
        val_7=$(i2c-test -b 7 -s 0x49 -rc 1 -d 0xfc)
        if [ $? = 0 ]
        then
        #echo $val_7
        hex_7=${val_7:34:2}
        #echo $hex_7   #57

        dec_7=$((0x$hex_7 & 0xff))
        #echo $dec_7  #

        dec_v_7=$((dec_7*9766))
        dec_v_v_7=$(($(DIV_ROUND_CLOSEST $dec_v_7 1000)*57/10))
        echo "ADS7830 CH7:P12V Voltage : "$dec_v_v_7"mV"
              break
        fi

        if [ $cnt -eq 5 ]
        then
          echo "Unable to read channel7 voltage !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

start_ipmistack
stop_ipmistack
delete
access
OpenChannel
read_channel0
...
read_channel6
read_channel7
start_ipmistack

在这里插入图片描述

6.读INA220电压和电流:Read_INA220_Voltage_Current.sh

在这里插入图片描述

#!/bin/bash

delete()
{
    cnt=0
    while true
    do
        echo 0x73 > /sys/bus/i2c/devices/i2c-3/delete_device
        if [ $? = 0 ]
        then
            break
		    fi
        if [ $cnt -eq 5 ]
        then
          echo "Unable to delete device  !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

OpenChannel()
{
    cnt=0
    while true
    do
        i2c-test -b 3 -s 0x71 -w -d 0x02 >/dev/null 2>&1
        if [ $? = 0 ]
        then
            break
		    fi
        if [ $cnt -eq 5 ]
        then
          echo "Unable to access 9548 channel2 !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

read_voltage(){
    cnt=0
    while true
    do
        val_v=$(i2c-test -b 3 -s 0x41 -m 1 -rc 2 -d 0x02)
        if [ $? = 0 ]
        then
        #echo $val_v  #08 aa
        hexval_v_h=${val_v:14:2}
        hexval_v_l=${val_v:17:2}
        hexval_v=${hexval_v_h}${hexval_v_l}
        dec_v_v=$((0x$hexval_v>>3))
        dec_v_v=$(($dec_v_v<<2))
        echo "INA220 Voltage : "$dec_v_v"mV"
              break
        fi
        if [ $cnt -eq 5 ]
        then
          echo "Unable to read INA220 voltage !"
          exit 1
        fi
        cnt=$(($cnt+1))
    done
}

DIV_ROUND_CLOSEST(){
    if [ $# -ne 2 ]
    then
    echo 0
    else
    __x=$1
    __d=$2
    A=$(((__x) > 0))
    B=$(((__d) > 0))
    C=$(($__d>>1))
    C=$(($__x+$C))
    C=$(($C/$__d))
    D=$(($__d>>1))
    D=$(($__x+$D))
    D=$(($D/$__d))
    E=$(($A==$B))
    echo $(($E?$C:$D))
    fi
}

Read_Reg()
{
    val=$(i2c-test -b 3 -s 0x41 -m 1 -rc 2 -d $1)
    val_h=${val:14:2}
    val_l=${val:17:2}
    val=${val_h}${val_l}
    echo $val
}

start_ipmistack()
{
    cnt=0
    while true
    do
        /etc/init.d/ipmistack start >/dev/null 2>&1
        s1=$(ps aux)
        s2="/usr/local/bin/IPMIMain"
        result=$(echo $s1 | grep "${s2}")
        if [[ "$result" != "" ]]
        then
            break
        fi
        if [ $cnt -eq 5 ]
        then
          echo "Unable to start ipmistack !"
          exit 1
        fi
        cnt=$(($cnt+1))
		    sleep 10
    done
}

start_ipmistack
stop_ipmistack
delete
access
OpenChannel
read_voltage

i2c-test -b 3 -s 0x41 -w -d 0x05 0x03 0x7f >/dev/null 2>&1  #0x37f上面的校正值
config_shunt_div=100
dividend=$(DIV_ROUND_CLOSEST 1000000000 $config_shunt_div)
shunt_val=$(Read_Reg 0x01)

current_lsb_uA=$(DIV_ROUND_CLOSEST $dividend 0x$shunt_val)
current_val=$(Read_Reg 0x04)
ret=$((0x$current_val * $current_lsb_uA))
ret=$(DIV_ROUND_CLOSEST $ret 1000)
echo "INA220 Current : "$ret"mA"
start_ipmistack

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/681654.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python空循环:提高代码效率的神器

Python空循环&#xff1a;提高代码效率的神器 Python作为一门高效、易学的编程语言&#xff0c;广泛应用于各行各业。在编写Python代码时&#xff0c;循环结构是经常使用的。但是&#xff0c;有时候我们需要使用循环结构&#xff0c;但并不需要执行任何操作。这时候&#xff0…

chatgpt赋能python:Python中的空格:一种重要的编程元素

Python中的空格&#xff1a;一种重要的编程元素 在Python编程中&#xff0c;空格是被广泛使用的重要元素之一。本文将介绍Python中空格的重要性&#xff0c;并探讨空格在编程中的不同应用。 为什么空格在Python编程中如此重要&#xff1f; Python对空格敏感&#xff0c;意味…

CVPR2023 多目标跟踪(MOT)汇总

一、《OVTrack: Open-Vocabulary Multiple Object Tracking》 作者:Siyuan Li* Tobias Fischer* Lei Ke Henghui Ding Martin Danelljan Fisher Yu Computer Vision Lab, ETH Zurich 论文链接 &#xff1a;https://openaccess.thecvf.com/content/CVPR2023/papers/Li_OVTrack…

[Selenium] 通过Java+Selenium查询某个博主的Top40文章质量分

系列文章目录 通过JavaSelenium查询文章质量分 通过JavaSelenium查询某个博主的Top40文章质量分 文章目录 系列文章目录前言一、环境准备二、查询某个博主的Top40文章2.1、修改pom.xml配置2.2、配置Chrome驱动2.3、引入浏览器配置2.4、设置无头模式2.5、启动浏览器实例&#x…

【瑞萨RA_FSP】WiFi——ESP8266模块通讯

文章目录 一、Wifi模块简介二、ESP8266功能介绍1. 通用输入/输出接口&#xff08;GPIO&#xff09;2. 使用UART与WIFI通讯3. ESP8266工作模式介绍 三、AT指令四、实验&#xff1a;STA模式测试1. 文件结构2. 宏定义函数3. ESP8266-STA功能函数4. 中断回调函数5. hal_entry入口函…

chatgpt赋能python:Python中的空值

Python中的空值 在Python编程中&#xff0c;空值指的是没有任何值的对象。在其他编程语言中&#xff0c;空值常常被称为null、nil、None或者undefined。Python中的空值用None关键字表示。 None 在Python语言中&#xff0c;None用于表示没有任何值。当用户要定义一个值却不想…

chatgpt赋能python:Python组合框(Combobox)介绍

Python组合框&#xff08;Combobox&#xff09;介绍 Python组合框&#xff08;Combobox&#xff09;是GUI编程中常用的一个组件&#xff0c;它可以让你在一个下拉框中选择一个或多个选项。Python组合框的特点是可以让用户自定义选项&#xff0c;也可以在选项中加入数据&#x…

红黑树-迭代器实现

目录 迭代器自增 当前结点存在右子树 当前结点没有存在右子树 迭代器自增完整代码 迭代器自减 迭代器自减代码&#xff1a; 迭代器自增 红黑树的迭代器应该怎么实现呢&#xff1f;现在我模仿大佬的实现逻辑。 我们迭代器最重要是可以允许自增与自减的实现的。 会发现我们…

chatgpt赋能python:Python程序运行速度问题

Python程序运行速度问题 Python是一种高级语言&#xff0c;其语法简洁、易于学习&#xff0c;在科学计算、数据分析、web开发等领域有着广泛的应用。然而&#xff0c;Python程序在运行速度方面却存在一定的瓶颈&#xff0c;这也是许多开发者关注的问题。本文将从多个方面探讨影…

【深度学习笔记】二分类问题与 Logistic 回归

本专栏是网易云课堂人工智能课程《神经网络与深度学习》的学习笔记&#xff0c;视频由网易云课堂与 deeplearning.ai 联合出品&#xff0c;主讲人是吴恩达 Andrew Ng 教授。刚兴趣的网友可以观看网易云课堂的视频进行深入学习&#xff0c;视频的链接如下&#xff1a; https://m…

chatgpt赋能python:Python等待一秒:介绍和用法全解析

Python等待一秒&#xff1a;介绍和用法全解析 什么是Python等待一秒&#xff1f; 在编写Python脚本时&#xff0c;我们通常要让程序暂停一段时间&#xff0c;这可以通过让程序等待一定的时间来实现。等待时间可以是任意长度的时间&#xff0c;最常见的时间单位是秒。Python中…

chatgpt赋能python:三种常见的Python程序错误及解决方案

三种常见的Python程序错误及解决方案 Python是一种高级编程语言&#xff0c;具有易读、易学、易维护等特点&#xff0c;被广泛应用于Web开发、数据分析、人工智能等领域。但是&#xff0c;即使是有10年Python编程经验的工程师也难免会犯错误。这篇文章将介绍Python程序中的三种…

Unity3D:添加设备

Unity3D&#xff1a;添加设备 推荐&#xff1a;将NSDT场景编辑器加入你的3D工具链 3D工具集&#xff1a;NSDT简石数字孪生 添加设备 若要将新设备添加到设备模拟器&#xff0c;请创建设备定义和设备覆盖。 设备定义是 Unity 项目中扩展名的文本文件。它包含描述设备属性的 …

数据结构第六章 图 6.4 图的应用 错题整理

4.A A. 不是简单路径的话&#xff0c;有环&#xff0c;去环路径会更短 B. 适合的 弗洛伊德算法才不适合 C. 本来就是 D 2X2矩阵拓展到3X3矩阵 再扩大 若是子集 即加入新顶点后&#xff0c;最短路径都没有变&#xff0c;错 5.B 本题用弗洛伊德更合适 但这道题只需全部代入求最…

chatgpt赋能python:Python简单计算器代码

Python简单计算器代码 Python是一种高级的编程语言&#xff0c;被广泛用于开发各种类型的应用程序&#xff0c;包括计算器应用程序。在本文中&#xff0c;我们将介绍Python简单计算器代码的实现和用法。 Python简单计算器代码介绍 一个简单的计算器能够实现基本的算术运算&a…

回溯注意点:回溯时间复杂度的计算与剪枝操作

文章目录 回溯的时间复杂度计算示例1&#xff1a;77.组合示例2&#xff1a;216.组合总和Ⅲ示例3&#xff1a;17.电话号码字母组合关于剪枝对时间复杂度的影响 回溯的剪枝操作必要性及适用场景示例1&#xff1a;组合剪枝剪枝优化点&#xff1a; 示例2&#xff1a;组合剪枝剪枝优…

STL容器(持续更新中)

一、string类 1. 构造函数 常用的构造函数如下。 构造函数原型含义string()默认构造函数。创建一个默认string对象&#xff0c;长度为0string(const string &s)拷贝构造函数。用一个string对象初始化另一个string对象string(const char *s)用字符串常量构建string对象st…

Linux系统编程(vfork和fork)

文章目录 前言一、vfork讲解二、vfork使用三、exit和_exit1.exit和_exit对比2.在vfork中的使用 四、vfork和fork区别总结 前言 本篇文章讲解vfork和fork创建进程的区别。 一、vfork讲解 vfork 是一个在类Unix操作系统中的系统调用&#xff0c;它创建一个新进程&#xff0c;且…

欠拟合、过拟合、正则化、学习曲线

1.欠拟合、过拟合、正则化、学习曲线 1.1 欠拟合、过拟合 欠拟合&#xff1a;模型相对于要解决的问题来说太简单了&#xff0c;模型并没有拟合训练数据的状态 过拟合&#xff1a;模型相对于要解决的问题来说太复杂了&#xff0c;模型只能拟合训练数据的状态 下图来自&#x…

第41步 深度学习图像识别:Efficientnet建模(Tensorflow)

一、写在前面 &#xff08;1&#xff09;Efficientnet EfficientNet是Google在2019年提出的一种新的卷积神经网络架构&#xff0c;主要目标是提高模型的效率&#xff0c;即在保持或提高模型性能的同时&#xff0c;尽可能地降低模型的复杂性和计算需求。 EfficientNet的关键思…