The DTC library, dtcreg, contains a set of functions that facilitate reading from and writing to registers on the DTC.

A detailed account of updates may be found in the Readme file at [http://cms1.bu.edu/~msdim/dtc_software/].

Opening and Closing

The code may be found in /home/msdim/ipmi/ipmitool-1.8.11/dtcreg, where dtcreg.o is the actual library and dtcreg.h is the associated header file.

Using dtcreg is much like file handling in C: you declare a handle, open/initialize the handle, perform read/write operations with the handle, and close the handle.

First, it should be noted that in building a program that uses ipmitool libraries, there are two external global variables that must be defined in the program being built. Define the following global variables:

int verbose = 0;
int csv_output = 0;

The handle for dtcreg is called hDTC. It contains an instance of the ipmi_intf (IPMI interface) structure called intf. In addition, it contains two 1-bit flags: int lock and int dblBridge. lock is set to 1 (true) once the handle is opened and communication with the MCH is established and is set to 0 (false) once the handle is closed; hence, a locked handle (which has been closed or never initialized) cannot have read/write commands used on it, avoiding segmentation faults. dblBridge determines whether communication is double bridged or single bridged (in general it will be double) and setting it to 0 means that single bridged communication will be used (anything but 0 implies double bridged).

The open statement is: int dtc_open(hDTC *handle, char *ip, int dblBridge). This different from the C fopen in two essential ways:

1. The address of the handle is passed to the first parameter.

2. dtc_open returns in error code (0 for success)

The second parameter is the ip address of the MCH in character string form, e.g. "192.168.1.10". The third parameter sets whether the communication is single or double bridged (as explained previously) and should be set to either DTC_SINGLE or DTC_DOUBLE.

The close function is: int dtc_close(hDTC *handle). It accepts the address of a handle and returns an error code. This function should be called when a particular handle should not be used anymore, like at the end of the program.

Using hDTC, dtc_open, and dtc_close should look something like this:

{
  hDTC handle;
  dtc_open(&handle, "192.168.1.10", DTC_DOUBLE);
  /* Read/write in here... */
  
  dtc_close(&handle);
}

Reading and Writing

There are 4 read and 4 write functions. As of version 3, each of these functions requires a pointer to a hDTC handle for the first parameter and a register address for the second. Prior to version 3, each function required the actual handle to be passed. The requrement of a pointer to the handle arises from the need to change values stored in the struct. Version 3 fixes a timeout problem: after one minute, the connection would timeout and the read and write functions were useless after. Now, if dtc_read/dtc_write fails, the function closes the handle and attempts to re-open it: if the re-open is successful, then the read/write is performed; else, the handle is simply closed to avoid future attempted operations on a closed connection. Furthermore, version 3 removes the dtc_readx/dtc_writex variations: they simply required a string register address rather than a numeric register address which made console input simpler. To convert strings composed of numbers, either in plain notation ("109") or in hexadecimal notation ("0x2c"), the following standard function should be used:

strtoul(char *str, NULL, 0);  // "string to unsigned long"

Note that the byte number variations (dtc_read## and dtc_write##) call dtc_read() and dtc_write() for their reading/writing operations. Therefore, any major "low level" hardware interface changes will be made in the dtc_read() and dtc_write() functions and should carry through to their variants.

dtc_read/dtc_write

These are the most basic read and write functions and are called by the higher level read/write functions. dtc_read reads from one register and dtc_write writes to one register.

int dtc_read(hDTC *handle, int regAddr, uint8_t dat[], int *lenRead)

The third parameter asks for an array of 8-bit unsigned integers which will contain the read data. The fourth parameter asks for the address of an integer in which the length of the read data will be stored, i.e. the length of the data array. The max array length that this (and all following functions) assumes is defined by MAX_DATA in dtcreg.h and is by default set to 16.

int dtc_write(hDTC *handle, int regAddr, uint8_t dat)

This is a simple function: the third parameter is the 8-bit value to write to the register.

dtc_read8/dtc_read32/dtc_read16

Specialized for reading from 8-bit registers and 32-bit registers (four subsequent 8-bit registers). Can also read from a number of subsequent registers.

int dtc_read8(hDTC *handle, int regAddr, uint8_t dat[], int count)

The third parameter requires an array which will hold the amount of data specified by count, which specifies the number of subsequent registers to read (count = 1 reads one).

int dtc_read32(hDTC *handle, int regAddr, uint32_t dat[], int count)

Here, count refers to the number of 32-bit registers to read from, that is, 4*count will be the total number of 8-bit registers to be read.

dtc_read16 is similar to the above descriptions.

dtc_write8/dtc_write32/dtc_write16

Similar to dtc_read8/dtc_read32.

int dtc_write8(hDTC *handle, int regAddr, uint8_t dat[], int count)

Takes an array of data in the third argument and writes to a number of subsequent registers specified by count. So, dat[0] is written to the register specified by regAddr, dat[1] is written to regAddr+1, ..., dat[count-1] is written to regAddr+count-1.

int dtc_write32(hDTC *handle, int regAddr, uint32_t dat[], int count)

dat[0] is written to registers regAddr through regAddr+3, dat[1] is written to regAddr+4 through regAddr+7, ..., dat[count-1] is written to regAddr+4*(count-1) through regAddr+4*(count-1)+3.

dtc_write16 is similar to the above descriptions

Compiling

dtcreg is built on ipmitool and is a wrapper for some of its structures and functions; so while using it does not require knowledge of the ipmitool code, programs built with it must include several additional libraries which are required by ipmitool. There is a makefile included in the dtcreg directory. A description of the header files and libraries and where they are located is at ipmitool.

Header files (relative to top ipmitool directory):

(include/ipmitool/) ipmi.h, ipmi_intf.h, ipmi_main.h, ipmi_raw.h, ipmi_strings.h

(src/plugins/) lan/lan.h

Libraries (relative to top ipmitool directory):

lib/.libs/libipmitool.a src/plugins/.libs/libintf.a src/plugins/lan/.libs/libintf_lan.a

(other) libncurses, libcrypto, libm

-- MichaelDimitriyev - 16 Jun 2010

Edit | Attach | Watch | Print version | History: r6 < r5 < r4 < r3 < r2 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r6 - 26 Jul 2010 - MichaelDimitriyev
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback