blob: 8a8de037d9502de5ce02c0d84323b502a3914473 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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);
}
|