Skip to content
deebot edited this page Aug 11, 2020 · 27 revisions

Parallel Bidirectional Communication between ARM and PRU using GPIO interface

Introduction

Beaglebone boards have two main subsystems namely ARM and PRU. The ARM allows us to run a linux OS and utilize the plethora of already existing code and libraries in out implementation, however running a linux also has its downsides.As it is a non premtive OS so it is not suitable for situations where we need to perform tasks in real time. This is where PRU comes in picture, using the two 200MHz PRU on a beaglebone one can offload the time critical tasks to the PRU and can fetch the final results on the ARM side. Thus creating a solution which has best of both the worlds.

As the name suggests project which is done under under GSOC2020 is aimed at providing a solution where a bidirectional communication can be achieved between PRU and ARM and firmware is implmented to interface a Universal shift register 74hc299 which helps extend the no of i/o which do not have the OS induced overhead. This might be used in situations for example when interfaceing a LED matrix or when connecting alot of inputs like in case of Keypads and joystics. So all the processing can be done inside the PRU and the results can be sent to the ARM where there are alot of possibilities for processing this Data, may be creating a web based UI to disply states etc.

Digging Deeper

The technique/protocol used to implement the communication is called rpmsg,The RPMsg protocol was created as part of the Open Asymmetric Multi Processing (OpenAMP) framework project to provide a standard interface for communication between multiple cores in a heterogeneous multi-core system. There was already a character driver in the linux source for this implementation. But here a gpiochip driver is implemented which is a new implementation to deal with the rpmsg based communication. To understand this better, we need to understand the architecture at a little more deeper level. The TRM tells us that there are 4 general purpose i/o modules and each module provides 32 gpio pins. So the AM335X provides 32 X 4 gpio. This fact can also be coraborated by looking inside the /dev and running the gpiodetect command.

IMAGE WILL COME HERE.

However not all of these gpios are accessable on the headers on the beagleboards. Now the intresting part is that in the implementation of the GPIO driver the linux system thinks it has another gpio module which controls 9 gpio lines. However these lines are virutal and there is no actual hardware pins corresponding to these lines inside the linux subsysystem.

IMAGE WILL COME HERE

The data that is sent using the sysfs interface is packaged in a char array and then send over to the PRU where this data is pushed to the i/o of the shift register.Similarly a gpio line can also be used to read input. So this data can also be read using the sysfs interface. This is a more intuitive interface as compared to using a char driver when any project involves controlling multiple i/o on the PRU side. Also this comes with another advantage that now one can use the libgpiod library to send and receive i/o state as if these are a part of gpio modules on the ARM. Another point worth mentioning is that in the implementation 9 virtual lines are created out of which 8 are used to send data and the state of 9th line tells the PRU if data need to be pushhed out to the shift register i/o or there is need to read the inputs and accordingly the shift register pins are first configured as input or output.

Usage Senarios

The code from this repository can be used partially or completely as it is, the probable usage senarios can be:

  1. Just use the linux kernel module to pass on the messages using sysfs interface and libgpiod
  2. Just want to interface the 74HC299 or 74HC595 to the PRUs in C and then want to use the usual char driver.
  3. Use the project as it is.

How to Use

Clone this wiki locally