GithubHelp home page GithubHelp logo

shangma / prusst Goto Github PK

View Code? Open in Web Editor NEW

This project forked from sbarral/prusst

0.0 2.0 0.0 59 KB

A convenient interface to the UIO kernel module for TI Programmable Real-time Units

License: Apache License 2.0

Rust 100.00%

prusst's Introduction

prusst

Build Status Version

A convenient Rust interface to the UIO kernel module for TI Programmable Real-time Unit coprocessors found among others on the BeagleBone development boards. It provides roughly the same functionality as the C prussdrv library but with a safer, rustic API that attempts to mitigate risks related to uninitialized or invalid register states, use of freed memory, memory allocations conflicts etc.

Documentation

The API documentation lives here.

Background

PRUs (Programmable Real-time Units) are RISC cores integrated into some TI processors such as the AM335x that powers the BeagleBone::{White, Black, Green} development boards. They are what sets the BeagleBone apart from other popular boards such as the Raspberry Pi, allowing real-time process control without the complexity associated with an external co-processor.

PRUs have direct access to some general purpose I/O as well as indirect access to memory and peripherals via an interconnect bus. Their predictable single-cycle instruction execution and absence of pipe-lining or caching is what makes them especially suitable for real-time processing.

Since the PRU assembly language is simple and enables total control of the execution timing, critical real-time portions are typically programmed directly in assembly for the PRU, which cooperates with the host processor for the heavy-lifting (pre and post-processing, communication etc.).

This library provides a relatively simple abstraction over the UIO kernel module which makes it easy to perform common operations such as executing code on the PRU, transferring data between the PRU and the host processor or triggering/waiting for system events.

Design rationale

The design of the library exploits the Rust type system to reduce the risk of shooting onself in the foot. Its architecture is meant to offer improved ergonomics compared to its C relative, while operating at a similarly low level of abstraction and providing equivalent functionality.

Data-race safety is warranted by checking that only one Pruss instance (a view of the PRU subsystem) is running at a time. The magic of the Rust borrowing rules will then statically ensure, inter alia:

  • the absence of memory aliasing for local and shared PRU RAM, meaning that a previously allocated RAM segment may not be re-used before the data it contains is released,

  • the impossibility to request code execution on a PRU core before the code has actually been loaded,

  • the impossibility to overwrite PRU code that is already loaded and still in use,

  • the impossibility to concurrently modify the interrupt mapping.

Type safety also avoids many pitfalls associated with interrupt management. Unlike the C prussdrv library, system events, host interrupt, events out and channels are all distinct types: they cannot be misused or inadvertently switched in function calls. A related benefit is that the interrupt management API is very self-explanatory.

Event handling is one of the few places where prusst requires the user to be more explicit than the C prussdrv library. Indeed, the prussdrv_pru_clear_event function of the C driver automatically re-enables an event out after clearing the triggering system event, which may wrongly suggest that the combined clear-enable operation is thread-safe (it isn't). In contrast, prusst mandates that both Intc::clear_sysevt and Intc::enable_host be called if the event out needs to be caught again. This behavior is probably less surprising and is arguably more consistent with the atomicity of other interrupt management functions.

System prerequisites

The uio_pruss kernel module must be loaded on your system. For the BeagleBone debian distribution, it is available and loaded out-of-the-box with kernel 4.1.x and above on the bone kernel images (in contrast to the TI images which include the remoteproc module instead). You can install the bone image with the --bone-kernel or --bone-rt-kernel options, e.g.:

$ cd /opt/scripts/tools/
$ git pull
$ sudo ./update_kernel.sh --bone-kernel --lts

Installation

Just add the crate to your project's Cargo.toml:

[dependencies]
prusst = "0.1"

Note that Rust 1.9 or above is required.

Cross-compilation

The native Rust toolchain runs flawlessly on the BeagleBone debian distribution, provided that there is enough spare room (if HDMI is not used, the console debian image is a good option). As can be expected though, compilation is a bit slowish.

Cross-compilation can solve this problem and is surprisingly simple, courtesy of rustup.rs. Assuming a multiarch-enabled Ubuntu/Debian box, Rust can be set up on the host machine with rustup.rs using this excellent cross-compilation guide. If the host machine runs Debian Jessie, you may first need to add:

deb http://emdebian.org/tools/debian/ jessie main

to your /etc/apt/source.list to be able to install the cross-toolchain.

Hello world

extern crate prusst;

use prusst::{Pruss, IntcConfig, Sysevt, Evtout};
use std::fs::File;

fn main() {
    // Configure and get a view of the PRU subsystem.
    let mut pruss = Pruss::new(&IntcConfig::new_populated()).unwrap();
    
    // Get a handle to an event out before it is triggered.
    let irq = pruss.intc.register_irq(Evtout::E0);

    // Open, load and run a PRU binary.
    let mut file = File::open("hello.bin").unwrap();
    unsafe { pruss.pru0.load_code(&mut file).unwrap().run(); }
    
    // Wait for the PRU code from hello.bin to trigger an event out.
    irq.wait();
    
    // Clear the triggering interrupt.
    pruss.intc.clear_sysevt(Sysevt::S19);

    // Do nothing: the `pruss` destructor will stop any running code and release ressources.
    println!("We are done...");
}

Examples

More advanced usage of the library is demonstrated in the examples, such as PRU RAM allocation, 2-ways communication with PRU, concurrent management of IRQs, etc.

Assuming the prusst crate has been locally cloned and the PASM assembler is installed (if not, just apt-get the am335x‑pru‑package), the first step before running the examples is to compile the PRU programs. This can be done in one go from the root crate directory with:

$ cd examples; sh make_pru_binaries.sh; cd ..

You can then proceed to build the examples, e.g.:

$ cargo build --example barebone_blink

If you have a BeagleBone board and a loaded cape that enables the PRU (such as cape-universal and friends), you can right away blink your on-board USR LEDs with the barebone_blink or barebone_parallel_blink examples. They must be run with root privilege from a location containing an examples directory with the PRU executables:

$ ls examples/*.bin
examples/barebone_blink_pru0.bin  examples/barebone_blink_pru1.bin  examples/pwm_generator.bin
$ sudo /path_to_executable/barebone_blink

If you do not have a BeagleBone and a PRU-enabling cape, or if you want to run the pwm_generator example, you should install the prusst-examples overlay provided in the examples directory. This overlay enables the PRU subsystem and a PRU-privileged GPIO (pr1_pru0_pru_r30_1, a.k.a. pin P9_29 on the BeagleBone).

The overlay is compiled, installed and loaded as usual with:

$ dtc -O dtb -o examples/prusst-examples-00A0.dtbo -b 0 -@ examples/prusst-examples.dts
$ sudo cp examples/prusst-examples-00A0.dtbo /lib/firmware
$ sudo sh -c "echo 'prusst-examples' > /sys/devices/platform/bone_capemgr/slots"

IMPORTANT: the prusst-examples overlay is incompatible with HDMI on the BeagleBone Black and other HDMI-equipped boards. To avoid any problem, no HDMI-enabling cape should be loaded at boot time (it is apparently not enough to just unload them).

License

This software is licensed under the Apache License, Version 2.0 or the MIT license, at your option.

Copyright (c) 2016 Serge Barral.

This library is named after French novelist Marcel Prusst (1871-1922). Well, almost.

prusst's People

Watchers

 avatar  avatar

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.