pru

package module
v0.0.0-...-02ff089 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 27, 2023 License: Apache-2.0 Imports: 6 Imported by: 0

README

pru-rp

Go library for accessing the TI PRU using the RemoteProc framework. This API is used in more recent kernels.

godoc for this package is available.

Examples

The examples use firmware from the TI PRU Software Support package examples. The environment variable PRU_SSP should be set to the location of the package, and the go generate command can be used to build and install the firmware.

export PRU_SSP=~/git.ti.com/pru-software-support-package
cd examples/echo
go generate

The examples used are:

Example Firmware file Example source from package
echo am335x-pru{0,1}-echo{0,1}-fw examples/am335x/PRU_RPMsg_Echo_Interrupt{0,1}
base am335x-pru0-halt-fw examples/am335x/PRU_Halt

Sample skeleton application

import "github.com/aamcrae/pru-rp"

func main() {
	p, _ := pru.Open(0)            // Open PRU0
	defer p.Close()
	p.Load("am335x-pru0-echo0-fw") // Load the firmware from /lib/firmware
	p.Callback(func (msg []byte) { // Add callback
		fmt.Printf("msg = [%s]\n", buf)
    })
	p.Start(true)                 // Start the PRU (RPMsg required)
	p.Send([]byte("Test string"))  // Send a message.
	time.Sleep(time.Second)        // Wait for message reply
}

Accessing Shared Memory

The host CPU can access the various RAM blocks on the PRU subsystem, such as the PRU unit 0 and 1 8KB RAM and the 12KB shared RAM. These RAM blocks are exported as byte slices ([]byte) initialised over the RAM block as a byte array.

Permissions

The PRU memory is accessible via the /dev/mem device, so to read or write to the memory, the program must have read/write access to this device. The easiest way is by running the program as root, or using sudo. With earlier kernels, it was possible to change the /dev/mem permissions to 0660 (to allow group r/w access), and add the user account to group kmem, but this is no longer enough as the CAP_SYS_RAWIO capability is also required to access this device.

Shared Memory API

There are a number of ways that applications can access the shared memory as structured access. For ease of access, the package exports a variable Order (as a binary/encoding Order). This allows use of the binary/encoding package:

	p := pru.Open()
	r := pru.Ram()
	pru.Order.PutUint32(r.Memory[0:], word1)
	pru.Order.PutUint32(r.Memory[4:], word2)
	pru.Order.PutUint16(r.Memory[offs:], word2)
	...
	v := pru.Order.Uint32(r.Memory[20:])

Of course, since the RAM is presented as a byte slice, any method that uses a byte slice can work:

	r := pru.Ram()
	s := pru.SharedRam()
	f := os.Open("MyFile")
	f.Read(r.Memory[0x100:0x1FF])
	data := make([]byte, 0x200)
	copy(data, s.Memory[0x400:])

The RAM objects support the Reader/Writer interface:

	p := pru.Open()
	r := p.Ram()
	params := []interface{}{
		uint32(event),
		uint32(intrBit),
		uint16(2000),
		uint16(1000),
		uint32(0xDEADBEEF),
		uint32(in),
		uint32(out),
	}
	for _, v := range params {
		binary.Write(r, pru.Order, v)
	}
	...
	r.Seek(my_offset, io.SeekStart)
	fmt.Fprintf(r, "Config string %d, %d", c1, c2)
	r.WriteAt([]byte("A string to be written to PRU RAM"), 0x800)
	r.Seek(0, io.SeekStart)
	b1 := r.ReadByte()
	b2 := r.ReadByte()
	...
Synchronisation

A caveat is that the RAM is shared with the PRU, and Go does not have any explicit way of indicating to the compiler that the memory is shared, so potentially there are patterns of access where the compiler may optimise out accesses if care is not taken - reads and writes may also be subject to reordering.

If the memory is accessed when the PRU units are disabled, then using the Reader/Writer interface or the binary/encoding methods described above should be sufficient.

For accesses that do rely on explicit ordering for reading or writing, or for when memory accesses may be concurrent with PRU access, it is recommended that the sync/ataomic and unsafe packages are used to access the memory:

	p := pru.Open()
	r := pru.Ram()
	shared_rx := (*uint32)(unsafe.Pointer(&r.Memory[rx_offs]))
	shared_tx := (*uint32)(unsafe.Pointer(&r.Memory[tx_offs]))
	// Load and run PRU program ...
	for {
		n := atomic.LoadUint32(shared_rx)
		// process data from PRU
		...
		// Store word in PRU memory
		atomic.StoreUint32(shared_tx, 0xDEADBEEF)
	}

