I’m trying to get the hang of the pru and all the examples segfault out of the gate. So I grabbed TI’s skeleton code and tried compiling and running that, segfault. I reduced it down to the first line, fine. First 3, segfault. Comment out prussdrv_open, fine. Thow -g at the compiler and run it under gdb and that really narrows it down:
“Program received signal SIGSEGV, Segmentation fault.
0xb6fc9eec in __pruss_detect_hw_version () from /usr/lib/libprussdrv.so”
gdb doesn’t really have a reference once it gets into that library so I can’t see my surroundings. There are zero results for this in google. Has anyone seen this before? I must be missing something pretty simple.
Did you load one of the PRU device tree overlays? Most of the hardware
on the SoC defaults to "off" (powered down with no clock signal) until
you explicitly enable it via loading it's driver. Trying to access the
hardware before it is enabled typically results in hardware bus faults,
which are likely showing up as segment faults in the debugger.
I have TI’s example code exactly
[code]
#include <prussdrv.h>
#include <pruss_intc_mapping.h>
#define PRU_NUM 0
/* IRQ handler thread */
void *pruevtout0_thread(void *arg) {
do {
prussdrv_pru_wait_event (PRU_EVTOUT_0);
prussdrv_pru_clear_event (PRU0_ARM_INTERRUPT);
} while (1);
}
void main (void)
{
/* 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 */
prussdrv_init ();
prussdrv_open (PRU_EVTOUT_0);
/* Map PRU’s INTC */
prussdrv_pruintc_init(&pruss_intc_initdata);
/* Load and execute binary on PRU */
prussdrv_exec_program (PRU_NUM, “./PRU_example.bin”);
/* Wait for event completion from PRU */
prussdrv_pru_wait_event (PRU_EVTOUT_0); // This assumes the PRU generates an interrupt
// connected to event out 0 immediately before halting
/* Disable PRU and close memory mappings */
prussdrv_pru_disable(PRU_NUM);
prussdrv_exit ();
}[/code]
for the pru code I have an example I found online:
#define GPIO1 0x4804c000
#define GPIO_CLEARDATAOUT 0x190
#define GPIO_SETDATAOUT 0x194
MOV r1, 10
BLINK:
MOV r2, 7<<22
MOV r3, GPIO1 | GPIO_SETDATAOUT
SBBO r2, r3, 0, 4
MOV r0, 0x00a00000
DELAY:
SUB r0, r0, 1
QBNE DELAY, r0, 0
MOV r2, 7<<22
MOV r3, GPIO1 | GPIO_CLEARDATAOUT
SBBO r2, r3, 0, 4
MOV r0, 0x00a00000
DELAY2:
SUB r0, r0, 1
QBNE DELAY2, r0, 0
SUB r1, r1, 1
QBNE BLINK, r1, 0
I compile it with pasm using the -b option.
It stopped segfaulting when I sudoed the program so I copied in the whole code. The compiler complains that there aren’t enough parameters for prussdrv_pru_clear_event. The header does have two parameters but all other TI documentation only has one. If I just throw a zero as the second parameter it will run but does nothing because who knows what I’m doing.
"It stopped segfaulting when I sudoed the program so I copied in the whole code. The compiler complains that there aren’t enough parameters for prussdrv_pru_clear_event. The header does have two parameters but all other TI documentation only has one. If I just throw a zero as the second parameter it will run but does nothing because who knows what I’m doing. "
- show quoted text -
In several examples I see: prussdrv_pru_clear_event (PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
I’m trying to get a feel for this too. Maybe this will help.
You have responded to this at a fortuitous time. I JUST got it working on an example code.
- I edited the device tree turning on the PRUSS system and turning off the status lights
- modprobe uio_pruss
- sudo ./[program name]
and boom it started blinking just as it should. Now it doesn’t exit properly and I will have to play with the clear_event() to see if that’s the root but I’m very happy with it right this second.
Okay so this is weird. It’s been working fine for the past few days. I uploaded code that I was testing and it wasn’t responding like I expected so I ctl-c out of the program. I edited the code and ran it again but it failed to exit like normal. So I restarted the BB, modprobed, edited the code so all it does is turn on a light and exit. I run it but the light doesn’t come on and it doesn’t exit.
How is it fine one second and not loading the next? Is it possible for PRUs to be hard hung? I wouldn’t think they could keep code after a reset.
I found tonight someone has made a CLI debugger called prudebugger. Beautiful piece of work. In single stepping and general breaking in my code I realized the code was getting lost in an SBBO. When it does that it seems to stop responding to resets. It has to be halted manually and then reset. Anyone seen this?
the code is very standard
`
#define GPIO1 0x4804c000
#define GPIO_CLEARDATAOUT 0x190
MOV r2, 1<<21
MOV r3, GPIO1 | GPIO_CLEARDATAOUT
SBBO r2, r3, 0, 4
`
Is that the entire program? You have to enable the bridge to the SoC
interconnect bus before doing memory accesses to things like the GPIO
banks. That could be why your program is "getting lost".
Not the entire thing but I definitely didn’t know about a SOC bridge. That section of code is a derivation on:
http://boxysean.com/blog/2012/08/12/first-steps-with-the-beaglebone-pru/
Nothing is ever said about that and it worked for quite a few runs before becoming lost. However, I’m more than willing to try enabling it but I’m having trouble finding mention of it.
In the PRU Reference Guide, see section 11.1.2 on the SYSCFG register.
This is why you typically see something like the following at the start
of most PRU programs:
// Clear syscfg[standby_init] to enable ocp master port
LBCO r0, CONST_PRUCFG, 4, 4
CLR r0, r0, 4
SBCO r0, CONST_PRUCFG, 4, 4
Fantastic. That restored SBBO for me. Thanks a bunch!