GithubHelp home page GithubHelp logo

piranha32 / iooo Goto Github PK

View Code? Open in Web Editor NEW
24.0 8.0 7.0 2.15 MB

Cross-platform object oriented IO library

License: GNU Lesser General Public License v3.0

C++ 19.91% C 0.26% Shell 63.75% Makefile 14.66% M4 1.43%

iooo's Introduction

====== Table of contents

What it is

IOoo is an object oriented, universal framework that allows to write applications that can be easily ported between different platforms. The library's core are basic I/O operations, like GPIO, SPI, I2C, etc. The next layer is built by simple device drivers, implementing basic functions of connected devices. The interface is defined by an abstract class, which describes what functions can be called by the higher layers. Except for instantiation, the application should always refer to the methods defined by the generic interface. Implementations can contain platform-specific methods, however their use is limited to the parts of the application that are tied to the underlying hardware (i.e. setting pin muxing). Hardware-independent modules should always refer to the generic interfaces.

Currently the interfaces are defined for GPIO, SPI, I2C and ADC. Hardware implementation exists for Beaglebone. Because of the way how the platform-specific classes are implemented, porting the framework to Raspberry PI should be trivial.

Implemented hardware interfaces

  • GPIO: GPIO operations on Beaglebone are implemented using memory mapped interface. This is the fastest way to access the I/O lines.
  • SPI: SPI implementation relies on kernel drivers and accesses SPI buses through the /dev interface. This implementation should be portable across all Linux versions.
  • I2C: I2C implementation also relies on kernel drivers and the /dev interface.
  • ADC: Since it is common to put your own ADC chips on a circuit board for better accuracy, both the native ADC of the BeagleBone and the ability to use external ADCs like the LTC2485 are exposed. The native ADC uses the /sys/device interface and if the 'helper' files change from platform to platform, it is trivial to set the correct file path for each device using a class for each host system. The LTC248X set of chips are built on top of the I2C implementation.

Implemented device drivers

  • HD44780-compatible LCD displays
  • TLC5946 LED controller

Why yet another I/O library?

TL;DR: Because it's better

Details: The framework has been conceived to address my need of having a universal interface that would allow me to prototype, develop and debug applications on general-purpose computer and then quickly move them the target platform based on a small microcontroller. Such approach gives the comfort of using all the development tools that I use every day while working on PC-based projects, while working on a project that will run on a much less capable hardware.

I started to think about such portable framework long time ago. At that time I was using 8-bit microcontrollers, with small amount of RAM. It was possible to write even complex programs using C++, however more advanced language features (like virtual methods) were adding too much overhead to be useful. When I moved my projects to 32bit processors with more memory, such a universal framework started to look like a viable idea. The idea behind the components of the framework is simple:

  • For hardware interfaces define an abstract class which will define all methods used by the application to "talk" to the HW module.
  • The interface contains most commonly used operations, like writing and reading GPIO lines or serial interfaces. The GPIO interface allows to define a group of arbitrary lines and access them as an ordered set of wires. Mapping bits in a word to I/O lines is one of most commonly implemented operations and I wanted to stop implementing it over and over again.
  • More complex devices are handled by device drivers. Writing them may look like unnecessary job for Linux systems, as many of the devices will have drivers in the kernel, however they will come in handy when the application will be running on a much simpler platform, without the support of the underlying OS.
  • Device drivers are split into two parts:
    • Low-level interface, mapping control signals to hardware lines (like "set MODE line to 1", "write 0x3D to DATA lines").
    • Higher level module, implementing device's functionality (like "putChar", "clear", "drawPoint").

Splitting the driver into two parts completely isolates the high-level module from the wire-level interface. The PHY (low level) modules may use the abstract I/O interfaces described above, but they are not required to. As long as the PHY supports all the operations used by the upper layer, the implementation can be as close to the actual hardware as necessary. A good example of this approach is TLC5946 PHY module for Beaglebone. The module is based on generic PHY using GPIOs to control the chip, but uses PRU to generate waveforms required by GSCLK and BLANK lines.

Building and Installation Instructions

You need to have the following tools installed.

  • git
  • gcc-4.7 or higher
  • automake
  • autoconf

Clone the source code from github:

git clone https://github.com/piranha32/IOoo.git

After cloning the repository and cd'ing into the new folder, run the following commands in the terminal.

./configure
make
sudo make install

If you are cross compiling, you can add a --host=cross-compiler-prefix option to the ./configure command.

If there are problems with the ./configure, you can try autoreconf to fix the build scripts.

Tutorial

[TBD]

Known problems and limitations

  • 4-bit interface for HD44780 has not been tested.
  • Linux implementation is not MT-safe
  • Incomplete documentation
  • I2C class and all subclasses of ADC have not yet been formally tested (you can help!)

