The following example provides an implementation of an environment interface
structure suitable for standalone (bare metal) software applications on Xilinx processors. The implementation reuses the stubbed
implementation for logging functions and replaces the register read and write functions with
versions suitable for this platform. Also demonstrated is the use of the user context
initialization data to store the base address of the Vitis Networking P4 IP. The example has
the following steps:
- Define the user context.
- Implement the register read and write functions.
- Implement functions to create and destroy the example environment interface structure.
- Use of the example environment interface structure:
-
The following provides a structure that can contain the address of the Vitis Networking P4 IP core:
typedef struct ExampleUserContext { XilVitisNetP4AddressType VitisNetP4IpAddress; } ExampleUserContext;
-
- Implement the register read and write functions:
- The functions use the
Xil_Out32
and theXil_In32
functions from the Xilinx hardware abstraction layer of the standalone library, see OS and Libraries Document Collection (UG643) for more information.XilVitisNetP4ReturnType ExampleVitisNetP4WordWrite32Baremetal(XilVitisNetP4EnvIf *EnvIfPtr, XilVitisNetP4AddressType Address, uint32_t WriteValue) { ExampleUserContext *UserCtxPtr; if (EnvIfPtr == NULL) { return XIL_VITISNETP4_GENERAL_ERR_NULL_PARAM; } if (EnvIfPtr->UserCtx == NULL) { return XIL_VITISNETP4_GENERAL_ERR_INTERNAL_ASSERTION; } UserCtxPtr = (ExampleUserContext *)EnvIfPtr->UserCtx; /* Currently have base address fixed, move to UserCtx */ Xil_Out32(UserCtxPtr->VitisNetP4IpAddress + Address, WriteValue); return XIL_VITISNETP4_SUCCESS; } XilVitisNetP4ReturnType ExampleVitisNetP4WordRead32Baremetal(XilVitisNetP4EnvIf *EnvIfPtr, XilVitisNetP4AddressType Address, uint32_t *ReadValuePtr) { ExampleUserContext *UserCtxPtr; if (EnvIfPtr == NULL) { return XIL_VITISNETP4_GENERAL_ERR_NULL_PARAM; } if (ReadValuePtr == NULL) { return XIL_VITISNETP4_GENERAL_ERR_NULL_PARAM; } if (EnvIfPtr->UserCtx == NULL) { return XIL_VITISNETP4_GENERAL_ERR_INTERNAL_ASSERTION; } UserCtxPtr = (ExampleUserContext *)EnvIfPtr->UserCtx; *ReadValuePtr = Xil_In32(UserCtxPtr->VitisNetP4IpAddress + Address); return XIL_VITISNETP4_SUCCESS; }
- The functions use the
- Functions to create and destroy the environment interface structure:
-
int ExampleCreateBaremetalEnvIf(XilVitisNetP4EnvIf *EnvIfPtr, XilVitisNetP4AddressType VitisNetP4IpAddress) { XilVitisNetP4ReturnType Result; ExampleUserContext *UserCtxPtr; UserCtxPtr = calloc(1, sizeof(ExampleUserContext)); if (UserCtxPtr == NULL) { printf("ERROR: Failed to allocate memory\n\r"); return -1; } UserCtxPtr->VitisNetP4IpAddress = VitisNetP4IpAddress; /* * Reusing the Stub and updating the Read and Write function */ Result = XilVitisNetP4StubEnvIf(EnvIfPtr); if (Result == XIL_VITISNETP4_SUCCESS) { /* Install stubs for each platform-specific function */ (*EnvIfPtr)->WordWrite32 = ExampleVitisNetP4WordWrite32Baremetal; (*EnvIfPtr)->WordRead32 = ExampleVitisNetP4WordRead32Baremetal; (*EnvIfPtr)->UserCtx = (XilVitisNetP4UserCtxType)UserCtxPtr; } return 0; } void ExampleDestoryBaremetalEnvIf(XilVitisNetP4EnvIf *EnvIfPtr) { free(EnvIfPtr->UserCtx); }
-
- Use of the example environment interface structure:
-
XilVitisNetP4EnvIf EnvIf; int Result; Result = ExampleCreateBaremetalEnvIf(&EnvIf, XPAR_VITISNETP4_0_BASEADDR); if (Result != XIL_VITISNETP4_SUCCESS) { return -1; } ExampleDestoryBaremetalEnvIf(&EnvIf);
-