Disclaimer

This is not an officially supported Google product.

Documentation

Overview

Package pru-rp provides a Go library to access the Programmable Real-time Units (PRU) of the TI AM335x (https://www.ti.com/processors/sitara-arm/applications/industrial-communications.html) The commonly available product with this part is the Beaglebone Black (https://beagleboard.org/black)

The RemoteProc (https://software-dl.ti.com/processor-sdk-linux/esd/docs/08_00_00_21/linux/Foundational_Components/PRU-ICSS/Linux_Drivers/RemoteProc.html) framework is used, which is standard on recent Linux kernels, and optional on earlier (<4.19) kernels

This package does not include any support for developing or building the PRU firmware; for that, the standard TI PRU S/W support package should be used (https://git.ti.com/cgit/pru-software-support-package).

Complete documentation is available via https://github.com/aamcrae/pru-rp, and through godoc at https://pkg.go.dev/github.com/aamcrae/pru-rp

Index

Constants

View Source
const (
	RpBufSize = 512
)

Device paths etc.

Variables

Functions

func Duration

func Duration(ticks int) time.Duration

Duration converts instruction cycles to time.Duration

func MicroSeconds2Ticks

func MicroSeconds2Ticks(m int) int

Return the number of instruction cycles for the microseconds specified.

func Ticks

func Ticks(d time.Duration) int

Return the number of instruction cycles for the duration specified.

Types

type PRU

type PRU struct {
	// contains filtered or unexported fields
}

func Open

func Open(unit int) (*PRU, error)

Open initialises the PRU.

func (*PRU) Callback

func (p *PRU) Callback(f func([]byte)) error

Callback sets the callback for any events This must be set before the PRU is started.

func (*PRU) Close

func (p *PRU) Close()

Close shuts down the PRU

func (*PRU) Load

func (p *PRU) Load(name string) error

Load writes the name of the firmware to be loaded. This is a file that resides in /lib/firmware. If the PRU is currently running, it is stopped first.

func (*PRU) Ram

func (p *PRU) Ram() (*RamIO, error)

Ram creates a type that can use a Reader/Writer interface to the underlying byte array of this PRU's RAM.

func (*PRU) Send

func (p *PRU) Send(buf []byte) error

Send sends a message to this PRU via RPMsg

func (*PRU) SharedRam

func (p *PRU) SharedRam() (*RamIO, error)

SharedRam creates a type that can use a Reader/Writer interface to the underlying byte array for the shared PRU RAM.

func (*PRU) Start

func (p *PRU) Start(rpmsg bool) error

Start writes the start command to the PRU, and sets up the RPMsg device (if required). rpmsg is set if the PRU requires the RPMsg virtual device.

func (*PRU) Status

func (p *PRU) Status() Status

Status returns the current status of the PRU

func (*PRU) Stop

func (p *PRU) Stop() error

Stop writes the stop command to the PRU

type RamIO

type RamIO struct {
	Memory []byte
	// contains filtered or unexported fields
}

RamIO implements various io interfaces, using an underlying byte array.

func (*RamIO) Read

func (r *RamIO) Read(p []byte) (int, error)

func (*RamIO) ReadAt

func (r *RamIO) ReadAt(p []byte, offs int64) (int, error)

func (*RamIO) ReadByte

func (r *RamIO) ReadByte() (byte, error)

func (*RamIO) Seek

func (r *RamIO) Seek(offs int64, whence int) (int64, error)

Seek moves the offset

func (*RamIO) Write

func (r *RamIO) Write(p []byte) (int, error)

Write copies the byte slice into the RAM array

func (*RamIO) WriteAt

func (r *RamIO) WriteAt(p []byte, offs int64) (int, error)

WriteAt copies the byte slice into the RAM array at the offset specified

func (*RamIO) WriteByte

func (r *RamIO) WriteByte(b byte) error

type Status

type Status int
const (
	StatusOffline Status = iota
	StatusRunning
	StatusUnknown
)

Status values

func (Status) String

func (s Status) String() string

String returns string value of status.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL