Tool/software: TI C/C++ Compiler
Hello,
I am using the PRU of the AM335x SItara Processor from Linux on the Beaglebone Black and I have a few doubts about the PRU itself.
I would resume my question with: is it possible to use the PRU as a standalone micro-controller ?
To explain better what I mean, I will show the following example which performs the following tasks:
- 1 - Toggle the P9_27 GPIO
- 1 - Read the P9_28 GPIO
- 3 - Send an interrupt event to a Linux program if the P9_28 is at logic state 0.
The PRU Assembly code is the following:
// start of program in pru memory
.origin 0
// program entry point (for a debugger)
.entrypoint start
// 5ns per instruction
#define ins_per_us 200
// two instructions per delay loop
#define ins_per_delay_loop 2
#define delay 1 * (ins_per_us / ins_per_delay_loop)
// allows notification of program completion
#define PRU0_R31_VEC_VALID 32
// the event number that is sent back
#define PRU_EVTOUT_0 3
#define GER 0x00020010
#define SECR0 0x00020280
#define SECR1 0x00020284
start:
// turn on the output pin (led on)
set r30.t5
// store the length of the delay in reg0
mov r0, delay
delayon:
// decrement reg0 by 1
sub r0, r0, 1
// loop to delayon, unless reg0=0
qbne delayon, r0, 0
ledoff:
// clear the output bin (led off)
clr r30.t5
// reset reg0 to the length of the delay
mov r0, delay
delayoff:
// decrement reg0 by 1
sub r0, r0, 1
// loop to delayoff, unless reg0=0
qbne delayoff, r0, 0
// is the button pressed? if not, loop
qbbc start, r31.t3
exec_int:
// notify the calling app that finished
mov r31.b0, PRU0_R31_VEC_VALID | PRU_EVTOUT_0
jmp start
and the C program which uses the prussdrv libraries is:
/** Program to load a PRU program that flashes an LED until a button is * pressed. By Derek Molloy, for the book Exploring BeagleBone * based on the example code at: * processors.wiki.ti.com/.../PRU_Linux_Application_Loader_API_Guide */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <prussdrv.h> #include <pruss_intc_mapping.h> #define PRU_NUM 0 // using PRU0 for these examples typedef enum { false, true } bool; int main (void) { int n = 0; int res = 0; if(getuid()!=0) { printf("You must run this program as root. Exiting.\n"); exit(EXIT_FAILURE); } // Initialize structure used by prussdrv_pruintc_intc // PRUSS_INTC_INITDATA is found in pruss_intc_mapping.h tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA; // Allocate and initialize memory res = prussdrv_init (); printf("prussdrv_init = %d\n", res); res = prussdrv_open (PRU_EVTOUT_0); printf("prussdrv_open = %d\n", res); // Map PRU's interrupts prussdrv_pru_reset (0);
res = prussdrv_pruintc_init(&pruss_intc_initdata); printf("prussdrv_pruintc_init = %d\n", res);
// Load and execute the PRU program on the PRU prussdrv_exec_program (PRU_NUM, "./ledButton.bin"); while (true) { // Wait for event completion from PRU, returns the PRU_EVTOUT_0 number n = prussdrv_pru_wait_event(PRU_EVTOUT_0); printf("EBB PRU program completed, event number %d.\n", n); // prussdrv_exec_program (PRU_NUM, "./ledButton.bin"); } // Disable PRU and close memory mappings prussdrv_pru_disable(PRU_NUM); prussdrv_exit (); return EXIT_SUCCESS; }
The program itself works, the GPIO toggles and the interrupt is sent from the PRU and it's catched from the Linux program, but:
- 2 - The PRU is performing a polling on the P9_28 GPIO.
- 2 - After one interrupt event is sent from the PRU to Linux, I am not able to sent it again. I have to reload the firmware to the PRU if I want to re-send the interrupt event.
So the final questions are:
- 3 - Is it possible to generate an hardware interrupt (like GPIO state change) from the PRU before sending a notification to Linux ? In other words let the PRU in a infinite loop and jump to the interrupt vector if an hardware interrupt is generated.
- 3 - Is it possible to re-send the interrupt event to Linux without having to reload the PRU firmware ?
Could you confirm is tasks 1.3 and 2.3 are possible or not ?
If they are possible I am of course missing some information from the AM335x Techincal Reference manual. In this case could you point me to the right sections or give me some suggestion ?
Thank you.
Regards,
Simon