class to map uio addresses into user space

This commit is contained in:
Jakob Meier 2022-01-25 18:30:12 +01:00
parent 186b3565e0
commit 7360878390
4 changed files with 126 additions and 1 deletions

View File

@ -10,4 +10,5 @@ target_sources(${LIB_FSFW_NAME} PRIVATE
add_subdirectory(gpio)
add_subdirectory(spi)
add_subdirectory(i2c)
add_subdirectory(uart)
add_subdirectory(uart)
add_subdirectory(uio)

View File

@ -0,0 +1,3 @@
target_sources(${LIB_FSFW_NAME} PUBLIC
UioMapper.cpp
)

View File

@ -0,0 +1,63 @@
#include <fcntl.h>
#include <unistd.h>
#include <filesystem>
#include <fstream>
#include <sstream>
#include "UioMapper.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
UioMapper::UioMapper(std::string uioFile, int mapNum) : uioFile(uioFile), mapNum(mapNum) {}
UioMapper::~UioMapper() {}
ReturnValue_t UioMapper::getMappedAdress(uint32_t** address, Permissions permissions) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
int fd = open(uioFile.c_str(), O_RDWR);
if (fd < 1) {
sif::warning << "PtmeAxiConfig::initialize: Invalid UIO device file" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
size_t size = 0;
result = getMapSize(&size);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
*address = static_cast<uint32_t*>(
mmap(NULL, size, static_cast<int>(permissions), MAP_SHARED, fd, mapNum * getpagesize()));
if (*address == MAP_FAILED) {
sif::warning << "UioMapper::getMappedAdress: Failed to map physical address of uio device "
<< uioFile.c_str() << " and map" << static_cast<int>(mapNum) << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t UioMapper::getMapSize(size_t* size) {
std::stringstream namestream;
namestream << UIO_PATH_PREFIX << uioFile.substr(5, std::string::npos) << MAP_SUBSTR << mapNum
<< SIZE_FILE_PATH;
FILE* fp;
fp = fopen(namestream.str().c_str(), "r");
if (fp == nullptr) {
sif::warning << "UioMapper::getMapSize: Failed to open file " << namestream.str() << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
char hexstring[SIZE_HEX_STRING] = "";
int items = fscanf(fp, "%s", hexstring);
if (items != 1) {
sif::warning << "UioMapper::getMapSize: Failed with error code " << errno
<< " to read size "
"string from file "
<< namestream.str() << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
items = sscanf(hexstring, "%x", size);
if (items != 1) {
sif::warning << "UioMapper::getMapSize: Failed with error code " << errno << "to convert "
<< "size of map" << mapNum << " to integer" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
fclose(fp);
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -0,0 +1,58 @@
#ifndef FSFW_HAL_SRC_FSFW_HAL_LINUX_UIO_UIOMAPPER_H_
#define FSFW_HAL_SRC_FSFW_HAL_LINUX_UIO_UIOMAPPER_H_
#include <sys/mman.h>
#include <string>
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
/**
* @brief Class to help opening uio device files and mapping the physical addresses into the user
* address space.
*
* @author J. Meier
*/
class UioMapper {
public:
enum class Permissions: int {
READ_ONLY = PROT_READ,
WRITE_ONLY = PROT_WRITE,
READ_WRITE = PROT_READ | PROT_WRITE
};
/**
* @brief Constructor
*
* @param uioFile The device file of the uiO to open
* @param uioMap Number of memory map. Most UIO drivers have only one map which has than 0.
*/
UioMapper(std::string uioFile, int mapNum = 0);
virtual ~UioMapper();
/**
* @brief Maps the physical address into user address space and returns the mapped address
*
* @address The mapped user space address
* @permissions Specifies the read/write permissions of the address region
*/
ReturnValue_t getMappedAdress(uint32_t** address, Permissions permissions);
private:
static constexpr char UIO_PATH_PREFIX[] = "/sys/class/uio/";
static constexpr char MAP_SUBSTR[] = "/maps/map";
static constexpr char SIZE_FILE_PATH[] = "/size";
static constexpr int SIZE_HEX_STRING = 10;
std::string uioFile;
int mapNum = 0;
/**
* @brief Reads the map size from the associated sysfs size file
*
* @param size The read map size
*/
ReturnValue_t getMapSize(size_t* size);
};
#endif /* FSFW_HAL_SRC_FSFW_HAL_LINUX_UIO_UIOMAPPER_H_ */