This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I have a problem sending an interrupt from PRU to linux kernel module
on a am335. I tried on beaglebone with TI debian and bullseye images.
Any help would be appreciated as i'm stuck...
Context: A fairly common and simple scenario of writing a double buffer
to PRU memory from kernel module and read it with PRU1. PRU sends an
interrupt when it starts reading a buffer.
What i have done:
- I use IEP for timing purposes in PRU. Interrupt mapping and catching works.
- Instead mapping to host 6/7 to interrupt arm i temporarily mapped to
host 0/1 to check correctness. I can catch it with the other PRU.
- I can write PRU memory from user space and kernel module (both
verified with scope on io pins written with pru)
- irq_request in kernel module returns 0. Kernel module shows up in
/proc/interrupts
Literally everthing works except the interrupt signal from PRU to ARM.
The commented sections where tryouts. The unspecific FFFF settings are
also tryouts. I also tried only setting specific bits.
I also tried other events/channels/interrupts...
ko
result = request_irq(24, pru_output0_irq_handler, IRQF_TRIGGER_RISING, "testirq", NULL); result = request_irq(25, pru_output1_irq_handler, IRQF_TRIGGER_RISING, "testirq", NULL);
CT_INTC.SIPR0 = 0xFFFFFFFF; CT_INTC.SIPR1 = 0xFFFFFFFF; CT_INTC.SITR0 = 0; CT_INTC.SITR1 = 0; CT_INTC.SECR0 = 0xFFFFFFFF; CT_INTC.SECR1 = 0xFFFFFFFF; CT_INTC.ESR0 = 0xFFFFFFFF; CT_INTC.ESR1 = 0xFFFFFFFF; CT_INTC.CMR1_bit.CH_MAP_7 = 1; CT_INTC.CMR4_bit.CH_MAP_16 = 6; CT_INTC.CMR4_bit.CH_MAP_17 = 7; CT_INTC.HMR0_bit.HINT_MAP_1 = 1; CT_INTC.HMR1_bit.HINT_MAP_6 = 6; CT_INTC.HMR1_bit.HINT_MAP_7 = 7; //CT_INTC.SICR = 16; //CT_INTC.SICR = 17; //CT_INTC.EISR = 16; //CT_INTC.EISR = 17; //CT_INTC.HIEISR = 0; CT_INTC.HIEISR = 1; CT_INTC.HIEISR = 6; CT_INTC.HIEISR = 7; CT_INTC.HIER = 0xFFFFFFFF; //CT_INTC.ECR0 = 0xFFFFFFFF; //CT_INTC.ECR1 = 0xFFFFFFFF; //CT_INTC.ESR0 = 0xFFFFFFFF; //CT_INTC.ESR1 = 0xFFFFFFFF; //CT_INTC.GER_bit.EN_HINT_ANY = 0x1; CT_INTC.GER = 1; while(1) { CT_INTC.SECR0 = (1 << 16); __R31 = 0b100000; WRITE_OUTPUT(output0); CT_INTC.SECR0 = (1 << 17); __R31 = 0b100001; WRITE_OUTPUT(output1); }
Thanks
Hello Andreas,
What Linux driver are you using to initialize the PRU firmware? TI's remoteproc driver? The community UIO driver? (not sure if that is still maintained with current releases) Something else?
What Linux driver are you using to receive the interrupts?
By default, TI provides support for initializing the remote core through remoteproc, and communicating with Linux through RPMsg (which is 496 byte messages within a 512 byte total envelope, with an interrupt to notify). We do not provide support for JUST using interrupts to interact with Linux.
Also, please note that the PRU remoteproc driver does not work on Linux kernel 6.1 specifically if RPMsg is used. We are currently working on debugging and providing a patch to fix it on kernel 6.1, and make sure it is fixed going into kernel 6.6.
Regards,
Nick
Hello.
Thanks answering. I dont use any drivers, i just try to receive interrupts in my own kernel module.
Ok, support for such direct use of interrupts is not provided.
Can you point me to an linux user space example for RPMsg ? Do the RPMsg drivers provide source code ?
Regards
Andreas
Hello Andreas,
From the PRU firmware side, the RPMsg libraries are in the PRU Software Support Package (PSSP) here:
https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package/tree/lib
Where the PRU RPMsg example firmware is here:
https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package/tree/examples/am335x/PRU_RPMsg_Echo_Interrupt0
From the Linux side, the PRU RPMsg driver is here
ti-linux-kernel-6.1.80+gitAUTOINC+2e423244f8-ti/drivers/rpmsg/rpmsg_pru.c
(the same driver is also in any other ti-linux-kernel branch, I cannot remember if it is in the upstream tree or not)
Usually when I test RPMsg I do it directly from the command line:
https://software-dl.ti.com/processor-sdk-linux/esd/AM335X/09_01_00_001/exports/docs/linux/Foundational_Components/PRU-ICSS/RPMsg_Quick_Start_Guide.html#rpmsg-quick-start-guide
We do have the Linux userspace ti-rpmsg-char library for later devices like AM62x & AM64x, but so far it looks like it was set up to communicate with M4 / R5/ C7 cores, not PRU cores. But the same basic concepts may apply to AM335x & PRU as well:
https://git.ti.com/cgit/rpmsg/ti-rpmsg-char/
Regards,
Nick
Thanks Nick. I'll try that out. For the moment it should be fast enough.
BTW is source code for the rproc kernel modules available ?
I could analyze it later to check why my code doesnt work.
Hello Andreas,
Yes, the PRU Remoteproc driver is also on the ti-linux-kernel branch here:
drivers/remoteproc/pru_rproc.c
Regards,
Nick