shared memory utils
This commit is contained in:
parent
998279b54d
commit
682711c2a6
54
utils/FileToSharedMem/.vscode/launch.json
vendored
Executable file
54
utils/FileToSharedMem/.vscode/launch.json
vendored
Executable file
@ -0,0 +1,54 @@
|
||||
{
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "(gdb) DevMem am64xx_Debug",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/out/build/am64xx_Debug/DevMem",
|
||||
"MIMode": "gdb",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": true,
|
||||
"miDebuggerPath": "/usr/bin/gdb-multiarch",
|
||||
"miDebuggerServerAddress": "192.168.0.5:5000",
|
||||
"miDebuggerArgs": "",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Включить автоматическое форматирование для gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Задать для варианта приложения дизассемблирования значение Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) FileToSharedMem am64xx_Debug",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/out/build/am64xx_Debug/FileToSharedMem",
|
||||
"MIMode": "gdb",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": true,
|
||||
"miDebuggerPath": "/usr/bin/gdb-multiarch",
|
||||
"miDebuggerServerAddress": "192.168.0.5:5000",
|
||||
"miDebuggerArgs": "",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Включить автоматическое форматирование для gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Задать для варианта приложения дизассемблирования значение Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": "2.0.0"
|
||||
}
|
7
utils/FileToSharedMem/.vscode/settings.json
vendored
Normal file
7
utils/FileToSharedMem/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"*.tcc": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"ostream": "cpp"
|
||||
}
|
||||
}
|
51
utils/FileToSharedMem/CMakeLists.txt
Normal file
51
utils/FileToSharedMem/CMakeLists.txt
Normal file
@ -0,0 +1,51 @@
|
||||
cmake_minimum_required(VERSION 3.17)
|
||||
project(FileToSharedMem)
|
||||
|
||||
# Подключаем исходные файлы проекта.
|
||||
set(SOURCES
|
||||
MemMapping.cpp MemMapping.h
|
||||
)
|
||||
|
||||
# Подключаем внешние зависимости.
|
||||
include(FetchContent)
|
||||
include(SharedLibraries.cmake)
|
||||
|
||||
|
||||
# Определяем зависимости, являющиеся общими для всех целей.
|
||||
set(LIST_OF_SHARED_LIBRARIES
|
||||
cxxopts
|
||||
)
|
||||
|
||||
# Определяем свойства, являющиеся общими для всех целей.
|
||||
set(LIST_OF_SHARED_PROPERTIES
|
||||
CXX_STANDARD 20
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS OFF
|
||||
)
|
||||
|
||||
|
||||
add_executable(FileToSharedMem FileToSharedMem.cpp ${SOURCES})
|
||||
add_executable(DevMem DevMem.cpp ${SOURCES})
|
||||
|
||||
# Добавляем корневую директорию для того чтобы избежать инклюдов с ../
|
||||
target_include_directories(FileToSharedMem PRIVATE ${PROJECT_SOURCE_DIR})
|
||||
target_include_directories(DevMem PRIVATE ${PROJECT_SOURCE_DIR})
|
||||
|
||||
# Подключаем зависимости.
|
||||
target_link_libraries(FileToSharedMem PRIVATE ${LIST_OF_SHARED_LIBRARIES})
|
||||
target_link_libraries(DevMem PRIVATE ${LIST_OF_SHARED_LIBRARIES})
|
||||
|
||||
# Определяем свойства.
|
||||
set_target_properties(FileToSharedMem PROPERTIES ${LIST_OF_SHARED_PROPERTIES})
|
||||
set_target_properties(DevMem PROPERTIES ${LIST_OF_SHARED_PROPERTIES})
|
||||
|
||||
|
||||
# Подключаем зависимости платформы.
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(WIN_SHARED_LIBRARIES -Wl,-Bstatic,--whole-archive -static-libgcc -static-libstdc++ -lwinpthread
|
||||
-Wl,--no-whole-archive wsock32 ws2_32
|
||||
)
|
||||
|
||||
target_link_libraries(FileToSharedMem PRIVATE ${WIN_SHARED_LIBRARIES})
|
||||
target_link_libraries(DevMem PRIVATE ${WIN_SHARED_LIBRARIES})
|
||||
endif()
|
78
utils/FileToSharedMem/CMakePresets.json
Normal file
78
utils/FileToSharedMem/CMakePresets.json
Normal file
@ -0,0 +1,78 @@
|
||||
{
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"displayName": "default",
|
||||
"description": "Default build using Ninja generator",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||
"cacheVariables": {
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "x86_64_Debug",
|
||||
"inherits": "default",
|
||||
"displayName": "x86_64 Debug",
|
||||
"description": "Degub build for x86_64",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_C_COMPILER": "gcc",
|
||||
"CMAKE_CXX_COMPILER": "g++"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "x86_64_Release",
|
||||
"inherits": "x86_64_Debug",
|
||||
"displayName": "x86_64 Release",
|
||||
"description": "Release build for x86_64",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "am64xx_Debug",
|
||||
"inherits": "default",
|
||||
"displayName": "am64xx Debug",
|
||||
"description": "Degub build for am64xx-evm board(arm cortex-a53)",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_TOOLCHAIN_FILE": "${workspaceFolder}/../../compile/toolchain.cmake",
|
||||
"BOARD": "am64xx-evm"
|
||||
},
|
||||
"environment": {
|
||||
"ENV_TARGET_CROSS_COMPILE_PREFIX": "/opt/ti-processor-sdk-linux-am64xx-evm-09.02.00.08/linux-devkit/sysroots/x86_64-arago-linux/usr/bin/aarch64-oe-linux/aarch64-oe-linux-",
|
||||
"ENV_TARGET_SYSTOOT_PATH": "/opt/ti-processor-sdk-linux-am64xx-evm-09.02.00.08/linux-devkit/sysroots/aarch64-oe-linux"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "am64xx_Release",
|
||||
"inherits": "am64xx_Debug",
|
||||
"displayName": "am64xx Release",
|
||||
"description": "Release build for am64xx-evm board(arm cortex-a53)",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "x86_64 Debug",
|
||||
"configurePreset": "x86_64_Debug"
|
||||
},
|
||||
{
|
||||
"name": "x86_64 Release",
|
||||
"configurePreset": "x86_64_Release"
|
||||
},
|
||||
{
|
||||
"name": "am64xx Release",
|
||||
"configurePreset": "am64xx_Release"
|
||||
},
|
||||
{
|
||||
"name": "am64xx Debug",
|
||||
"configurePreset": "am64xx_Debug"
|
||||
}
|
||||
]
|
||||
}
|
42
utils/FileToSharedMem/DevMem.cpp
Normal file
42
utils/FileToSharedMem/DevMem.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include "MemMapping.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
switch(argc)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
size_t addrPhys = std::stoull(argv[1], nullptr, 0);
|
||||
int val;
|
||||
|
||||
MemMapping map(O_RDONLY, addrPhys, sizeof(val), PROT_READ, MAP_PRIVATE);
|
||||
|
||||
memcpy(&val, map.get(), sizeof(val));
|
||||
|
||||
std::cout << "0x" << std::hex << val << std::endl;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
size_t addrPhys = std::stoull(argv[1], nullptr, 0);
|
||||
int val = std::stoull(argv[2], nullptr, 0);
|
||||
|
||||
MemMapping map(O_RDWR | O_SYNC, addrPhys, sizeof(val), PROT_READ | PROT_WRITE, MAP_SHARED);
|
||||
|
||||
memcpy(map.get(), &val, sizeof(val));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
std::cout << "Wrong argument count!" << std::endl;
|
||||
std::cout << "Usage:" << std::endl;
|
||||
std::cout << "Read 32 bits: devmem 0x12345678" << std::endl;
|
||||
std::cout << "Write 32 bits: devmem 0x12345678 314159" << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
103
utils/FileToSharedMem/FileToSharedMem.cpp
Normal file
103
utils/FileToSharedMem/FileToSharedMem.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <cxxopts.hpp>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cstdint>
|
||||
|
||||
#include "MemMapping.h"
|
||||
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
|
||||
using namespace std::literals::string_literals;
|
||||
using namespace std::literals::string_view_literals;
|
||||
|
||||
cxxopts::Options options(
|
||||
"FileToSharedMem",
|
||||
"FileToSharedMem: copies file content to memory location.\n"
|
||||
""
|
||||
);
|
||||
|
||||
options.set_width(160);
|
||||
|
||||
options.add_options()
|
||||
("help", "Display this help", cxxopts::value<bool>()->default_value("false"))
|
||||
("verbose", "Verbose output", cxxopts::value<bool>()->default_value("true"))
|
||||
("file", "Set binary file path", cxxopts::value<std::string>()->default_value("Project.bin"))
|
||||
("addr", "Set memory physical address", cxxopts::value<std::string>()->default_value("0xa6000000"));
|
||||
|
||||
auto result = options.parse(argc, argv);
|
||||
|
||||
if (result["help"].as<bool>())
|
||||
return not( std::cout << options.help() << std::endl );
|
||||
|
||||
|
||||
std::string file_path = result["file"].as<std::string>();
|
||||
uint64_t addr = std::stoull(result["addr"].as<std::string>(), nullptr, 0);
|
||||
|
||||
std::ifstream fin(file_path, std::ios::in | std::ios::binary);
|
||||
|
||||
if(!fin)
|
||||
{
|
||||
fprintf(stderr, "Couldn't open file %s", file_path);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//service fields in shared mem
|
||||
struct
|
||||
{
|
||||
uint32_t len;
|
||||
uint32_t mark;
|
||||
} service = {.len = std::filesystem::file_size(file_path), .mark = 0};
|
||||
|
||||
const int accessQuant = 8;
|
||||
const int map_len = service.len + sizeof(service) + accessQuant; //с небольшим запасом
|
||||
|
||||
MemMapping map(O_RDWR | O_SYNC, addr, map_len, PROT_READ | PROT_WRITE, MAP_SHARED);
|
||||
|
||||
void * pDst = map.get();
|
||||
|
||||
memcpy(pDst, &service, sizeof(service));
|
||||
pDst += sizeof(service);
|
||||
|
||||
{
|
||||
const uint32_t mask = accessQuant - 1;
|
||||
const int buf_len = (service.len & mask) ? ((service.len & ~mask) + accessQuant) : service.len;
|
||||
|
||||
std::vector<char> buf(buf_len);
|
||||
if(!fin.read(buf.data(), service.len))
|
||||
{
|
||||
fprintf(stderr, "Couldn't read from file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memcpy(pDst, buf.data(), buf.size());
|
||||
|
||||
// По одному байту работает, но некрасиво
|
||||
//
|
||||
// int i;
|
||||
// char * p = (char *)pDst;
|
||||
// const char * pSrc = buf.data();
|
||||
// for(i = 0; i < service.len; i++)
|
||||
// *p++ = *pSrc++;
|
||||
}
|
||||
|
||||
//Так нельзя - получаем Bus error
|
||||
//
|
||||
// if(!fin.read((char *)pDst, service.len))
|
||||
// {
|
||||
// fprintf(stderr, "Couldn't read from file");
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
service.mark = 0x12345678;
|
||||
pDst = map.get();
|
||||
memcpy(pDst, &service, sizeof(service));
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
49
utils/FileToSharedMem/MemMapping.cpp
Normal file
49
utils/FileToSharedMem/MemMapping.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include "MemMapping.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
MemMapping::MemMapping(int memOpenFlags, size_t addr, size_t size, int mmapProt, int mmapFlags)
|
||||
{
|
||||
const size_t pageMask = sysconf(_SC_PAGESIZE) - 1;
|
||||
const size_t pageAddr = addr & ~(pageMask); //базовый адрес страницы
|
||||
|
||||
m_pageOffset = addr & pageMask; //смещение относительно начала страницы
|
||||
|
||||
int fd = open("/dev/mem", memOpenFlags);
|
||||
if(fd < 0)
|
||||
{
|
||||
fprintf(stderr, "Can't open /dev/mem, flags=0x%X, %s line %i\n", memOpenFlags, __FILE__, __LINE__);
|
||||
throw std::runtime_error("MemMapping failed");
|
||||
}
|
||||
|
||||
// mmap() делается с адреса, кратного странице -> выделяемый размер нужно увеличить на величину смещения внутри страницы
|
||||
m_size = size + m_pageOffset;
|
||||
m_mapAddr = mmap(NULL,
|
||||
m_size,
|
||||
mmapProt,
|
||||
mmapFlags,
|
||||
fd,
|
||||
pageAddr);
|
||||
|
||||
//После mmap регистров дескриптор больше не нужен - закрываем файл
|
||||
close(fd);
|
||||
|
||||
if(m_mapAddr == MAP_FAILED)
|
||||
{
|
||||
fprintf(stderr, "MemMapping: can't mmap addr=0x%X size=0x%X errno=%i\n", addr, size, errno);
|
||||
throw std::runtime_error("MemMapping failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MemMapping::~MemMapping()
|
||||
{
|
||||
if(munmap(m_mapAddr, m_size) < 0)
|
||||
{
|
||||
fprintf(stderr, "MemMapping: can't unmap addr=0x%X size=0x%X errno=%i\n", m_mapAddr, m_size, errno);
|
||||
}
|
||||
}
|
25
utils/FileToSharedMem/MemMapping.h
Normal file
25
utils/FileToSharedMem/MemMapping.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
class MemMapping
|
||||
{
|
||||
public:
|
||||
/*
|
||||
* memOpenFlags - параметры доступа к /dev/mem, например O_RDWR, O_SYNC
|
||||
* addr - физический адрес в памяти, м.б. не кратен размеру страницы
|
||||
* mmapProt - параметры mmap, например PROT_READ | PROT_WRITE
|
||||
* mmapFlags - параметры mmap, например MAP_SHARED
|
||||
*/
|
||||
MemMapping(int memOpenFlags, size_t addr, size_t size, int mmapProt, int mmapFlags);
|
||||
~MemMapping();
|
||||
void * get() { return m_mapAddr + m_pageOffset; };
|
||||
|
||||
private:
|
||||
void * m_mapAddr; //замапированный виртуальный адрес, кратный размеру страницы
|
||||
size_t m_size; //замапированный размер
|
||||
|
||||
size_t m_pageOffset; //отступ исходного addr от начала страницы
|
||||
};
|
9
utils/FileToSharedMem/RepositoryPath.cmake
Normal file
9
utils/FileToSharedMem/RepositoryPath.cmake
Normal file
@ -0,0 +1,9 @@
|
||||
# Specify the path to dependencies' git repositories
|
||||
|
||||
cmake_path(SET cxxopts_path "git@sofdev:External/cxxopts.git")
|
||||
|
||||
if (
|
||||
NOT DEFINED cxxopts_path)
|
||||
|
||||
message(FATAL_ERROR "Path to the dependency git repository is not specified")
|
||||
endif()
|
13
utils/FileToSharedMem/SharedLibraries.cmake
Normal file
13
utils/FileToSharedMem/SharedLibraries.cmake
Normal file
@ -0,0 +1,13 @@
|
||||
include(RepositoryPath.cmake)
|
||||
|
||||
FetchContent_Declare(
|
||||
cxxopts
|
||||
GIT_REPOSITORY ${cxxopts_path}
|
||||
GIT_TAG master
|
||||
)
|
||||
FetchContent_GetProperties(cxxopts)
|
||||
if(NOT cxxopts_POPULATED)
|
||||
FetchContent_Populate(cxxopts)
|
||||
add_subdirectory(${cxxopts_SOURCE_DIR} ${cxxopts_BINARY_DIR})
|
||||
endif()
|
||||
|
16
utils/FileToSharedMem/debug_support/copy_and_debug_start
Executable file
16
utils/FileToSharedMem/debug_support/copy_and_debug_start
Executable file
@ -0,0 +1,16 @@
|
||||
|
||||
# $1 - root@192.168.0.5
|
||||
# $2 - ../out/build/am64xx_Debug/PeaceTrueNetConnector
|
||||
|
||||
$(dirname "$0")/copy_app $1 $2
|
||||
|
||||
|
||||
ssh $1 <<END_SCRIPT
|
||||
|
||||
cd /home/root/
|
||||
chmod 777 $(basename "$2")
|
||||
|
||||
gdbserver :5000 $(basename "$2")
|
||||
exit
|
||||
|
||||
END_SCRIPT
|
12
utils/FileToSharedMem/debug_support/copy_app
Executable file
12
utils/FileToSharedMem/debug_support/copy_app
Executable file
@ -0,0 +1,12 @@
|
||||
|
||||
# $1 - root@192.168.0.5
|
||||
# $2 - ../out/build/am64xx_Debug/PeaceTrueNetConnector
|
||||
|
||||
ssh $1 <<END_SCRIPT
|
||||
|
||||
killall gdbserver
|
||||
|
||||
exit
|
||||
END_SCRIPT
|
||||
|
||||
scp $2 $1:/home/root/
|
14
utils/FileToSharedMem/debug_support/debug_start
Executable file
14
utils/FileToSharedMem/debug_support/debug_start
Executable file
@ -0,0 +1,14 @@
|
||||
|
||||
# $1 - root@192.168.0.5
|
||||
# $2 - ../out/build/am64xx_Debug/PeaceTrueNetConnector
|
||||
|
||||
|
||||
ssh $1 <<END_SCRIPT
|
||||
|
||||
cd /home/root/
|
||||
chmod 777 $(basename "$2")
|
||||
|
||||
gdbserver :5000 $(basename "$2")
|
||||
exit
|
||||
|
||||
END_SCRIPT
|
Loading…
Reference in New Issue
Block a user