#!/bin/sh # script Version 1.1 20240912 # 支持测试的传感器芯片 emc1413 ina3221 adc128 # 支持通过 chip 参数直接做I2C命令透传来访问芯片寄存器 # 支持通过 fru 参数读取FRU十六进制内容 # --------------------------------------------------------- # Project Feature Varible (按照项目需要修改) # --------------------------------------------------------- # 应用的服务器产品,根据服务器产品手动修改这个变量 # 当前适配的服务器产品 5280m7 5468m7 donghu yichun server_type="5280m7" # --------------------------------------------------------- # Common Varible (请勿随意修改) # --------------------------------------------------------- # Input Param # Introduction of pcie_slot # 1.脚本即将访问的网卡位于服务器上的PCIe插槽位置 pcie_slot=$1 # Introduction of sensor_type # 1.脚本即将读取和处理的传感器名称 sensor_type=$2 # Introduction of chip_slave # 1.chip i2c slave address(7bit) chip_slave=$3 # Introduction of option_data # 1.在FRU的处理过程中,使用option_data来区分是读操作还是写操作,将值设置为 # "read"或者"write" # 2.在chip的处理过程中,使用option_data来代表一条完整的i2c命令,这条命令会 # 被发到chip上,一个例子:"i2ctransfer -y 12 w2@0x10 0x90 0x00 r9" option_data=$4 # Introduction of option_data2 # 1.仅用于fru write操作,代表即将写入的fru文件名 option_data2=$5 # CHIP REGISTER REG_pca9641_controll="0x01" # --------------------------------------------------------- # Global Varible (请勿随意修改) # --------------------------------------------------------- # DEBUG MODE=0 : Disable debug mode # =1 : Enable debug mode # 启用debug模式后需要手动配置 i2c_bus DEBUG_MODE=0 # 选通网卡I2C通路的关键变量 i2c_bus=12 pca9641_slave=0x41 pca9548_channel=0x04 pca9548_slave=0x72 # 硬件上是否有PCA9641? is_have_pca9641=1 log="/tmp/nicsensor_debug.log" INFO="Info" WARNING="Warning" ERROR="Error" SCRIPT_VRESION="1.2 InTest Rev3" fru_file_name=$option_data2 # --------------------------------------------------------- # Script Function Defination # --------------------------------------------------------- # script usage print_usage(){ echo "" echo "================>>> nicsensor script usage <<<=================" echo " Command Format : ./nicsensor.sh [slot] [sensor tpye] [slave]" echo " Option Detail" 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 "" echo " To Auto detect i2c slave on server, please use:" echo " ./nicsensor.sh detect" echo " This function now only support on server 5280m7, 5468m7, donghu" echo "" echo " If want to read/write chip register, use the below format" echo " ./nicsensor.sh [slot] chip [slave] [i2c_command]" echo " i2c_command : such as [i2ctransfer -y 13 w1@0x10 0x00 r2]" echo "" echo " If want to use debug mode, please modify the DEBUG_MODE to 1" echo " now status : DEBUG_MODE = $DEBUG_MODE" echo "" } print_chip_command_format(){ echo "Command Format : ./nicsensor.sh [slot] chip [slave] [i2c_command]" } print_fru_command_format(){ echo "Command Format : ./nicsensor.sh [slot] fru [slave] write [fru_file]" } # 格式化输出信息 # @Param1 信息等级 [Info/Warning/Error] # @Param2 信息内容 format_print(){ echo ">>> [$1] $2" } # 格式化输出信息到日志文件 # @Param1 信息等级 [Info/Warning/Error] # @Param2 信息内容 format_log_print(){ echo "[$1] $2" >> $log } # 自查一些脚本中的属性配置 conf_pre_check(){ # 校验debug mode的值 if [ $DEBUG_MODE -ne 0 && $DEBUG_MODE -ne 1 ];then format_print $ERROR "Invalid conf value, DEBUG_MODE: $DEBUG_MODE" exit 1 fi } # 根据5280m7 pcie slot 和 i2c 对对应关系调整变量 set_configuration_5280m7(){ is_have_pca9641=1 # 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 } # 根据5468m7 pcie slot 和 i2c 对对应关系调整变量 set_configuration_5468m7(){ is_have_pca9641=1 # set pca9641 address && I2C BUS if [ $pcie_slot -le 4 ];then pca9641_slave="0x31" pca9548_slave="0x70" i2c_bus=13 else pca9641_slave="0x42" pca9548_slave="0x71" i2c_bus=14 fi # set pca9548 switch channel if [ $pcie_slot -eq 0 ];then pca9548_channel="0x01" elif [ $pcie_slot -eq 1 ];then pca9548_channel="0x02" elif [ $pcie_slot -eq 2 ];then pca9548_channel="0x04" elif [ $pcie_slot -eq 3 ];then pca9548_channel="0x08" elif [ $pcie_slot -eq 4 ];then pca9548_channel="0x10" elif [ $pcie_slot -eq 5 ];then pca9548_channel="0x01" elif [ $pcie_slot -eq 6 ];then pca9548_channel="0x02" elif [ $pcie_slot -eq 7 ];then pca9548_channel="0x04" elif [ $pcie_slot -eq 8 ];then pca9548_channel="0x08" elif [ $pcie_slot -eq 9 ];then pca9548_channel="0x10" elif [ $pcie_slot -eq 10 ];then pca9548_channel="0x20" fi } # 根据donghu pcie slot 和 i2c 对对应关系调整变量 set_configuration_donghu(){ is_have_pca9641=0 i2c_bus=3 # set pca9548 switch channel if [ $pcie_slot -eq 0 ];then pca9548_channel="0x80" elif [ $pcie_slot -eq 1 ];then pca9548_channel="0x40" elif [ $pcie_slot -eq 2 ];then pca9548_channel="0x20" elif [ $pcie_slot -eq 3 ];then pca9548_channel="0x10" elif [ $pcie_slot -eq 4 ];then pca9548_channel="0x08" elif [ $pcie_slot -eq 5 ];then pca9548_channel="0x04" elif [ $pcie_slot -eq 6 ];then pca9548_channel="0x02" elif [ $pcie_slot -eq 7 ];then pca9548_channel="0x01" fi } # 根据yichun pcie slot 和 i2c 对对应关系调整变量 set_configuration_yichun(){ is_have_pca9641=0 pca9548_slave="0x74" # set pca9548 switch channel if [ $pcie_slot -eq 0 ];then i2c_bus=12 pca9548_channel="0x02" elif [ $pcie_slot -eq 1 ];then i2c_bus=13 pca9548_channel="0x02" elif [ $pcie_slot -eq 2 ];then i2c_bus=14 pca9548_channel="0x02" fi } # 根据输入信息调整选通芯片的配置(PCA9641 PCA9548) # 20240912 - 更新脚本:支持通过服务器型号进行配置 set_configuration(){ format_log_print $INFO "Server Type : $server_type" # 根据服务器型号执行对应的配置策略 if [ $server_type == "5280m7" ];then set_configuration_5280m7 elif [ $server_type == "5468m7" ];then set_configuration_5468m7 elif [ $server_type == "donghu" ];then set_configuration_donghu elif [ $server_type == "yichun" ];then set_configuration_yichun else format_print $ERROR "Error: Unsupport Server Type !!! - $server_type" exit 1 fi } # 初始化调试日志 init_debuglog(){ # 只保留一次日志读取记录 if [ -e $log ];then rm $log fi # print time header res_date=`date` format_log_print $INFO "=========================== $res_date" format_log_print $INFO "Script Version : $SCRIPT_VERSION" if [ $DEBUG_MODE -ne 0 ];then format_log_print $WARNING "Enable debug mode : $DEBUG_MODE" fi } # 记录配置信息日志 prepare_start_info(){ # 记录单次配置信息到调试日志中去 format_log_print $INFO "PCIE slot : $pcie_slot" format_log_print $INFO "I2C Bus: $i2c_bus" format_log_print $INFO "PCA9641 slave: $pca9641_slave" format_log_print $INFO "PCA9548 slave: $pca9548_slave" format_log_print $INFO "PCA9548 channel: $pca9548_channel" # 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` format_log_print $INFO "After request 9641 lock, The REG value is $res_lock" # Build 9641 Connection res_build=`i2ctransfer -y $i2c_bus w2@$pca9641_slave $REG_pca9641_controll 0x85 r1` format_log_print $INFO "After Build 9641 connection, The REG value is $res_build" # 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 format_print $ERROR "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` format_log_print $INFO "After switch channel" # After set 9548 channel , record i2c device info res_after=`i2cdetect -y $i2c_bus` echo $res_after >> $log } # --------------------------------------------------------- # Chip EMC1413 # --------------------------------------------------------- # EMC1413处理逻辑 process_emc1413(){ # emc1413 no need to init # get chip emc1413 value read_emc1413_channel_value } # --------------------------------------------------------- # Chip ADC128 # --------------------------------------------------------- # ADC128处理逻辑 process_adc128(){ # check if chip adc128 need init check_adc128_init # get chip adc128 value read_adc128_channel_value } # --------------------------------------------------------- # Chip INA3221 # --------------------------------------------------------- # INA3221处理逻辑 process_ina3221(){ # ina3221 no need to init first # get chip ina3221 value read_ina3221_channel_value } # --------------------------------------------------------- # CHIP # --------------------------------------------------------- # chip处理逻辑 process_chip(){ # cpld no need to init first # write and read cpld write_read_chip } # --------------------------------------------------------- # FRU # --------------------------------------------------------- # 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(){ # 首先选通 PCA9641 和 PCA9548,构建I2C通路 # 如果使用了debug模式,那么将不执行选通9641和9548的操作 if [ $DEBUG_MODE -eq 0 ];then # set global varible by server type set_configuration # 记录开始执行脚本前的I2C配置信息 prepare_start_info # 从9641获取I2C控制权 if [ $is_have_pca9641 -eq 1 ];then get_pca9641_controll fi # 选择9548 channel switch_pca9548_channel fi # 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" == "chip" ];then process_chip elif [ "$sensor_type" == "fru" ];then process_fru else format_print $ERROR "Unsupport Sensor Type !!!" print_usage fi } # --------------------------------------------------------- # Start Execute Script # --------------------------------------------------------- # 配置校验 conf_pre_check # 参数合法校验 if [ "$sensor_type" == "chip" ];then if [ $# -le 3 ];then format_print $ERROR "Command Format illegal" print_chip_command_format exit 1 fi fi if [ "$1" == "detect" ];then start_detect_device exit 0 fi # 在正式执行脚本之前初始化调试日志 init_debuglog # 如果是fru write操作, 需要对即将写入的bin文件进行数据预处理 if [ "$sensor_type" == "fru" ];then if [ "$option_data" == "write" ];then format_log_print $INFO "Opreation FRU Write" # 在fru write操作下要求必须有 option_data2, 做参数检查 if [ "$option_data2" == "" ];then format_print $ERROR "Please provide fru file name" print_fru_command_format exit 1 fi # 解析fru bin文件 parse_fru_write_data fi fi if [ $# -le 2 ];then print_usage else start_get_sensor fi