AMP (Asymmetric Multiprocessing Mode) and OCM for Zynq SoCs

In the last blog we learned about the Zynq SoC's OCM (On-Chip Memory), which enables communication between internal processor cores in AMP mode. Now we will write some program code to take advantage of this device (OCM).

In this demo example, we will use the UART interface to realize the communication connection between CPU0 and the host computer (notebook), we will send 8-bit ASCII code value from the host computer to the serial port of Zynq SoC, once received, this 8-bit ASCII code The code value will be transferred to the specified OCM memory address, and this memory address is shared by the two processor cores. Every time CPU1's timer expires, CPU1 will read the value of this memory address and set the value of the corresponding GPIO output pin to the read value. The LED light is designed on the MicroZed I/O carrier board. The carrier board is connected to the Zynq SoC through the Micro Header device. Through the corresponding settings, the LED light will be displayed on and off according to the read ASCII code value. We can confirm that the value passed between the two CPUs is correct by looking at the status of the LED lights.

Obviously the first thing we have to do is set the memory address to use, we will only be passing 8-bit unsigned integers, so we only need to request an address space, here I have chosen to use the ZynqSoC's OCM for the highest 64K bytes of storage To complete this work, I disable the cache (cache) function of this storage space. In the application, we can use the following function commands to achieve.
Xil_SetTlbAttributes(0xFFFF0000,0x14de2);

I will use the memory address 0XFFFF0000 as a medium to transfer one byte of data between CPU0 and CPU1. Of course, there are many ways to achieve this function. We will introduce the two most commonly used methods below:

The first method is to use the general Xilinx I/O interface functions to read and write to the specified address. These functions are included in the Xil_IO.h header file, allowing to store and access 8-bit, 8-bit, 16-bit or 32-bit character, short, or integer numeric data. Using these functions you can read the data at the specified address, or write the specified data at the specified address.
Xil_Out8(0xFFFF0000,0x55);
read_char = Xil_In8(0xFFFF0000);

In order to ensure that these addresses point to the same OCM location, especially when different people write different applications, they will call the common header file, the header file contains a macro definition for this address, which is a very good An example of an engineering practice is shown below:
#define LED_PAT 0xFFFF0000

The second method is to use pointers to a single memory location in both programs. We can define a pointer to a constant address, using C language we would define a macro like this
#define LED_OP (*(volatileunsignedint *)(0xFFFF0000))

This method does not need to call the library function of the Xilinx I/O interface, and the access function can be realized through the pointer.

Both of the above two methods can successfully implement my laptop to communicate with CPU0 through UART, then transmit the data to CPU1, and finally control the on-off state of the LED lights on the MicroZed I/O carrier board, as shown in the picture below (we Taking a picture with a black and white camera to prevent glare, the far right is the lowest position of the LED light):

The following information was received from the ZynqSoC:

Of course when we implement communication between processors on the ZynqSoC via OCM, we have to remember that register values ​​are updated faster than we have seen so far, because we use CPU1's timer to trigger a memory read Operation, in the next blog, we will cover more complex communication methods between the ZynqSoC's processors, we will focus on the way software interrupts.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325947649&siteId=291194637