(ES) 3.3.1 Aplicaciones de.espacio de usuario (User space) - coffeebrain/Codesign_HW_SW GitHub Wiki
For this section it is important to know the following key concepts:
Is the system of memory allocation used to run applications.
- Start an Embedded Command Shell
~/intelFPGA/19.1/embedded/embedded_command_shell.sh- Add sopc_builder binary files to the PATH environment variable
export PATH=$PATH:~/intelFPGA_lite/19.1/quartus/sopc_builder/bin- Go to userspace folder in the project folders
cd ~/Codesign_HW_SW/software/userspace- Run the
sopc-create-header-filescommand with the following arguments
sopc-create-header-files ../../Quartus_Files/soc_system.sopcinfo --single hps_0.h --module hps_0- A file name
hps_0.hmust have been created in the userspace folderm the file should look something like this
#ifndef _ALTERA_HPS_0_H_
#define _ALTERA_HPS_0_H_
...
#define ONCHIP_MEMORY2_0_COMPONENT_TYPE altera_avalon_onchip_memory2
#define ONCHIP_MEMORY2_0_COMPONENT_NAME onchip_memory2_0
...
#define CUSTOM_COMPONENT_0_COMPONENT_TYPE custom_component
#define CUSTOM_COMPONENT_0_COMPONENT_NAME custom_component_0
#define CUSTOM_COMPONENT_0_BASE 0x10000
#define CUSTOM_COMPONENT_0_SPAN 8
#define CUSTOM_COMPONENT_0_END 0x10008
...Make devmem_custom_component.c and Makefile files.
COMPONENT = custom_component
TARGET = devmem_$(COMPONENT)
CFLAGS = -static -g -Wall -std=gnu99
LDFLAGS = -g -Wall
CC = $(CROSS_COMPILE)gcc
ARCH = arm
HOST = <DE0-Nano-SoC-IP-address>
build: $(TARGET)
$(TARGET): $(TARGET).o
$(CC) $(LDFLAGS) $^ -o $@
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -f $(TARGET) *.a *.o *.~
install: $(TARGET)
scp $(TARGET) root@${HOST}:/root/$(COMPONENT)
To make a user space application that interacts with an IP component the following code sections must be taken into consideration:
- Including important Libraries
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <error.h>
#include <stdint.h>
#include <sys/mman.h>- Define Lightweight bridge memory base address and span
#define HPS_TO_FPGA_LW_BASE 0xFF200000
#define HPS_TO_FPGA_LW_SPAN 0x0020000- Create neccessary variable, for example an int variable to save a read value
int custom_component_0_value = 0;- Use the
opencommand from fcntl.h header file to call the/dev/memdevice and be sure it opens by assuring a major number greater than 0 is given
devmem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if(devmem_fd < 0)
{
perror("devmem open");
exit(EXIT_FAILURE);
}- Map the entire address space of the Lightweight bridge with
mmap()to use access later with the custom module and be sure it doesn't fail
lw_bridge_map = (uint32_t*)mmap(NULL, HPS_TO_FPGA_LW_SPAN, PROT_READ|PROT_WRITE, MAP_SHARED, devmem_fd, HPS_TO_FPGA_LW_BASE);
if(lw_bridge_map == MAP_FAILED)
{
perror("devmem mmap");
close(devmem_fd);
exit(EXIT_FAILURE);
}- Map the custom module with its corresponding offset from the Lightweight bridge base address
custom_component_map = (uint32_t*)(lw_bridge_map + CUSTOM_COMPONENT_0_BASE);- Perform write or read operations on the
custom_component_map
- Read from the
custom_component_mapmemory address, for example in the address 0
custom_component_0_value = (int) custom_component_map[0];- Write to the
custom_component_mapmemory address, for example a0xFF
*custom_component_map = 0xFF;- Unmap
lw_bridge_map
result = munmap(lw_bridge_map, HPS_TO_FPGA_LW_SPAN);
if(result < 0)
{
perror("devmem munmap");
close(devmem_fd);
exit(EXIT_FAILURE);
}- Close the file descriptor from the
/dev/memdevice and exit user space app
close(devmem_fd);
exit(EXIT_SUCCESS);#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <error.h>
#include <stdint.h>
#include <sys/mman.h>
// Lightweight bridge memory base address and span
#define HPS_TO_FPGA_LW_BASE 0xFF200000
#define HPS_TO_FPGA_LW_SPAN 0x0020000
int main(int argc, char ** argv)
{
int custom_component_0_value = 0;
// Open memory device
devmem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if(devmem_fd < 0)
{
perror("devmem open");
exit(EXIT_FAILURE);
}
// Map lightweight bridge memory
lw_bridge_map = (uint32_t*)mmap(NULL, HPS_TO_FPGA_LW_SPAN, PROT_READ|PROT_WRITE, MAP_SHARED, devmem_fd, HPS_TO_FPGA_LW_BASE);
if(lw_bridge_map == MAP_FAILED)
{
perror("devmem mmap");
close(devmem_fd);
exit(EXIT_FAILURE);
}
// Map component. Lightweight bridge + Component offset
custom_component_map = (uint32_t*)(lw_bridge_map + CUSTOM_COMPONENT_0_BASE);
// Read from custom component
custom_component_0_value = (int) custom_component_map[0];
// Write to custom component
*custom_component_map = 0xFF;
// Unmap lightweight bridge memory
result = munmap(lw_bridge_map, HPS_TO_FPGA_LW_SPAN);
if(result < 0)
{
perror("devmem munmap");
close(devmem_fd);
exit(EXIT_FAILURE);
}
// Close and exit
close(devmem_fd);
exit(EXIT_SUCCESS);
}