Trivial bug in(?) and proposed change to libi2c.h

Till Straumann strauman at slac.stanford.edu
Wed May 14 22:21:27 UTC 2008


Robert S. Grimes wrote:
> Till Straumann wrote:
>>> That being said, how would that fit in with device major and minor
>>> numbers?  I am certainly unsure here, so let me restate my
>>> configuration, which is more complex than some.  I have several,
>>> separate SPI IP peripherals - this would correspond to a traditional
>>> microprocessor with multiple SPI controllers.  Each SPI "bus" has
>>> multiple devices attached to it.  So, I was under the impression that a
>>> major device number would be assigned to each instance of the SPI
>>> controller driver, and a minor number to each SPI device driver.
>>>
>>> Is this correct?
>>>
>>> Or should the major number correspond to the SPI driver, the minor
>>> number to a specific controller, and some new number (in the struct
>>> under discussion) assigned for each SPI device.
>>>
>>>     
>> The latter. Traditionally, the major number is associated with a
>> particular driver
>> (registered with the OS) the minor number with a device instance;
>> ultimately the semantics of the
>> minor number are defined by the driver, the major number by the OS.
>>
>> libi2c registers itself with RTEMS under one major number and it uses
>> specific
>> semantics for the minor number. Basically, libi2c uses parts of the
>> minor number
>> to identify a 'low-level' aka 'bus' driver and dispatches read/write
>> etc. to the
>> 'bus' driver registered with libi2c under the 'bus' number (some bits or
>> the minor number).
>>   
> So the major number here is libi2c,
yes
> and the minor number specifies both a "controller" device (either i2c 
> or spi, right?) and a "chip" device (e.g. an I2C EEPROM, and SPI FRAM, 
> etc.), right?
yes.

The 'minor' number actually encodes three things:

1)  'device' driver (e.g., temp. sensor) as registered with
     rtems_libi2c_register_drv(). The device driver
     knows what to write to/read from the device
     to achieve certain things. However, it doesn't know
     how to interact with the particular i2c/spi controller
     chip in order to write to/read from the device.

2) 'bus' driver (for a particular i2c/spi controller) as registered
    with rtems_libi2c_register_bus(). The bus driver knows
    *how* to communicate with the attached devices but
    it doesn't know about the semantics.

3) device address on the bus (multiple devices using the
    same 'device' and 'bus' drivers may be present.

a) you register a bus-driver for your SPI chip with libi2c and get
    a bus number returned.

b) you register a device-driver for your EEPROM with libi2c on
    a bus (use number from step a) at a device address on that bus.
    You obtain a minor number back.
    Optionally, step b) also creates a file system entry (mknod)
    with your name of choice, libi2c's major number and the minor
    number from step b)

    Step b) can be repeated for multiple instances of identical
    devices (same dev-driver but different dev-address => different
    minor number).


Here's what happens when you e.g., read() from a libi2c device:

   1) OS knows (by major number) that it has to call libi2c
   2) OS dispatches rtems_i2c_read()
   3) libi2c figures out what bus and device drivers (as registered in a+b)
       to use. It sends a addressing sequence using the bus driver and
       the device address (encoded in minor number)
   4) libi2c calls the 'device' driver's 'read' function
   5) the 'read' function does it's job (e.g., if you read from a 
thermometer
       the driver has to i) trigger a measurement, ii) read back from the
       device, interpret the results and hand them to the user.
   6) the device driver accomplishes i), ii) using libi2c's low-level 
routines
        rtems_libi2c_start_write_bytes & friends to interact with the device
   7) low-level routines use the bus driver (as encoded in 'minor') to
        actually perform the communication

A bit complicated but it strictly separates drivers for the
bus controllers ('how' to read/write) from the drivers for
the attached devices ('what' to read/write).

Look in libchip/i2c for examples of libi2c 'device' drivers.
   
>> Whatever you do, please do not break the current semantics for i2c 
>> devices
>> where the bus number and device-address on the bus(es) are encoded in
>> the minor number.
>> The 'device address' on the bus which is also encoded in the minor 
>> number is
>> used by libi2c to address a particular device on a 'bus' during the
>> addressing phase
>> which precedes every read/write operation.
>>   
> Of course - my "off-topic" was meant as a request for explanation WRT 
> how things are done, with the implication that we maintain the same 
> approach.
>> If you have multiple identical controllers you should be able to
>> register them multiple times with libi2c under a different bus number.
>>   
> ...and the "different bus number" is used in the minor number, right?
yep

HTH
-- T.
>
> Things are clearing up around these parts - thanks!
>
> Take care,
> -Bob




More information about the users mailing list