Debian <--> PRUSS communication

186 views
Skip to first unread message

Paul Van den Bergh

unread,
Aug 29, 2017, 5:54:16 PM8/29/17
to BeagleBoard
Hello,

Since I'm new to this forum, I will introduce myself.  I'm C/C++ software engineer and have experience with, among other things, Atmel AVR and SAM (Cortex) .  Recently I started playing with embedded Linux (Raspberry Pi and Beaglebone Black) as a hobby project.  My goal is to develop a DCC Central using the Beaglebone Black platform.

I'm using Code Composer Studio V7 (on Windows) to write, compile and debug code on the BBB (for the pru using a Blackhawk USB100v2 JTAG emulator).  On the BBB I flashed the latest IoT release :

debian@beaglebone:~$ uname -a
Linux beaglebone 4.4.84-ti-r120 #1 SMP Sun Aug 27 03:11:07 UTC 2017 armv7l GNU/Linux
debian@beaglebone
:~$ cat /etc/dogtag
BeagleBoard.org Debian Image 2017-08-24
debian@beaglebone
:~$

The BBB is plugged in a Newhaven 7" LCD cape (functional in character mode), but I cannot see the cape loaded :

debian@beaglebone:~$ cat /sys/devices/platform/bone_capemgr/slots
 
0: ---l--  -1
 
1: ------  -1
 
2: ---l--  -1
 
3: ---l--  -1
debian@beaglebone
:~$

Since I can compile C code in CCS and debug PRU code on the device, I think the pru's are operational :

debian@beaglebone:~$ lsmod | grep pru
pru_rproc              
15879  2
pruss_intc              
9009  1 pru_rproc
pruss                  
12346  1 pru_rproc
debian@beaglebone
:~$

Now I'm looking into ways to write a linux app that can communicate with the PRU firmware.  Am I correct in assuming that rpmsg is the way to go ?  After google-ing a lot and reading about the subject, I try to run this code :

int main(void)
{
   
struct pru_rpmsg_transport transport;
    uint16_t src
, dst, len;
   
volatile uint8_t *status;

   
/* Allow OCP master port access by the PRU so the PRU can read external memories */
    CT_CFG
.SYSCFG_bit.STANDBY_INIT = 0;

   
/* Clear the status of the PRU-ICSS system event that the ARM will use to 'kick' us */
    CT_INTC
.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;

   
/* Make sure the Linux drivers are ready for RPMsg communication */
    status
= &resourceTable.rpmsg_vdev.status;
   
while (!(*status & VIRTIO_CONFIG_S_DRIVER_OK));

   
/* Initialize the RPMsg transport structure */
    pru_rpmsg_init
(&transport, &resourceTable.rpmsg_vring0, &resourceTable.rpmsg_vring1, TO_ARM_HOST, FROM_ARM_HOST);

   
/* Create the RPMsg channel between the PRU and ARM user space using the transport structure. */
   
while (pru_rpmsg_channel(RPMSG_NS_CREATE, &transport, CHAN_NAME, CHAN_DESC, CHAN_PORT) != PRU_RPMSG_SUCCESS);

   
while(1)
   
{
       
/* Check bit 30 of register R31 to see if the ARM has kicked us */
       
if (__R31 & HOST_INT)
       
{
           
/* Clear the event status */
            CT_INTC
.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;
           
/* Receive all available messages, multiple messages can be sent per kick */
           
while (pru_rpmsg_receive(&transport, &src, &dst, payload, &len) == PRU_RPMSG_SUCCESS)
           
{
               
// Process payload here

               
/* Echo the message back to the same address from which we just received */
                pru_rpmsg_send
(&transport, dst, src, payload, len);
           
}
       
}
   
}
}

However, this sequence loops at  while (!(*status & VIRTIO_CONFIG_S_DRIVER_OK));

I suppose there is some driver missing or not running, but have no idea which one...

Any help is appreciated !!

Thanks in advance,

Paul


Reply all
Reply to author
Forward
0 new messages