diff options
author | Martin Braun <martin.braun@ettus.com> | 2019-07-25 10:41:25 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-08-02 11:03:11 -0700 |
commit | 173531521970ed823b2f300180b8cacda94ec841 (patch) | |
tree | df23a21876e4430ae2b232499af5626189b819a3 /host/lib/usrp/x300/x300_claim.cpp | |
parent | e2ce13e35d915c2d8b1300fd88745610c17638d1 (diff) | |
download | uhd-173531521970ed823b2f300180b8cacda94ec841.tar.gz uhd-173531521970ed823b2f300180b8cacda94ec841.tar.bz2 uhd-173531521970ed823b2f300180b8cacda94ec841.zip |
x300: Refactor heavily
This pulls out a lot of code from x300_impl and puts it into its own
compilation units:
- EEPROM code goes to x300_mb_eeprom.*
- Claim code goes to x300_claim.*
- PCIe code goes to uhd::usrp::x300::pcie_manager
- Ethernet code goes to uhd::usrp::x300::eth_manager
Diffstat (limited to 'host/lib/usrp/x300/x300_claim.cpp')
-rw-r--r-- | host/lib/usrp/x300/x300_claim.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/host/lib/usrp/x300/x300_claim.cpp b/host/lib/usrp/x300/x300_claim.cpp new file mode 100644 index 000000000..8a8de037d --- /dev/null +++ b/host/lib/usrp/x300/x300_claim.cpp @@ -0,0 +1,89 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#include "x300_claim.hpp" +#include "x300_fw_common.h" +#include <uhd/utils/platform.hpp> +#include <chrono> +#include <thread> + +using namespace uhd; +using namespace uhd::usrp::x300; + +/*********************************************************************** + * claimer logic + **********************************************************************/ + +void uhd::usrp::x300::claimer_loop(wb_iface::sptr iface) +{ + claim(iface); + std::this_thread::sleep_for(std::chrono::seconds(1)); +} + +claim_status_t uhd::usrp::x300::claim_status(wb_iface::sptr iface) +{ + claim_status_t claim_status = CLAIMED_BY_OTHER; // Default to most restrictive + auto timeout_time = std::chrono::steady_clock::now() + std::chrono::seconds(1); + while (std::chrono::steady_clock::now() < timeout_time) { + // If timed out, then device is definitely unclaimed + if (iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_STATUS)) == 0) { + claim_status = UNCLAIMED; + break; + } + + // otherwise check claim src to determine if another thread with the same src has + // claimed the device + uint32_t hash = iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC)); + if (hash == 0) { + // A non-zero claim status and an empty hash means the claim might + // be in the process of being released. This is possible because + // older firmware takes a long time to update the status. Wait and + // check status again. + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + continue; + } + claim_status = (hash == get_process_hash() ? CLAIMED_BY_US : CLAIMED_BY_OTHER); + break; + } + return claim_status; +} + +void uhd::usrp::x300::claim(wb_iface::sptr iface) +{ + iface->poke32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_TIME), uint32_t(time(NULL))); + iface->poke32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC), get_process_hash()); +} + +bool uhd::usrp::x300::try_to_claim(wb_iface::sptr iface, long timeout_ms) +{ + const auto timeout_time = + std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout_ms); + while (1) { + claim_status_t status = claim_status(iface); + if (status == UNCLAIMED) { + claim(iface); + // It takes the claimer 10ms to update status, so wait 20ms before verifying + // claim + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + continue; + } + if (status == CLAIMED_BY_US) { + break; + } + if (std::chrono::steady_clock::now() > timeout_time) { + // Another process owns the device - give up + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + return true; +} + +void uhd::usrp::x300::release(wb_iface::sptr iface) +{ + iface->poke32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_TIME), 0); + iface->poke32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC), 0); +} |