BeagleBoard/GSoC/BeagleLibs

From eLinux.org
Jump to: navigation, search


Summary

Two high quality, well-documented libraries for interfacing with BeagleBone hardware (GPIO, ADC reads, PWM, UART, SPI, and I2C) in Rust and Go.

Student: [1]
Mentors: No mentors were suggested to me in IRC, but the best candidates are probably Vladimir Pantelic and/or Jason Kridner
Code: https://github.com/ekmecic/bb-rust, https://github.com/ekmecic/bb-go
Wiki: http://elinux.org/BeagleBoard/GSoC/BeagleLibs
GSoC: Not up yet.

Status

This project is currently just a proposal.

About you

IRC: ee (have previously gone by yugo/yugo43)
Github: https://github.com/ekmecic, GitHub Hello World pull request
School: University of Waterloo
Country: Canada
Primary language: English
Typical work hours: 8AM-5PM US Eastern
Previous GSoC participation: None.

About your project

Project name: BeagleLibs for Rust and Go

Description

My project is basically two high quality, well-documented libraries for interfacing with BeagleBone hardware in Rust and Go. These libraries will provide interfaces for common usecases like GPIO, ADC reads, PWM, UART, SPI, and I2C (I'm open to more!). The intent of the project is to bridge the gap between the lower level and the higher level languages and make using the BeagleBone accessible to a wider range of users.

People trying to get into hardware projects today are faced with a difficult choices, especially when it comes to the platform their project will be based on. On one end of the spectrum, they can use a platform like Arduino for their project, which is simple but unusable for anything that outside of the realm of a simple tool or prototype. On the other end, they can work with bare metal microcontrollers, but these have a steep learning curve, the pain of setting up toolchains, and usually cost money either for IDEs, flashing hardware, or both. The BeagleBone community has made an great strides toward bridging this gap by with the cheap and approachable BeagleBones, but users are still confronted with the choice of fast/difficult to use C, or easy to use/slow JavaScript.

Users seeking to work on the BeagleBone shouldn't have to face this choice; which is where this project comes in. By providing a well-documented set of libraries for the common tasks that every hardware project uses, users will be able to harness the power of performant languages while still having a pleasant development process. I envision these libraries exposing simple APIs for subsystems like GPIO, ADC reads, PWM, UART, SPI, and I2C (I'm open more!).

At its essence, this project opens up the BeagleBone to a new swath of users by exposing a high quality interface for the BeagleBone in two great languages.

I chose Rust and Go for a few reasons. First, and most importantly, I have experience using both languages. In the case of Rust, I've already used it on the BeagleBone with great success during one of my work semesters. Second, both Rust and Go are relatively new languages that are proving to be popular, and opening the BeagleBone up to these communities can't hurt. Furthermore, they relieve some of the common pain points in the development process, take as an example Rust's cargo build system, which makes setting up a project and the accompanying build system trivial. Lastly, there aren't any libraries out there that do what I'm looking to do. Rust does provide some support for sysfs GPIO and PWM and there is a similar Go library, but neither of these projects reach the level of functionality and documentation that I aim to achieve in this project.

(Tentative) API Examples

I've written up a few simple API examples in Rust-ish pseudocode to give people a better idea of what I'm going for. These are (intentionally) very basic examples which are meant to illustrate the intended nature of the library: easy to use and predictable. Of course, I will add additional functionality for user to be able to configure the devices as they see fit i.e. different SPI modes etc.

GPIO

let gpio = gpio::new(20);
gpio.direction(In);
gpio.on();
gpio.wait_for_edge(Rising);

ADC

let adc = adc::new(62);
let value = adc.read();

PWM

let pwm = pwm::new(40); // Declare a new PWM object on pin 40
pwm.set_duty_cycle_ns(50000); // Duty cycle in nanoseconds
pwm.on(50); // Turn the PWM pin on
pwm.off();

UART

let uart = uart::new(UART1, 115200);
uart.write("lalalalala");
uart.read(10); // Read 10 characters from UART

SPI

let spi = spi::new(SPI1, 50000);
spi.write("lalalalala");
let str = spi.read(10); // Wait for and read 10 data items

I2C

let i2c = i2c::new(I2C1);
i2c.write(0x01, bytes("lalalalala")); // Write "lalalalala" to I2C at address 0x01
let bytes = i2c.read(0x01, 10);


Timeline

My approach divides the project time into two: one half for the Rust library, and the other for Go. I chose this approach because it'll allow me to implement all the lessons I learn from making one library when I make the other, while also allowing me to use community feedback to improve the project while I'm working on it. Provide a development timeline with a milestone each of the 11 weeks. (A realistic timeline is critical to our selection process.)

