Page MenuHomeFreeBSD

Increase interrupt capabilities of ti_pruss driver

Authored by on Aug 10 2017, 5:54 PM.



The ti_pruss driver for the PRUSS Hardware provided by the AM335x ARM CPU has basic interrupt capabilities. The updated driver provides some more options:

  • sysctl based configuration for the interrupts (examples see test plan)
  • a device file ( /dev/pruss0.irqN) for each enabled interrupt. This file can be read and the device blocks if no irq has happened or returns an uint64_t timestamp based on nanouptime()
  • each interrupt device file provides kqueue-based event notification, blocking read() or select().
Test Plan

These steps have been done as a simple test

Configure and enable the PRUSS interrupts:

sysctl # mapping channel 2 to irq2
sysctl dev.ti_pruss.0.irq.2.event=16 # mapping event 16 to irq2
sysctl dev.ti_pruss.0.irq.2.enable=1 # enable the irq2
sysctl dev.ti_pruss.0.global_interrupt_enable=1 # enable PRU global interrupts

PRU-Code, named test.p (assembler is in Ports devel/pasm)

.origin 0
.entrypoint START
ZERO &r0, 120
MOV r31, (1 << 5) 

Assembling the pru code (result is file test.bin)

pasm -V3 -bL test.p

Loading the binary into the PRU0 with pructl (from ports devel/pructl)

# -p 0 is pru0, -t ti is type Texas Instruments, -er means enable+reset
pructl -p 0  -t ti -er test.bin

read interrupt file:

#include <sys/time.h>                                                                                                                                                            
#include <sys/types.h>                                                                                                                                                           
#include <sys/event.h>                      
#include <err.h>                            
#include <fcntl.h>                          
#include <stdio.h>                          
#include <stdlib.h>                         
#include <string.h>                         
#include <unistd.h>                         
#include <signal.h>                         

int main( int argc, char* argv[] )          
        int fd;                         

        printf("opening of %s ", argv[1]);  
        fd = open( argv[1], O_RDONLY);      

        if (fd == -1) 

                uint64_t time;                      
                while( read(fd, &time, sizeof(time)) > 0 )                              
                        printf("=> %llu.%09llu \n", time/1000000000, time%1000000000);  

        return EXIT_SUCCESS;                

The read-test program should print the timestamps of the interrupts as uptime in nanoseconds

Diff Detail

Lint Skipped
Unit Tests Skipped

Event Timeline changed the visibility from "Custom Policy" to "All Users".

Fix re-enabling interrupts changed the visibility from "All Users" to "Public (No Login Required)".Aug 14 2017, 5:51 AM
ian requested changes to this revision.Sep 10 2017, 7:37 PM
ian added a subscriber: ian.

It looks like nobody has picked up this change. I can't comment on the pruss functionality, but I've added some comments on style stuff. If no other committers are familiar with the pruss hardware and want to take this, I'm inclined to commit it (after a bit of style cleanup) and if it breaks any existing users, we'll just deal with the problems as they come up.


I don't think it's worth creating a whole malloc category for an 8-byte allocation per open device, unless there's anticipation of thousands of open instances or something. For small incidental allocations by drivers, use M_DEVBUF.


This mallocs sizeof pointer bytes.


Negative return values are a linux thing, in freebsd return just the error named constant (and style rules say to put it in parens), so

return (ENOMEM);

That applies to all return statements throughout the code, they all have to be in parens.


Style rules require K&R braces style (opening brace on the same line as the if/for/while/whatever).


Style rules require if statements to be split onto two (or more0 lines.


Use %d for signed integer in printf.


Style rules say all vars have to be declared at the top of the function, not inline like this.

This revision now requires changes to proceed.Sep 10 2017, 7:37 PM

Updated diff according to Ians remarks.

Thanks for making all these tedious style changes, this looks good. I'm going to commit it as soon as test builds complete.

This revision is now accepted and ready to land.Oct 2 2017, 12:52 AM
This revision was automatically updated to reflect the committed changes.

Mostly style issues.

30–32 ↗(On Diff #33619)

These are out of order.

35 ↗(On Diff #33619)

And this

42 ↗(On Diff #33619)

sys/types.h is included from sys/param.h so is unneeded.

50 ↗(On Diff #33619)

And this

183–184 ↗(On Diff #33619)

This malloc can't fail. M_WAITOK will always return a valid pointer.

209 ↗(On Diff #33619)

return (...);

213 ↗(On Diff #33619)

And here.

237–238 ↗(On Diff #33619)

if (...) {

264 ↗(On Diff #33619)

Missing a space after the brace.

313–315 ↗(On Diff #33619)

The brace shouldn't be on a new line.

374 ↗(On Diff #33619)

Should be a /* */ comment

380 ↗(On Diff #33619)

Extra space after a bracket