BBBCSIO

InputPort Example Code

 

About the InputPort classes

The InputPort classes are designed to read the state (high or low) of a GPIO pin on the Beaglebone Black. In the Linux operating system there are two ways of accessing the GPIO pins. The first, called the SYSFS method, is the standard and approved Linux technique. During SYSFS accesses each GPIO is exposed as a file in the filesystem and the GPIO is manipulated as if it were a file. The second method, called Memory Mapped access, treats the Beaglebone Black's RAM memory as if it were a file and the GPIO state is manipulated as if it were a bit at an offset in a virtual file.

The major difference between the two techniques is that the SYSFS method is considerably slower than Memory Mapped access. For example, a maximum read frequency of about 1KHz is obtainable with SYSFS whereas something in the order of 1.8MHz (yes, mega Hertz) is obtainable with the Memory Mapped technique. SYSFS is the approved "Linux Way". However, if you need the speed, Memory Mapped access is the way to go.

The BBBCSIO library provides classes for both SYSFS and Memory Mapped access. The classes can be differentiated by the corresponding FS and MM appended to their names. The InputPortFS class provides SYSFS access to the GPIO and the InputPortMM class provides Memory Mapped access.

When should you use SYSFS or Memory Mapped access? Well, in testing, both seemed pretty robust and trouble free. If you need a read frequency greater than about 500Hz (beware the Nyquist Frequency) you'll definitely want to use the InputPortMM class - otherwise the InputPortFS class will probably suffice. Both classes are used in exactly the same way and have exactly identical public members.

Warnings - READ THIS!!!

The example code below uses a GPIO value of 49 which is exposed as pin 23 on the P9 header. You CAN NOT assume that this pin is available as a GPIO on your Beaglebone Black and even if it is a GPIO you still cannot assume it is set as a GPIO input (as opposed to being an output). Any one GPIO can be used for any of about half a dozen different peripherals (UART, SPI bus, PWM, A/D, HDMI, EMMC etc) and it is not a given that a GPIO used in these examples or any specific GPIO is available. The GPIO's used in these examples may be used for other things on your Beaglebone Black.

Before using any InputPort class on a GPIO you will need to ensure that the GPIO is configured as an input. There is no code you can call in the BBBCSIO library which does this. You MUST configure the GPIO externally prior to running your executable - usually this is done by editing the device tree.

Always be aware that the armhf Linux running on the Beaglebone Black is not a real-time operating system. This means, for example, although you might set up an InputPort() object to read at 10000 times a second, the actual timing of some of the reads may vary (and there may be lengthy gaps) as the process is pre-emptively swapped in and out by the kernel.

An Example of the InputPort Usage

The code below illustrates how to use the InputPortMM class to read the state of a GPIO pin and output that state to the console. You could use the SYSFS version by replacing each InputPortMM with an InputPortFS.

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Reads a GPIO port until a key is pressed and puts the value (true or false) 
        /// out to the console. Memory mapped version
        /// 
        /// NOTE: 
        ///   This code assumes that the port associated with the gpioID has been 
        ///   properly configured in the device tree as an input. If it is not
        ///   then the input may not work correctly. See the associated documentation
        /// 
        /// NOTE:
        ///    Be aware of the BBB max input voltage and pullup/pulldown resistors. 
        ///    Be really careful about the voltage you provide here. In general it 
        ///    is usually a good idea to run the input through some sort of buffer
        ///    to cap the max input at the BBB maximum.
        /// 
        /// </summary>
        /// <param name="gpioID">The gpioID</param>
        /// <history>
        ///    28 Aug 14  Cynic - Originally written
        /// </history>
        public void SimpleReadPortMM(GpioEnum gpioID)
        {
            // open the port
            InputPortMM inPort = new InputPortMM(gpioID);

            // look for the input until we have a keypress on the console
            while (Console.KeyAvailable == false)
            {
                bool inVal = inPort.Read();
                Console.WriteLine ("inVal = "+inVal.ToString());
                // sleep for a second
                Thread.Sleep(1000);
            }

            // close the port
            inPort.ClosePort();
            inPort.Dispose();
        }
In the above code, the gpioID is passed in when the function was called. This value is a member of the GpioEnum class which lists all possible GPIO's which can be present on the Beaglebone Black. The above code is called via a line which looks like:
SimpleReadPortMM(GpioEnum.GPIO_49);