Future work

  • Write more docs
  • Add more device drivers
  • Split the memory-mapped GPIO interface into two parts:
    • Generic functionality common for all memory-mapped implementations,
    • Platform specific part
  • Port library to Raspberry Pi. SPI should work without any changes, platform specific part of memory mapped GPIO should be very similar to Beaglebone version.
  • Port library to Stellaris/Tiva MCUs. Will require almost complete rewrite to eliminate dynamic memory allocations.

iooo's People

Contributors

cjxd avatar jadedanemone avatar piranha32 avatar schnitzeltony avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iooo's Issues

cross-platform with fatal error: 'linux/i2c.h' file not found

doesnt look that cross-platform to me.
these errors are on macOS, but FreeRTOS or baremetal would have the same problems.

../../include/SPI.h:9:10: fatal error: 'linux/spi/spidev.h' file not found
#include <linux/spi/spidev.h>
../../include/I2C.h:13:10: fatal error: 'linux/i2c.h' file not found
#include <linux/i2c.h>

looks like linux-only to me.

Question: How to include library in C++ project

Hi,

I was wondering how I might be able to include the library for code I have written. I am unable to find anything in /usr/src or any of the other standard install directories on the beaglebone.

Are there .a files or .so files that running make install generates? Or must we build the libraries ourselves.

Could you please provide an example of what files I would need to include, and an example invocation to g++ that I would need to use if I wanted to write a program that utilized the beaglebone's SPI interface via your library?

Thanks!

Brett

SPI setup

Hi
I'm trying to do the same thing with a BeagleBone C++ library. And want to implement your SPI library as it seems more advanced. However, in the SPI::open, shouldn't the pins for the SPI be setup as outputs or inputs? or is this not required for SPI in linux?

cheers
Peter

Bus error

May be related to issue #4.

Line 136 in BeagleGooP.cpp calls the following code:

debug(2,
        "BeagleGooP::enableOutput(): enabling pin %i (%s): port=%i, mask=%08x, OE_REG=%08x\n",
        i, localNames[i], ports[i], masks[i],
        parent->gpios[ports[i]][GPIO_OE_REG / 4]);

On my BeagleBone running their own release of Debian 7 with Linux 3.13, this causes a bus error. In particular the following statement parent->gpios[ports[i]][GPIO_OE_REG / 4].

The gpios[ports[i]] bit is fine, it's just trying to access the OE_REG offset that's the issue here. I'll see what happens if I export the GPIOs as suggested in the other issue whatever that means.

I2C Build Conflict

I get the following error when attempting to build the latest version.

