sitara_depot/utils/FileToSharedMem/FileToSharedMem.cpp

104 lines
2.8 KiB
C++
Raw Permalink Normal View History

2024-07-01 12:29:22 +03:00
#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;
}