By Adam Taylor

As I mentioned in the previous blog, we use the Xilinx Power Management Framework Library to make use of the Zynq UltraScale+ MPSoC’s Platform Management Unit (PMU). The detail of this framework is well documented within UG1199, “Zynq Power Management Framework User Guide For Zynq UltraScale+ MPSoC Devices”. Xilinx provides API support for clients running on the RPU, the APU, any MicroBlaze soft processors instantiated within the Zynq UltraScale+ MPSoC’s PL (programmable logic), and of course the master in the PMU.

This API allows all of the power masters to control all of the power domains and islands within the device. This API is available with Linux, FreeRTOS, and bare-metal operating systems running on the processing units within the MPSoC.

The API library layer for standalone applications that runs on the APU, RPU, and MicroBlaze processors is called the Xilpm. By including this library when we create the application and by regenerating the BSP, we can then begin to use the Xilpm library within our application. If you want to find the functions available within the API, then open the BSP’s MSS file and click on the documentation hyperlink. This will open the documentation for each of the functions available in the library. If you want to include these functions within the design, then you need to include the following header files, which will then be included within the BSP:

#include "pm_api_sys.h"

#include "pm_client.h"

However, this is only half of the story. Running this API on a Zynq UltraScale+ MPSoC processing element requires executing the corresponding API on the Zynq UltraScale+ MPSoC’s PMU as well. This API is called the PMUFW (Power Management Unit Firmware). To run PMUFW on the PMU, we need to create a program for the PMU using SDK. We do this the same way that we create other applications for the RPU and APU. Select “file -> new application project” and from the drop-down list of processors select the PMU. It appears at the bottom of the list as shown below:

On the same tab, leave the operating system as standalone. You should also enable the creation of a new BSP if this is the first time you have created a PMU application. Once you have created one PMU project, you can reuse the BSP if you so desire.

On the next tab, select the ZynqMP PMU Firmware example, which will create the PMU application code and the corresponding BSP. We can then build and use this application in our overall software application. This process allows the various processing units in the Zynq UltraScale+ MPSoC to communicate with the PMU correctly.

For JTAG debugging, I set my debug configuration to download the APU and PMU applications as shown below:

All we need to do now is write some simple software to demonstrate how this all works when it is up and running.

There are a number of power islands located within the one of the four Zynq UltraScale+ MPSoC power domains. Through the API acting under the control of power masters and the PMU, we can control and power down entire processing units or just power islands to optimize power dissipation.

We can use the XPM_GetNodeStatus function to create a simple code example that reports the status of the each of the nodes within the design. To do this we need to do the following:

Configure the PSU IPI just as we do for any peripheral

Initialize the Xilpm that we configured above

Request the status using the XPM_GetNodeStatus() function

Launch the application on the UltraZed Dev Board

When you run this application on the UltraZed board, you will see the request from the API being echoed out over a terminal and the response from the PMUFW. Once PMUFU has responded, you’ll see that the node status structure contains the requested status information. When I ran this simple example on my UltraZed board, I received the following results. The Node ID is defined within #include pm_defs.h.

In this printout, you can see the PMU firmware booting before the main application runs on the APU. The main application requests the node status of tightly coupled memory 0 A and APU Core 0. In this case the Zynq UltraScale+ MPSoC’s TCM (Tightly Coupled Memory) is powered down and responds with the status of “2,” which means it is suspended. While the usage indicates that it is used by another processing unit only. The APU reports a status of “1,” which shows it is powered up, and usage of “0,” which indicates that it is not used by any processing unit, because it is a processing unit all by itself.

You can find more information on the node status within UG1199 and the Xilpm documentation within your SDK installation.

With this framework up and running, we can now begin to work on the more advanced power management features we might want to use for our application. We can build on this simple example to develop more complex power management applications within the application code executing on the processing units.

Note: I am currently using an UltraZed board with ES1 silicon.

Code is available on Github as always.

If you want E book or hardback versions of previous MicroZed chronicle blogs, you can get them below.

First Year E Book here

First Year Hardback here.