2017-06-06: Milestone #1: Rust GPIO (incl. documentation and tests) complete
Write an API overview document and accompanying video. Set up git repositories. 2017-06-13: Milestone #2: Rust PWM (incl. documentation and tests) complete
2017-06-20: Milestone #3: Rust ADC (incl. documentation and tests) complete
2017-06-27: Milestone #4: Rust UART (incl. documentation and tests) complete
2017-07-04: Milestone #5: Rust SPI + I2C (incl. documentation and tests) complete
Publish the completed Rust library and seek feedback from a wider audience. 2017-07-11: Milestone #6: Go GPIO (incl. documentation and tests) complete
2017-07-18: Milestone #7: Go PWM (incl. documentation and tests) complete
2017-07-25: Milestone #8: Go ADC (incl. documentation and tests) complete
2017-08-01: Milestone #9: Go UART (incl. documentation and tests) complete
2017-08-08: Milestone #10: Go SPI (incl. documentation and tests) complete
2017-08-15: Milestone #11: Go I2C (incl. documentation and tests) complete
Write a document summarizing the accomplishments of the project and an accompanying video. Publish the completed Go library and seek feedback from a wider audience.

While this timeline might seem "spaced out", I believe anything worth doing is worth doing right, and so I think it's better to spend more time on each feature instead of cramming as much half-baked functionality as possible into the timeline. That's especially important for a tool that will hopefully be used by many people. In addition to what I've written above, I plan on posting weekly reports on the BeagleBone GSoC Google Groups summarizing my progress.

Experience and approach

Experience

My experience with programming and the BeagleBone comes from several different areas. First, I'm currently studying Mechatronics Engineering where we're taught programming from the first semester on, especially on the lower levels of the programming spectrum which are relevant in such a project. Outside of school, I started programming several years ago during high school where I toyed around with C and Python that I taught myself with the aid of books. The most relevant aspect of my experience is that which I gained during my work semesters (students at UW are required to spend a certain number of semesters working in the "real world"). During my last work semester I worked at a firm where several of my projects revolved around the BeagleBone. These projects went from low-level interfacing with the PRU in C for rapid data acquisition to high-level transmission of telemetry data from BeagleBone to PC over UDP sockets. In one of the projects I worked on, I actually wrote my own rudimentary drivers in Rust for the ADC subsystem, and used the Rust libraries for sysfs GPIO and PWM. This gave me a good feel for what was lacking in the currently available libraries as well as where improvements could be made, which I think is a unique perspective when working on such a project. I believe that the experience I've gleaned through school, self-teaching, and work has left me well-prepared to complete this project.

Approach

There's a famous saying deal with software projects: "The first 90% of a project accounts for 90% of the time, and the other 10%, of course, accounts for the other 90% of the time." With that in mind, I designed my timeline to divide the project up into manageable chunks with clearly defined goals and deliverables while also allowing enough time to finish each feature to the quality level I'm aiming for. Each week I plan to have one major feature complete, with documentation and applicable tests, that will be ready for use. This logical structure makes it easy for mentors to ascertain the progress of my project and see what's holding me up and also makes it easy for me to work on the project by dividing up the work in manageable chunks. Furthermore, doing the libraries in series (i.e. the entire Rust library, the the entire Go library) the experience I gain implementing one library will be transferrable and useful for implementing the second one.

In terms of how I plan on carrying out my work, my approach will be simple. I'll carry out my development in two separate git repositories, one for Rust, and one for Go. Each weekday I will devote 3-5 hours on the project and additional time on the weekends as needed with the goal of commiting to the repositories on a daily basis.

Lastly, it's important to note that my project isn't the most technically demanding project in the world. The value in BeagleLibs isn't going to be next-level data structures and algorithms or an especially wide breadth of interfaces, it'll be a clean, consistent, and approachable set of APIs that people can trust to base their projects on. For this purpose, I will have a special emphasis on the documentation and tests that accompany my project because they are essential to it's goals and the success of this project.

Contingency

It feels like I've faced this problem while programming a million times. Based on past experience, it helps to momentarily step away from the computer, relax, have a drink, and approach the problem with a fresh mind. Of course, this doesn't solve every problem, so I've found that turning to friends, IRC, and the internet can be an invaluable source of information which I consult frequently. Besides that, one aspect of this project that I think will be especially conducive to this problem is the fact that there will always be things to work on. Let's say I get stuck on implementing the SPI interface in Rust. I can always turn to adding more docs for GPIO, brainstorming how I'll implement I2C, or troubleshooting other issues and then return to the SPI with a new eye.

Benefit

I believe this library will have several positive impacts on the BeagleBoard.org community:

  1. Introducing more people to the BeagleBoard.org community by using languages that are new and popular
  2. Providing a high quality and well-documented set of libraries in new languages, thereby making the BeagleBone usable in a wider range of projects where people might have not considered it before
  3. Making the BeagleBone more accessible for all users

Quotes

From the #beagle-gsoc IRC:

Mar 17 00:18:09 <nerdboy> i'd say qualified "yes" but beagleslackbot can give a better/more definitive answer...
Mar 21 23:44:48 <m_w> sounds like a valid project

Suggestions

Nothing that I can think of, except perhaps "how do you pronounce your last name?".