Many of our solutions contain multiple processors, either hardcore processors such as the Arm A9, A53 or R5, softcores likes MicroBlaze, Arm Cortex-M1/M3, or a combination of the two.
When we implement a multi-processor solution, typically we split the tasking between the available cores, exploiting each core to maximize its performance attributes. For example, using MicroBlaze or Cortex cores in the PL for dedicated real-time offloaded tasks while using hardcore application processors for higher level functions.
Of course, to correctly implement a multi-processor solution application, all the processors in the solution need to be able to communicate and share the available system resources safely and reliably.
This is where inter processor communication (IPC) comes in; when correctly implemented, it enables safe and reliable communication between processors, while also allowing multiple processors to share common resources, e.g. UARTs without conflict causing corruption.
Both Mailboxes and MUTEX play differing roles in our IPC solution:
Mailbox — Allows bi-directional communication between multiple processors using a FIFO based approach to messaging.
MUTEX — Implement mutual exclusion locks, this allows processors to lock shared resources preventing multiple accesses at the same time.
Regardless of if we use a heterogeneous SoC or FPGA, both Mailboxes and MUTEX’s are implemented within the programmable logic (PL).
We can implement Mailboxes and MUTEXs in our design directly from the Xilinx IP library. As both are intended for communication between two processors, they have two slave AXI inputs.
One slave AXI interface for each processor, using the Mailbox or MUTEX.
In this example, we going to use a Zynq communicating and sharing resources with a MicroBlaze in the PL.
The MicroBlaze will be connected to the GPIO which drives LEDs. My plan for the software application in the next blog is to show how we can send messages from the A9 to the MicroBlaze to turn on and off LEDs. A simple but effective demonstration, although first we need to complete the hardware design.
To create the block diagram, we first need to add in a Zynq processing system IP and run the block automation to configure the Zynq for the selected board.
That is one processing system added. For the second, add a MicroBlaze using the IP catalog. Once the MicroBlaze IP is in the block diagram, double click to re-customize the IP, select the microcontroller preset, leaving all other options unchanged.
Once the MicroBlaze IP is configured, the next step is to run its block automation to create the MicroBlaze solution. This will add in the block RAM from which the MicroBlaze will run and debug facilities.
Now that have our two processing system solutions, we are ready to add in the Mailbox and MUTEX — both can be added from Xilinx IP Catalog.
Once done, we can use the connection automation wizard to connect them into the two processor systems AXI connections.
The Mailbox transfers messages using a FIFO, the depth of this can be configured by re-using the Mailbox IP. To ensure efficient processing of messages at the receiving processor, the Mailbox is capable of generating interrupts to the relevant processor when messages are queued.
Like the Mailbox, the MUTEX is very similar, except it does not use a FIFO instead registers are used for each MUTEX to indicate the locked status or not. We can have up to 32 MUTEX shared between up to eight processors.
We will examine it more in the SW implementation blog next week but to prevent processors unlocking MUTEXs inadvertently or maliciously, CPU IDs are used.
The completed block diagram should look similar to the one below.
We can now build the hardware and export the design to SDK, ready to write the SW application next week.