⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipmi_sensor_factors.cpp

📁 HIP 硬件设备管理标准接口
💻 CPP
字号:
/* * ipmi_sensor_factors.cpp * * Copyright (c) 2004 by FORCE Computers * * Note that this file is based on parts of OpenIPMI * written by Corey Minyard <minyard@mvista.com> * of MontaVista Software. Corey's code was helpful * and many thanks go to him. He gave the permission * to use this code in OpenHPI under BSD license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  This * file and program are licensed under a BSD style license.  See * the Copying file included with the OpenHPI distribution for * full licensing terms. * * Authors: *     Thomas Kanngieser <thomas.kanngieser@fci.com> */#include "ipmi_sensor_factors.h"#include <math.h>static const char *analoge_data_format[] ={  "Unsigned",  "1Compl",  "2Compl",  "Analog"};const char *IpmiAnalogeDataFormatToString( tIpmiAnalogeDataFormat fmt ){  if ( (int)fmt <= eIpmiAnalogDataFormatNotAnalog )       return analoge_data_format[fmt];  return "Invalid";}static const char *linearization_map[] ={  "Linear",  "Ln",  "Log10",  "Log2",  "E",  "Exp10",  "Exp2",  "1OverX",  "Sqr",  "Cube",  "Sqrt",  "1OverCube"};const char *IpmiLinearizationToString( tIpmiLinearization val ){  if ( val == eIpmiLinearizationNonlinear )       return "NonLinear";  if ( val <= eIpmiLinearization1OverCube )       return linearization_map[val];  return "Invalid";}cIpmiSensorFactors::cIpmiSensorFactors()  : m_analog_data_format( eIpmiAnalogDataFormatUnsigned ),    m_linearization( eIpmiLinearizationLinear ),    m_m( 0 ),    m_tolerance( 0 ),    m_b( 0 ),    m_r_exp( 0 ),    m_accuracy_exp( 0 ),    m_accuracy( 0 ),    m_b_exp( 0 ){}cIpmiSensorFactors::~cIpmiSensorFactors(){}boolcIpmiSensorFactors::GetDataFromSdr( const cIpmiSdr *sdr ){  m_analog_data_format = (tIpmiAnalogeDataFormat)((sdr->m_data[20] >> 6) & 3);  m_linearization = (tIpmiLinearization)(sdr->m_data[23] & 0x7f);  if ( m_linearization <= 11 )     {       m_m            = sdr->m_data[24] | ((sdr->m_data[25] & 0xc0) << 2);       m_tolerance    = sdr->m_data[25] & 0x3f;       m_b            = sdr->m_data[26] | ((sdr->m_data[27] & 0xc0) << 2);       m_accuracy     = ((sdr->m_data[27] & 0x3f)                            | ((sdr->m_data[28] & 0xf0) << 2));       m_accuracy_exp = (sdr->m_data[28] >> 2) & 0x3;       m_r_exp        = (sdr->m_data[29] >> 4) & 0xf;       m_b_exp        = sdr->m_data[29] & 0xf;     }  return true;}boolcIpmiSensorFactors::Cmp( const cIpmiSensorFactors &sf ) const{  if ( m_analog_data_format != sf.m_analog_data_format )       return false;  if ( m_linearization != sf.m_linearization )       return false;  if ( m_linearization <= 11 )     {       if ( m_m            != sf.m_m            )            return false;       if ( m_tolerance    != sf.m_tolerance    )            return false;       if ( m_b            != sf.m_b            )            return false;       if ( m_accuracy     != sf.m_accuracy     )            return false;       if ( m_accuracy_exp != sf.m_accuracy_exp )            return false;       if ( m_r_exp        != sf.m_r_exp        )            return false;       if ( m_b_exp        != sf.m_b_exp        )            return false;     }  return true;}static doublec_linear( double val ){  return val;}static doublec_exp10( double val ){  return pow( 10.0, val );}static doublec_exp2( double val ){  return pow( 2.0, val );}static doublec_1_over_x( double val ){  return 1.0 / val;}static doublec_sqr( double val ){  return pow( val, 2.0 );}static doublec_cube( double val ){  return pow( val, 3.0 );}static doublec_1_over_cube( double val ){  return 1.0 / pow( val, 3.0 );}typedef double (*linearizer)( double val );static linearizer linearize[12] ={  c_linear,  log,  log10,  log2,  exp,  c_exp10,  c_exp2,  c_1_over_x,  c_sqr,  c_cube,  sqrt,  c_1_over_cube};static intsign_extend( int m, int bits ){    if ( m & (1 << (bits-1)) )	return m | (-1 << bits);    else	return m & (~(-1 << bits));}boolcIpmiSensorFactors::ConvertFromRaw( unsigned int val,                                    double      &result ) const{  double m, b, b_exp, r_exp, fval;  linearizer c_func;  if ( m_linearization == eIpmiLinearizationNonlinear )       c_func = c_linear;  else if ( m_linearization <= 11 )       c_func = linearize[m_linearization];  else       return false;  val &= 0xff;  m     = m_m;  b     = m_b;  r_exp = m_r_exp;  b_exp = m_b_exp;  switch( m_analog_data_format )     {       case eIpmiAnalogDataFormatUnsigned:	    fval = val;	    break;       case eIpmiAnalogDataFormat1Compl:	    val = sign_extend( val, 8 );	    if ( val == 0xffffffff )                 val += 1;	    fval = val;	    break;       case eIpmiAnalogDataFormat2Compl:	    fval = sign_extend( val, 8 );	    break;       default:	    return false;     }  result = c_func( ((m * fval) + (b * pow(10, b_exp))) * pow(10, r_exp) );  return true;}boolcIpmiSensorFactors::ConvertToRaw( tIpmiRound    rounding,                                  double        val,                                  unsigned int &result ) const{  bool rv;  double cval;  int    lowraw, highraw, raw, maxraw, minraw, next_raw;  switch( m_analog_data_format )     {       case eIpmiAnalogDataFormatUnsigned:	    lowraw   = 0;	    highraw  = 255;	    minraw   = 0;	    maxraw   = 255;	    next_raw = 128;	    break;       case eIpmiAnalogDataFormat1Compl:	    lowraw   = -127;	    highraw  = 127;	    minraw   = -127;	    maxraw   = 127;	    next_raw = 0;	    break;       case eIpmiAnalogDataFormat2Compl:	    lowraw   = -128;	    highraw  = 127;	    minraw   = -128;	    maxraw   = 127;	    next_raw = 0;	    break;       default:	    return false;    }  // We do a binary search for the right value.  Yuck, but I don't  // have a better plan that will work with non-linear sensors.  do     {       raw = next_raw;       rv = ConvertFromRaw( raw, cval );       if ( !rv )	    return false;       if ( cval < val )          {	    next_raw = ((highraw - raw) / 2) + raw;	    lowraw = raw;          }        else          {	    next_raw = ((raw - lowraw) / 2) + lowraw;	    highraw = raw;          }     }  while( raw != next_raw );  // The above loop gets us to within 1 of what it should be, we  // have to look at rounding to make the final decision.  switch( rounding )     {       case eRoundNormal:	    if ( val > cval )               {                 if ( raw < maxraw )                    {                      double nval;                      rv = ConvertFromRaw( raw + 1, nval );                      if ( !rv )                           return false;                      nval = cval + ((nval - cval) / 2.0);                      if ( val >= nval )                           raw++;                    }               }            else               {                 if ( raw > minraw )                    {                      double pval;                      rv = ConvertFromRaw( raw-1, pval );                      if ( !rv )                           return false;                      pval = pval + ((cval - pval) / 2.0);                      if ( val < pval )                           raw--;                    }               }	    break;       case eRoundUp:	    if ((val > cval) && (raw < maxraw))                 raw++;	    break;       case eRoundDown:	    if ( ( val < cval) && (raw > minraw ) )                 raw--;	    break;     }  if ( m_analog_data_format == eIpmiAnalogDataFormat1Compl )       if ( raw < 0 )	    raw -= 1;  result = raw & 0xff;  return true;}boolcIpmiSensorFactors::CreateDataFormat( SaHpiSensorDataFormatT &df ) const{  df.ReadingFormats          = SAHPI_SRF_RAW | SAHPI_SRF_INTERPRETED;  df.IsNumeric               = SAHPI_TRUE;  df.SignFormat              = (SaHpiSensorSignFormatT)AnalogDataFormat();  df.FactorsStatic           = SAHPI_TRUE;  df.Factors.M_Factor        = (SaHpiInt16T)M();  df.Factors.B_Factor        = (SaHpiInt16T)B();  df.Factors.AccuracyFactor  = (SaHpiUint16T)Accuracy();  df.Factors.ToleranceFactor = (SaHpiUint8T)Tolerance();  df.Factors.ExpA            = (SaHpiUint8T)AccuracyExp();  df.Factors.ExpR            = (SaHpiUint8T)RExp();  df.Factors.ExpB            = (SaHpiUint8T)BExp();  df.Factors.Linearization   = (SaHpiSensorLinearizationT)Linearization();  return true;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -