diff --git a/fake_lib/README.md b/fake_lib/README.md index 0b8c76d9..3ceb1a91 100644 --- a/fake_lib/README.md +++ b/fake_lib/README.md @@ -65,13 +65,14 @@ export FAKE_EC_HOMEDIR=/tmp/FakeEtherCAT rm -rf $FAKE_EC_HOMEDIR mkdir -p $FAKE_EC_HOMEDIR ``` +For each master instance, one subdirectory named by the master id is created. ### Spin up your application Now it's time to simply launch your application. You will notice that the PDO configuration will be dumped at stderr. The path displayed is the path of the RtIPC variable in the following format: -`$FAKE_EC_PREFIX/$MASTER_ID/$DOMAIN_ID/$ALIAS$POSITION/$PDO`. +`$FAKE_EC_PREFIX/$MASTER_ID/$ALIAS$POSITION/$PDO`. ## How to emulate EtherCAT slaves diff --git a/fake_lib/fakeethercat.cpp b/fake_lib/fakeethercat.cpp index 80f769d1..ca588db8 100644 --- a/fake_lib/fakeethercat.cpp +++ b/fake_lib/fakeethercat.cpp @@ -30,6 +30,7 @@ #include #include #include +#include static std::ostream &operator<<(std::ostream &os, const sdo_address &a) { @@ -420,13 +421,37 @@ static const char *getName() return "FakeEtherCAT"; } +static int mkpath(const std::string &file_path) +{ + if (file_path.empty()) + return 0; + + std::size_t offset = 0; + do + { + offset = file_path.find('/', offset + 1); + const auto subpath = file_path.substr(0, offset); + if (mkdir(subpath.c_str(), 0755) == -1) + { + if (errno != EEXIST) + { + return -1; + } + } + } while (offset != std::string::npos); + return 0; +} + static std::string getRtIpcDir(int idx) { - if (const auto ans = getenv("FAKE_EC_HOMEDIR")) + std::string ans; + if (const auto e = getenv("FAKE_EC_HOMEDIR")) { - return ans + std::string("/") + std::to_string(idx); + ans = e + std::string("/") + std::to_string(idx); } - return "/tmp/FakeEtherCAT/" + std::to_string(idx); + ans = "/tmp/FakeEtherCAT/" + std::to_string(idx); + mkpath(ans); + return ans; } ec_master::ec_master(int id) : rt_ipc_dir(getRtIpcDir(id)), rt_ipc_name(getName()), rt_ipc(rtipc_create(rt_ipc_name.c_str(), rt_ipc_dir.c_str())), id_(id)