sitara_depot/utils/FileToSharedMem/FileToSharedMem.cpp

104 lines
2.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}