In file included from I2C.cpp:12:0:
/usr/include/linux/i2c-dev.h:38:8: error: redefinition of ‘struct i2c_msg’
 struct i2c_msg {
        ^
In file included from ../include/I2C.h:13:0,
                 from I2C.cpp:8:
/usr/include/linux/i2c.h:68:8: error: previous definition of ‘struct i2c_msg’
 struct i2c_msg {
        ^
 In file included from I2C.cpp:12:0:
/usr/include/linux/i2c-dev.h:90:7: error: redefinition of ‘union i2c_smbus_data’
 union i2c_smbus_data {
       ^
In file included from ../include/I2C.h:13:0,
                 from I2C.cpp:8:
/usr/include/linux/i2c.h:128:7: error: previous definition of ‘union i2c_smbus_data’
 union i2c_smbus_data {
       ^

I'm working on a fix and will have a pull request soon.

Compile for Ubuntu BBB

Hi,

Is there a way to make this library on the BBB running Ubuntu 13.10?
Looking through the makefile, its hard coded for the angstrom distribution.

Thanks

Bus error

Code generates a bus error when the GPIO's are not exported via /sys/class/gpio.
I did'nt do in depth research but I've heard it might be a clock issue.

BTW,
This is a exelent library for the HD44870 displays. I had some stability issues in my own code.
4-bit interface is tested and works a treat!

build error

Hi there,

I get the following error after calling make to build the latest version:

make[2]: Entering directory `/home/ubuntu/external_drivers/IOoo/examples'

g++ -DHAVE_CONFIG_H -I. -I..  -I../include/  -D_HW_PLATFORM_BEAGLEBONE    -g -O2 -std=gnu++11 -MT TestLCD.o -MD -MP -MF .deps/TestLCD.Tpo -c -o TestLCD.o TestLCD.cpp

TestLCD.cpp: In constructor 'TestLCD::TestLCD(int)':

TestLCD.cpp:45:55: error: 'debug' was not declared in this scope
   debug(0, "Incorrect number of bits in LCD interface");
                                                                                    ^
make[2]: *** [TestLCD.o] Error 1

make[2]: Leaving directory `/home/ubuntu/external_drivers/IOoo/examples'

make[1]: *** [all-recursive] Error 1

make[1]: Leaving directory `/home/ubuntu/external_drivers/IOoo'

make: *** [all] Error 2


... SPI::SharedResources&)' is implicitly deleted because the default definition would be ill-formed

I'm running into the following problem when I try to compile. Here's the output of my uname -a if it helps. I'm running a Wheezy release, with an updated 3.8 real time kernel.

Linux bbb-rs02 4.1.34-bone-rt-r24 #1 PREEMPT RT Thu Oct 13 04:12:45 UTC 2016 armv7l GNU/Linux

Any ideas how to fix? Alternately, I only need GPIO functionality. Is there any way to split only that out to bypass this error?

Thanks for any help!
Dave

(CDPATH="${ZSH_VERSION+.}:" && cd . && /bin/bash /root/devel/3rdparty/IOoo/IOoo/missing --run autoheader)
rm -f stamp-h1
touch config.h.in
cd . && /bin/bash ./config.status config.h
config.status: creating config.h
config.status: config.h is unchanged
make  all-recursive
make[1]: Entering directory `/root/devel/3rdparty/IOoo/IOoo'
Making all in src
make[2]: Entering directory `/root/devel/3rdparty/IOoo/IOoo/src'
/bin/bash ../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I..  -I../include/ -D_HW_PLATFORM_BEAGLEBONE -D_KERNEL_VERSION=\"0.0\" -DDEBUG_LEVEL=0   -g -O2 -std=gnu++11 -MT I2C.lo -MD -MP -MF .deps/I2C.Tpo -c -o I2C.lo I2C.cpp
libtool: compile:  g++ -DHAVE_CONFIG_H -I. -I.. -I../include/ -D_HW_PLATFORM_BEAGLEBONE -D_KERNEL_VERSION=\"0.0\" -DDEBUG_LEVEL=0 -g -O2 -std=gnu++11 -MT I2C.lo -MD -MP -MF .deps/I2C.Tpo -c I2C.cpp  -fPIC -DPIC -o .libs/I2C.o
libtool: compile:  g++ -DHAVE_CONFIG_H -I. -I.. -I../include/ -D_HW_PLATFORM_BEAGLEBONE -D_KERNEL_VERSION=\"0.0\" -DDEBUG_LEVEL=0 -g -O2 -std=gnu++11 -MT I2C.lo -MD -MP -MF .deps/I2C.Tpo -c I2C.cpp -o I2C.o >/dev/null 2>&1
mv -f .deps/I2C.Tpo .deps/I2C.Plo
/bin/bash ../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I..  -I../include/ -D_HW_PLATFORM_BEAGLEBONE -D_KERNEL_VERSION=\"0.0\" -DDEBUG_LEVEL=0   -g -O2 -std=gnu++11 -MT SPI.lo -MD -MP -MF .deps/SPI.Tpo -c -o SPI.lo SPI.cpp
libtool: compile:  g++ -DHAVE_CONFIG_H -I. -I.. -I../include/ -D_HW_PLATFORM_BEAGLEBONE -D_KERNEL_VERSION=\"0.0\" -DDEBUG_LEVEL=0 -g -O2 -std=gnu++11 -MT SPI.lo -MD -MP -MF .deps/SPI.Tpo -c SPI.cpp  -fPIC -DPIC -o .libs/SPI.o
In file included from /usr/include/c++/4.7/utility:72:0,
                 from /usr/include/c++/4.7/tuple:38,
                 from /usr/include/c++/4.7/mutex:39,
                 from ../include/SPI.h:11,
                 from SPI.cpp:8:
/usr/include/c++/4.7/bits/stl_pair.h: In instantiation of 'constexpr std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = const int; _T2 = SPI::SharedResources]':
/usr/include/c++/4.7/bits/stl_map.h:458:11:   required from 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = int; _Tp = SPI::SharedResources; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, SPI::SharedResources> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = SPI::SharedResources; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]'
SPI.cpp:54:54:   required from here
/usr/include/c++/4.7/bits/stl_pair.h:105:31: error: use of deleted function 'SPI::SharedResources::SharedResources(const SPI::SharedResources&)'
In file included from SPI.cpp:8:0:
../include/SPI.h:30:10: note: 'SPI::SharedResources::SharedResources(const SPI::SharedResources&)' is implicitly deleted because the default definition would be ill-formed:
../include/SPI.h:30:10: error: use of deleted function 'std::recursive_mutex::recursive_mutex(const std::recursive_mutex&)'
In file included from ../include/SPI.h:11:0,
                 from SPI.cpp:8:
/usr/include/c++/4.7/mutex:204:5: error: declared here
make[2]: *** [SPI.lo] Error 1
make[2]: Leaving directory `/root/devel/3rdparty/IOoo/IOoo/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/root/devel/3rdparty/IOoo/IOoo'
make: *** [all] Error 2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.