diff --git a/02.nicsensor/nicsensor.sh b/02.nicsensor/nicsensor.sh new file mode 100644 index 0000000..19694f3 --- /dev/null +++ b/02.nicsensor/nicsensor.sh @@ -0,0 +1,645 @@ +#!/bin/sh + +# script Version 1.0 20240614 +# 支持测试的传感器芯片 emc1413 ina3221 adc128 + +# --------------------------------------------------------- +# Project Feature Varible (按照项目需要修改) +# --------------------------------------------------------- + +# ADC128 分压系数 (Ravel) +votage_division_factor_0="1" +votage_division_factor_1="1" +votage_division_factor_2="1" +votage_division_factor_3="0.8" +votage_division_factor_4="0.6" +votage_division_factor_5="0.6" +votage_division_factor_6="0.2326" +votage_division_factor_7="1" + +# INA3221 分流电阻, 单位(毫欧姆)(Ravel) +shunt_resistor_0="2" +shunt_resistor_1="2" +shunt_resistor_2="5" + +# fru 烧录的起始地址 +fru_offset="0x00 0x00" + +# --------------------------------------------------------- +# Common Varible (请勿随意修改) +# --------------------------------------------------------- +# Input Param +pcie_slot=$1 +sensor_type=$2 +chip_slave=$3 + +# Introduction of option_data +# 1.在FRU的处理过程中,使用option_data来区分是读操作还是写操作,将值设置为 +# "read"或者"write" +# 2.在CPLD的处理过程中,使用option_data来代表一条完整的i2c命令,这条命令会 +# 被发到CPLD上,一个例子:"i2ctransfer -y 12 w2@0x10 0x90 0x00 r9" +option_data=$4 + +# CHIP REGISTER +REG_pca9641_controll="0x01" + +REG_adc128_config="0x00" +REG_adc128_advance="0x0b" +REG_adc128_status="0x0c" +REG_adc128_ch0="0x20" +REG_adc128_ch1="0x21" +REG_adc128_ch2="0x22" +REG_adc128_ch3="0x23" +REG_adc128_ch4="0x24" +REG_adc128_ch5="0x25" +REG_adc128_ch6="0x26" +REG_adc128_ch7="0x27" + +REG_emc1413_TD1_H="0x00" +REG_emc1413_TD1_L="0x29" +REG_emc1413_TD2_H="0x01" +REG_emc1413_TD2_L="0x10" +REG_emc1413_TD3_H="0x23" +REG_emc1413_TD3_L="0x24" + +REG_ina3221_ch1="0x01" +REG_ina3221_ch2="0x03" +REG_ina3221_ch3="0x05" +REG_ina3221_bus1="0x02" +REG_ina3221_bus2="0x04" +REG_ina3221_bus3="0x06" + +# --------------------------------------------------------- +# Global Varible (请勿随意修改) +# --------------------------------------------------------- + +# 选通网卡I2C通路的关键变量 +pca9641_slave=0x41 +i2c_bus=12 +pca9548_channel=0x04 +pca9548_slave=0x72 + +log="/tmp/nicsensor_debug.log" +fru_raw_file="/tmp/fru.bin" +INA3221_SHUNT_VOLT=0 +INA3221_BUS_VOLT=1 +INA3221_POWER=2 + +ina3221_ch0_volt="0" +ina3221_ch1_volt="0" +ina3221_ch2_volt="0" +ina3221_ch0_current="0" +ina3221_ch1_current="0" +ina3221_ch2_current="0" + +# --------------------------------------------------------- +# Script Function Defination +# --------------------------------------------------------- + +# script usage +print_usage(){ + echo "" + echo "================>>> nicsensor script usage <<<=================" + echo " format : ./nicsensor.sh [slot] [sensor tpye] [slave]" + echo " slot : 0 1 2 3 4 5" + echo " sensor type : emc1413, adc128, ina3221" + echo " slave : chip slave address , please provide 7 bit address" + echo " E.G. : ./nicsensor.sh 0 adc128 0x1f" + echo "" +} + +# 根据输入信息调整选通芯片的配置(PCA9641 PCA9548) +# 配置信息的具体方案根据5280M7 riser映射表来配置 +set_configuration(){ + + # set pca9641 address && I2C BUS + if [ $pcie_slot -le 2 ];then + pca9641_slave="0x41" + i2c_bus=12 + else + pca9641_slave="0x42" + i2c_bus=13 + fi + + # set pca9548 switch channel + if [ $pcie_slot -eq 0 ];then + pca9548_channel="0x02" + elif [ $pcie_slot -eq 1 ];then + pca9548_channel="0x04" + elif [ $pcie_slot -eq 2 ];then + pca9548_channel="0x08" + elif [ $pcie_slot -eq 3 ];then + pca9548_channel="0x02" + elif [ $pcie_slot -eq 4 ];then + pca9548_channel="0x04" + elif [ $pcie_slot -eq 5 ];then + pca9548_channel="0x08" + fi + +} + +# 初始化调试日志 +prepare_start_info(){ + # 只保留一次日志读取记录 + if [ -e $log ];then + rm $log + fi + + # print time header + res_date=`date` + echo "=========================== $res_date" >> $log + + # 记录单次配置信息到调试日志中去 + echo "PCIE slot : $pcie_slot" >> $log + echo "I2C Bus: $i2c_bus" >> $log + echo "PCA9641 slave: $pca9641_slave" >> $log + echo "PCA9548 slave: $pca9548_slave" >> $log + echo "PCA9548 channel: $pca9548_channel" >> $log + + # Record i2c device info to log + res_info=`i2cdetect -y $i2c_bus` + echo $res_info >> $log +} + +# 获取PCA9641的控制权 +get_pca9641_controll(){ + + # Request 9641 lock + res_lock=`i2ctransfer -y $i2c_bus w2@$pca9641_slave $REG_pca9641_controll 0x81 r1` + echo "After request 9641 lock, The REG value is $res_lock" >> $log + + # Build 9641 Connection + res_build=`i2ctransfer -y $i2c_bus w2@$pca9641_slave $REG_pca9641_controll 0x85 r1` + echo "After Build 9641 connection, The REG value is $res_build" >> $log + + # After get 9641 controll, Record i2c device info to log + res_after=`i2cdetect -y $i2c_bus` + echo $res_after >> $log + + if [ "$res_build" != "0x87" ];then + echo "Cannot establish connection with pca9641 !!!" + exit 1 + fi +} + +# 选通PCA9548的channel +switch_pca9548_channel(){ + + # set 9548 channel + res_setchannel=`i2ctransfer -y $i2c_bus w1@$pca9548_slave $pca9548_channel` + echo "After switch channel" >> $log + + # After set 9548 channel , record i2c device info + res_after=`i2cdetect -y $i2c_bus` + echo $res_after >> $log +} + + +# --------------------------------------------------------- +# Chip EMC1413 +# --------------------------------------------------------- +# 处理EMC1413读到的数据并输出结果 +# @Param1 emc1413读取数据高位 +# @Param2 emc1413读取数据低位 +# @Param3 channel号 +convert_emc1413_data(){ + # 将读取到的两位数据去掉 0x 前缀 + hex_value1=$(echo "$1" | awk '{sub(/^0x/,""); print}') + hex_value2=$(echo "$2" | awk '{sub(/^0x/,""); print}') + + # 由于 bc 计算器只能识别大写的 十六进制数据,将小写的十六进制数据全部转化为大写的数据 + upper_hex_value1=$(echo "$hex_value1" | awk '{ for(i=1; i<=length($0); i++){ if(tolower(substr($0,i,1)) ~ /^[a-f]$/) printf toupper(substr($0,i,1)); else printf substr($0,i,1); } print "" }') + upper_hex_value2=$(echo "$hex_value2" | awk '{ for(i=1; i<=length($0); i++){ if(tolower(substr($0,i,1)) ~ /^[a-f]$/) printf toupper(substr($0,i,1)); else printf substr($0,i,1); } print "" }') + + # 转化为10进制数据 + dec_value1=$(echo "ibase=16; $upper_hex_value1" | bc) + dec_value2=$(echo "ibase=16; $upper_hex_value2" | bc) + + # 计算温度值 + temp=$(echo "scale=4; $dec_value1 + ($dec_value2 / 32 * 0.125 )" | bc) + + # 格式化输出数据 + format_temp=$(echo "$temp" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }') + + echo "channel $3 : $format_temp C, hex value : $hex_value1 $hex_value2" + +} + +# 读取EMC1413芯片每个通道的数据,随后调用数据处理函数进行数据解析并输出 +read_emc1413_channel_value(){ + + echo "Start EMC1413 channel data ..." >> $log + + res_td1_h=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_emc1413_TD1_H r1` + res_td1_l=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_emc1413_TD1_L r1` + res_td2_h=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_emc1413_TD2_H r1` + res_td2_l=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_emc1413_TD2_L r1` + res_td3_h=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_emc1413_TD3_H r1` + res_td3_l=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_emc1413_TD3_L r1` + + # 将 I2C 读取的 raw 数据记录到调试日志中 + echo "channel 1 : $res_td1_h $res_td1_l" >> $log + echo "channel 2 : $res_td2_h $res_td2_l" >> $log + echo "channel 3 : $res_td3_h $res_td3_l" >> $log + + # start parse raw data + echo ">>> The emc1413 value is:" + convert_emc1413_data $res_td1_h $res_td1_l 1 + convert_emc1413_data $res_td2_h $res_td2_l 2 + convert_emc1413_data $res_td3_h $res_td3_l 3 + +} + +# EMC1413处理逻辑 +process_emc1413(){ + # emc1413 no need to init + + # get chip emc1413 value + read_emc1413_channel_value +} + +# --------------------------------------------------------- +# Chip ADC128 +# --------------------------------------------------------- +# 进行ADC128芯片的初始化 +check_adc128_init(){ + # Get Reg 0x00 status + res_adc128_status=`i2cget -y $i2c_bus $chip_slave $REG_adc128_config` + echo "REG adc128 STATUS : $res_adc128_status" >> $log + + # if stauts is not 0x01 (Start Monitor) ,then do init + if [ "$res_adc128_status" != "0x01" ];then + echo "Start Init ADC128 Chip" >> $log + # Init ADC128 work as mode 1 (0x02) + res_adc128_advance=`i2ctransfer -y $i2c_bus w2@$chip_slave $REG_adc128_advance 0x02` + # Set ADC128 on start (0x01) + res_adc128_setstart=`i2ctransfer -y $i2c_bus w2@$chip_slave $REG_adc128_config 0x01 r1` + + echo "After Set status, the REG 0x00 value is $res_adc128_setstart" >> $log + fi +} + +# 处理ADC128读到的数据并输出结果 +# @Param 1 ADC128读取数据高位 +# @Param 2 ADC128读取数据低位 +# @Param 3 channel号 +# @Param 4 分压系数 +convert_adc128_data(){ + # 将读取到的两位数据拼接起来 + hex_value1=$(echo "$1" | awk '{sub(/^0x/,""); print}') + hex_value2=$(echo "$2" | awk '{sub(/^0x/,""); print}') + merge_value="${hex_value1}${hex_value2}" + + # 由于 bc 计算器只能识别大写的 十六进制数据,这里将小写的十六进制数据全部转化为大写的数据 + upper_hex_value=$(echo "$merge_value" | awk '{ for(i=1; i<=length($0); i++){ if(tolower(substr($0,i,1)) ~ /^[a-f]$/) printf toupper(substr($0,i,1)); else printf substr($0,i,1); } print "" }') + + # 利用bc计算器进行运算,并将返回值格式化后输出 + dec_val=$(echo "ibase=16; $upper_hex_value" | bc) + volt=$(echo "scale=4; $dec_val / 16 / 4096 * 2.65 / $4" | bc) + format_volt=$(echo "$volt" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }') + + echo "Channel $3 : $format_volt v, hex value: $upper_hex_value" +} + +# 读取ADC128芯片每个通道的数据,随后调用数据处理函数进行数据解析并输出 +read_adc128_channel_value(){ + echo "Start Read ADC128 channel data ..." >> $log + + res_ch0=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch0 r2` + res_ch1=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch1 r2` + res_ch2=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch2 r2` + res_ch3=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch3 r2` + res_ch4=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch4 r2` + res_ch5=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch5 r2` + res_ch6=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch6 r2` + res_ch7=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch7 r2` + + # 将 I2C 读取的 raw 数据记录到调试日志中 + echo "channel0 : $res_ch0" >> $log + echo "channel1 : $res_ch1" >> $log + echo "channel2 : $res_ch2" >> $log + echo "channel3 : $res_ch3" >> $log + echo "channel4 : $res_ch4" >> $log + echo "channel5 : $res_ch5" >> $log + echo "channel6 : $res_ch6" >> $log + echo "channel7 : $res_ch7" >> $log + + # start parse raw data + echo ">>> The ADC128 value is :" + convert_adc128_data $res_ch0 0 $votage_division_factor_0 + convert_adc128_data $res_ch1 1 $votage_division_factor_1 + convert_adc128_data $res_ch2 2 $votage_division_factor_2 + convert_adc128_data $res_ch3 3 $votage_division_factor_3 + convert_adc128_data $res_ch4 4 $votage_division_factor_4 + convert_adc128_data $res_ch5 5 $votage_division_factor_5 + convert_adc128_data $res_ch6 6 $votage_division_factor_6 + convert_adc128_data $res_ch7 7 $votage_division_factor_7 +} + +# ADC128处理逻辑 +process_adc128(){ + # check if chip adc128 need init + check_adc128_init + + # get chip adc128 value + read_adc128_channel_value +} + +# --------------------------------------------------------- +# Chip INA3221 +# --------------------------------------------------------- +# 处理INA3221读到的电流数据并输出结果 +# @Param1 ina3221读取数据高位 +# @Param2 ina3221读取数据低位 +# @Param3 channel号 +# @Param4 0代表数据是shunt volt +# 1代表数据是bus volt +# @Param5 分流电阻 (仅在 Param4 是 shunt volt时有用) +convert_ina3221_data(){ + # 将读取到的两位数据拼接起来 + hex_value1=$(echo "$1" | awk '{sub(/^0x/,""); print}') + hex_value2=$(echo "$2" | awk '{sub(/^0x/,""); print}') + merge_value="${hex_value1}${hex_value2}" + + # 由于 bc 计算器只能识别大写的 十六进制数据,这里将小写的十六进制数据全部转化为大写的数据 + upper_hex_value=$(echo "$merge_value" | awk '{ for(i=1; i<=length($0); i++){ if(tolower(substr($0,i,1)) ~ /^[a-f]$/) printf toupper(substr($0,i,1)); else printf substr($0,i,1); } print "" }') + + # 将16进制数据转化为10进制 + dec_val=$(echo "ibase=16; $upper_hex_value" | bc) + + # todo 检查这个数据的最高位是否为1 + # max_unsigned_32bit_half=$(echo "scale=0; 2^31 / 2" | bc) + # if [ $(echo "$dec_val >= $max_unsigned_32bit_half" | bc) -eq 1 ];then + # echo "" + # else + # echo "" + # fi + if [ $4 -eq $INA3221_BUS_VOLT ];then + # 计算每个通道上的电压 + volt=$(echo "scale=4; $dec_val / 8 * 40 / 10000 * 2" | bc) + + # 格式化输出数据 + format_volt=$(echo "$volt" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }') + + echo "channel $3 : $format_volt V, hex value: $upper_hex_value" + + if [ $3 -eq 0 ];then + ina3221_ch0_volt=$format_volt + elif [ $3 -eq 1 ];then + ina3221_ch1_volt=$format_volt + else + ina3221_ch2_volt=$format_volt + fi + + elif [ $4 -eq $INA3221_SHUNT_VOLT ];then + # 计算每个分流电阻上的电压,同时计算出电流 + current_mv=$(echo "scale=4; $dec_val / 8 * 40 / 1000" | bc) + current=$(echo "scale=4; $current_mv / $5" | bc) + + # 格式化输出数据 + format_current=$(echo "$current" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }') + format_current_mv=$(echo "$current_mv" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }') + + echo "channel $3 : $format_current A, shunt volt: $format_current_mv mV, shunt resistor: $5 mOhm, hex value: $upper_hex_value" + + if [ $3 -eq 0 ];then + ina3221_ch0_current=$format_current + elif [ $3 -eq 1 ];then + ina3221_ch1_current=$format_current + else + ina3221_ch2_current=$format_current + fi + + elif [ $4 -eq $INA3221_POWER ];then + # 计算每个通道上的功耗,并算总和 + power_ch0=$(echo "scale=4; $ina3221_ch0_volt * $ina3221_ch0_current" | bc) + power_ch1=$(echo "scale=4; $ina3221_ch1_volt * $ina3221_ch1_current" | bc) + power_ch2=$(echo "scale=4; $ina3221_ch2_volt * $ina3221_ch2_current" | bc) + + # 格式化输出数据 + format_power_ch0=$(echo "$power_ch0" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }') + format_power_ch1=$(echo "$power_ch1" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }') + format_power_ch2=$(echo "$power_ch2" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }') + + total_power=$(echo "scale=4; $power_ch0 + $power_ch1 + $power_ch2" | bc) + + echo "channel 0 : $format_power_ch0 W" + echo "channel 1 : $format_power_ch1 W" + echo "channel 2 : $format_power_ch2 W" + echo "total power: $total_power W" + fi +} + +# 读取INA3221芯片每个通道的数据,随后调用数据处理函数进行数据解析并输出 +read_ina3221_channel_value(){ + echo "Start Read INA3221 channel data ..." >> $log + + res_ch0=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_ina3221_ch1 r2` + res_ch1=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_ina3221_ch2 r2` + res_ch2=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_ina3221_ch3 r2` + res_bus0=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_ina3221_bus1 r2` + res_bus1=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_ina3221_bus2 r2` + res_bus2=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_ina3221_bus3 r2` + + + # 将 I2C 读取的 raw 数据记录到调试日志中 + echo "channel 0 shunt volt: $res_ch0" >> $log + echo "channel 1 shunt volt: $res_ch1" >> $log + echo "channel 2 shunt volt: $res_ch2" >> $log + + echo "Channel 0 bus volt : $res_bus0" >> $log + echo "Channel 1 bus volt : $res_bus1" >> $log + echo "Channel 2 bus volt : $res_bus2" >> $log + + # start parse raw data + echo ">>> The INA3221 shunt value is :" + convert_ina3221_data $res_ch0 0 $INA3221_SHUNT_VOLT $shunt_resistor_0 + convert_ina3221_data $res_ch1 1 $INA3221_SHUNT_VOLT $shunt_resistor_1 + convert_ina3221_data $res_ch2 2 $INA3221_SHUNT_VOLT $shunt_resistor_2 + + echo ">>> The INA3221 bus value is :" + convert_ina3221_data $res_bus0 0 $INA3221_BUS_VOLT + convert_ina3221_data $res_bus1 1 $INA3221_BUS_VOLT + convert_ina3221_data $res_bus2 2 $INA3221_BUS_VOLT + + echo ">>> The INA3221 bus power is :" + convert_ina3221_data 0 0 0 $INA3221_POWER +} + +# INA3221处理逻辑 +process_ina3221(){ + + # ina3221 no need to init first + + # get chip ina3221 value + read_ina3221_channel_value +} + +# --------------------------------------------------------- +# CPLD +# --------------------------------------------------------- +# 临时支持CPLD读取 +write_read_cpld(){ + + # Modify i2c cmd which write to cpld if need + cmd_wr=$option_data + res_wr=`$cmd_wr` + + echo ">>> CPLD Command: $cmd_wr" + echo ">>> The Result : $res_wr" +} + +# cpld处理逻辑 +process_cpld(){ + + # cpld no need to init first + + # write and read cpld + write_read_cpld + +} + +# --------------------------------------------------------- +# FRU +# --------------------------------------------------------- +# 临时支持FRU读取 +read_fru(){ + + res_fru=`i2ctransfer -y $i2c_bus w2@$chip_slave $fru_offset r256` + + # 将FRU数据按照每行16个字符输出 + echo "The Fru Data :" + echo "$res_fru" | \ + awk '{ + line=""; + count=0; + + for(i=1; i<=NF; i++){ + hex=substr($i, 3); + + if(line != ""){ + line = line " "; + } + line = line hex; + + count++; + if (count == 16){ + print line; + line = ""; + count = 0; + } + } + + if(line != ""){ + print line; + } + }' + +} + +# 暂时不支持FRU写入,预留接口 +write_fru(){ + current_byte=0 + + echo "Not support write fru now ..." + exit 0 + + while IFS= read -r -n 1 byte || [[ -n "$byte" ]];do + i2cset -y $i2c_bus $chip_slave $current_byte $byte w + + current_byte=$(($current_byte+1)) + done < "$fru_raw_file" +} + +# fru 处理逻辑 +process_fru(){ + # fru no need to init first + + # write and read fru + if [ "$option_data" == "write" ];then + write_fru + else + # 默认为读取操作 + read_fru + fi +} +# --------------------------------------------------------- +# END of CHIP Function +# --------------------------------------------------------- + +# 读取sensor流程的起点 +start_get_sensor(){ + # print start info in log + prepare_start_info + + # 从9641获取I2C控制权 + get_pca9641_controll + + # 选择9548 channel + switch_pca9548_channel + + # get sensor detail value + if [ "$sensor_type" == "emc1413" ];then + process_emc1413 + elif [ "$sensor_type" == "adc128" ];then + process_adc128 + elif [ "$sensor_type" == "ina3221" ];then + process_ina3221 + elif [ "$sensor_type" == "cpld" ];then + process_cpld + elif [ "$sensor_type" == "fru" ];then + process_fru + fi +} + +# 搜索服务器所有PCIE插槽的I2C设备信息,当前仅支持特定Riser卡上的设备 +start_detect_device(){ + # 从9641获取I2C控制权 + i2c_bus=12 + pca9641_slave="0x41" + get_pca9641_controll + + echo ">>> PCIe slot 0 : bus12 9548channel1" + i2ctransfer -y $i2c_bus w1@0x72 0x02 + i2cdetect -y $i2c_bus + + echo ">>> PCIe slot 1 : bus12 9548channel2" + i2ctransfer -y $i2c_bus w1@0x72 0x04 + i2cdetect -y $i2c_bus + + echo ">>> PCIe slot 2 : bus12 9548channel3" + i2ctransfer -y $i2c_bus w1@0x72 0x08 + i2cdetect -y $i2c_bus + + i2c_bus=13 + pca9641_slave="0x42" + get_pca9641_controll + + echo ">>> PCIe slot 3 : bus13 9548channel1" + i2ctransfer -y $i2c_bus w1@0x72 0x02 + i2cdetect -y $i2c_bus + + echo ">>> PCIe slot 4 : bus13 9548channel2" + i2ctransfer -y $i2c_bus w1@0x72 0x04 + i2cdetect -y $i2c_bus + + echo ">>> PCIe slot 5 : bus13 9548channel3" + i2ctransfer -y $i2c_bus w1@0x72 0x08 + i2cdetect -y $i2c_bus +} + +# --------------------------------------------------------- +# Start Execute Script +# --------------------------------------------------------- + +if [ "$1" == "detect" ];then + start_detect_device + exit 0 +fi + +if [ $# -le 2 ];then + print_usage +else + set_configuration + start_get_sensor +fi diff --git a/02.nicsensor/readme.txt b/02.nicsensor/readme.txt new file mode 100644 index 0000000..02d8c82 --- /dev/null +++ b/02.nicsensor/readme.txt @@ -0,0 +1,88 @@ + ### 重要说明 :脚本仅用于M7服务器,带有i2c standard tool工具的BMC使用 + + 一、脚本使用方法 V1.0 + + 1、针对不同项目,请先修改脚本中的部分变量(ADC128电压传感器的分压系数,INA3221的分流精密电阻阻值) + + 2、为脚本增加可执行权限 chmod +x ./nicsensor.sh + + 3、脚本命令格式 ./nicsensor.sh + + 参数说明: + pcie_slot : 网卡所在的PCIE槽位,填数字0,1,2,3,4,5 + chip_type : 传感器芯片的类型,emc1413,adc128,ina3221 + chip_slave: 传感器芯片的I2C地址(7bit) + + 举例说明:读取PCIE 1 上网卡的adc128芯片, 芯片slave地址为0x1f + ./nicsensor.sh 1 adc128 0x1f + + 4、特殊命令 + + 4.1 扫描服务器的PCIE slot 0 - 5上所有的I2C设备 + + 命令: ./nicsensor.sh detect + + 4.2 读取fru信息 + + 命令: ./nicsensor.sh fru read + 举例说明:读取Ravel板卡的EEPROM中的FRU(0x57) + - ./nicsensor.sh 5 fru 0x57 read + + 4.3 读取CPLD寄存器 + + 命令: ./nicsensor.sh cpld + 举例说明:读取cpld的寄存器 0x00 ,读2个byte + - ./nicsensor.sh 5 cpld 0x10 "i2ctransfer -y 13 w1@0x10 0x00 r2" + + + 二、5280M7 PCIE槽位和PCA9548的channel关系 + + 5280M7的PCIE槽位和PCA9548/9546没有确定的对应关系,取决于使用的riser卡。根据一般情况选择的Riser卡,对应 + 情况如下: + + PCIE 0 = i2c bus 12 , 9548channel1(0x02) + PCIE 1 = i2c bus 12 , 9548channel2(0x04) + PCIE 2 = i2c bus 12 , 9548channel3(0x08) + PCIE 3 = i2c bus 13 , 9548channel1(0x02) + PCIE 4 = i2c bus 13 , 9548channel2(0x04) + PCIE 5 = i2c bus 13 , 9548channel3(0x08) + + 可以根据实际情况选择性的修改脚本中的 start_detect_device 和 set_configuration 两个函数 + + 三、M7 sysadmin用户 SSH打开方法 + + 5280M7服务器默认不开启SSH,且串口通常有较多干扰打印,因此推荐使用SSH来执行脚本,刷新BMC镜像后需要重新配置 + + 1、打开M7 BMC的串口,可通过串口线或者IPMI SOL带外登入 + + 使用IPMI SOL的前提环境:可与BMC网络连接,且电脑上有ipmitool工具 + SOL登陆方法: + 1)将SOL串口源切换到BMC: + ipmitool -I lanplus -H -U admin -P admin raw 0x3c 0x2c 0x02 0x01 + 2)打开SOL: + ipmitool -I lanplus -H -U admin -P admin sol activate + 备注: 为目标BMC的ip地址,请自行更改为对应的ip地址 + + 2、登录进入bmc的linux系统 + + bmc linux系统的默认用户名/密码 :sysadmin/superuser + + 3、在BMC的linux系统下执行命令 + + 1) cp /etc/defconfig/ssh_server_config_with_sysadmin /etc/ssh/sshd_config + + 2) /etc/init.d/ssh restart + + 执行完毕后,就可以使用ssh登录BMC了 + + 四、常见问题 + + 1、脚本执行时出现大量的 Error + + 由于M7服务器的I2C设计有PCA9641作为I2C仲裁器,脚本执行过程中可能会被9641强行断开I2C连接,造成大量的 + 脚本Error,这种时候重新执行脚本即可 + + 2、不建议使用该脚本进行压力测试 + + 由于BMC shell的版本非常原始,没有集成高级的命令行工具,因此处理数值时采用了复杂的脚本逻辑进行执行,处 + 理效率较低。另外由于9641芯片的存在,不能保证压力测试的正常执行。 diff --git a/Readme.md b/Readme.md index 7fafb18..4d21d5a 100644 --- a/Readme.md +++ b/Readme.md @@ -7,4 +7,7 @@ - 带内执行AC cycle : [inband_ac_cycle.sh](./01.stress_script/inband_ac_cycle.sh) - 带外执行AC cycle : [outband_ac_cycle.sh](./01.stress_script/outband_ac_cycle.sh) - OS执行reboot :[os_reboot.sh](./01.stress_script/os_reboot.sh) -- 使用YAFU带内升级BMC :[inband_stress_update.sh](./01.stress_script/inband_stress_update.sh) \ No newline at end of file +- 使用YAFU带内升级BMC :[inband_stress_update.sh](./01.stress_script/inband_stress_update.sh) + +### nicsensor +- M7服务器BMC读取网卡传感器 :[nicsensor.sh](./02.nicsensor/nicsensor.sh) \ No newline at end of file