104 lines
2.8 KiB
C++
104 lines
2.8 KiB
C++
|
||
#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;
|
||
}
|