Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit Trigger Distribution
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
White Rabbit Trigger Distribution
Commits
a0d2fba5
Commit
a0d2fba5
authored
Jun 07, 2019
by
Dimitris Lampridis
Committed by
Dimitris Lampridis
Jun 26, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sw: rework WRTD attributes
parent
fed05a7e
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
916 additions
and
243 deletions
+916
-243
wrtd_alarm.svh
hdl/testbench/include/wrtd_alarm.svh
+14
-19
wrtd_definitions.svh
hdl/testbench/include/wrtd_definitions.svh
+3
-2
wrtd_rule.svh
hdl/testbench/include/wrtd_rule.svh
+31
-22
wrtd-adcin.c
software/firmware/adc/wrtd-adcin.c
+2
-1
wrtd-adcout.c
software/firmware/adc/wrtd-adcout.c
+11
-10
wrtd-rt-adc.c
software/firmware/adc/wrtd-rt-adc.c
+2
-3
wrtd-rt-common.h
software/firmware/common/wrtd-rt-common.h
+86
-41
wrtd-fd.c
software/firmware/fd/wrtd-fd.c
+10
-10
wrtd-rt-fd.c
software/firmware/fd/wrtd-rt-fd.c
+2
-2
wrtd-rt-tdc.c
software/firmware/tdc/wrtd-rt-tdc.c
+2
-2
wrtd-tdc.c
software/firmware/tdc/wrtd-tdc.c
+2
-1
wrtd-common.h
software/include/wrtd-common.h
+6
-4
libwrtd-attributes.c
software/lib/libwrtd-attributes.c
+707
-57
libwrtd-private.h
software/lib/libwrtd-private.h
+11
-1
libwrtd-rules.c
software/lib/libwrtd-rules.c
+3
-1
libwrtd.h
software/lib/libwrtd.h
+21
-61
wrtd-config.c
software/tools/wrtd-config.c
+3
-6
No files found.
hdl/testbench/include/wrtd_alarm.svh
View file @
a0d2fba5
...
...
@@ -29,14 +29,12 @@
class
WrtdAlarm
extends
WrtdRepCap
;
protected
WrtdTstamp
setup_time
;
protected
wrtd_event
ev
;
protected
int
repeat_count
;
protected
uint32_t
period_ns
;
function
new
(
string
name
=
""
)
;
super
.
new
(
name
)
;
this
.
setup_time
=
new
()
;
this
.
ev
.
ts
=
new
()
;
this
.
ev
.
id
=
new
()
;
clear
()
;
...
...
@@ -44,7 +42,6 @@ class WrtdAlarm extends WrtdRepCap;
function
void
clear
(
)
;
super
.
clear
()
;
this
.
setup_time
.
zero
()
;
this
.
ev
.
ts
.
zero
()
;
this
.
ev
.
id
.
clear
()
;
this
.
ev
.
seq
=
0
;
...
...
@@ -55,26 +52,24 @@ class WrtdAlarm extends WrtdRepCap;
function
wrtd_data
data_pack
(
)
;
wrtd_data
ret
=
new
[
`WRTD_ALRM_WORD_SIZE
]
;
ret
[
0
:
2
]
=
this
.
setup_time
.
data_pack
()
;
ret
[
3
:
5
]
=
this
.
ev
.
ts
.
data_pack
()
;
ret
[
6
:
9
]
=
this
.
ev
.
id
.
data_pack
()
;
ret
[
10
]
=
this
.
ev
.
seq
;
ret
[
11
]
=
this
.
ev
.
flags
;
ret
[
12
]
=
this
.
enabled
;
ret
[
13
]
=
this
.
repeat_count
;
ret
[
14
]
=
this
.
period_ns
;
ret
[
0
:
2
]
=
this
.
ev
.
ts
.
data_pack
()
;
ret
[
3
:
6
]
=
this
.
ev
.
id
.
data_pack
()
;
ret
[
7
]
=
this
.
ev
.
seq
;
ret
[
8
]
=
this
.
ev
.
flags
;
ret
[
9
]
=
this
.
enabled
;
ret
[
10
]
=
this
.
repeat_count
;
ret
[
11
]
=
this
.
period_ns
;
return
ret
;
endfunction
// data_pack
function
void
data_unpack
(
wrtd_data
data
)
;
this
.
setup_time
.
data_unpack
(
data
[
0
:
2
]
)
;
this
.
ev
.
ts
.
data_unpack
(
data
[
3
:
5
]
)
;
this
.
ev
.
id
.
data_unpack
(
data
[
6
:
9
]
)
;
this
.
ev
.
seq
=
data
[
10
]
;
this
.
ev
.
flags
=
data
[
11
]
;
this
.
enabled
=
data
[
12
]
;
this
.
repeat_count
=
data
[
13
]
;
this
.
period_ns
=
data
[
14
]
;
this
.
ev
.
ts
.
data_unpack
(
data
[
0
:
2
]
)
;
this
.
ev
.
id
.
data_unpack
(
data
[
3
:
6
]
)
;
this
.
ev
.
seq
=
data
[
7
]
;
this
.
ev
.
flags
=
data
[
8
]
;
this
.
enabled
=
data
[
9
]
;
this
.
repeat_count
=
data
[
10
]
;
this
.
period_ns
=
data
[
11
]
;
endfunction
// data_unpack
endclass
//WrtdAlarm
...
...
hdl/testbench/include/wrtd_definitions.svh
View file @
a0d2fba5
...
...
@@ -37,8 +37,8 @@
`define
WRTD_IO_MSG_WORD_SIZE 2
`define
WRTD_CFG_MSG_WORD_SIZE 5
`define
WRTD_ROOT_WORD_SIZE 12
`define
WRTD_RULE_WORD_SIZE 4
0
`define
WRTD_ALRM_WORD_SIZE 1
5
`define
WRTD_RULE_WORD_SIZE 4
3
`define
WRTD_ALRM_WORD_SIZE 1
2
`define
WRTD_DEST_CPU_LOCAL
'
hfe
`define
WRTD_DEST_CH_NET
'
hff
...
...
@@ -83,6 +83,7 @@ typedef enum uint32_t {
typedef
enum
uint32_t
{
WRTD_LOG_DISCARD_NO_SYNC
=
1
,
WRTD_LOG_DISCARD_HOLDOFF
,
WRTD_LOG_DISCARD_TIMEOUT
,
WRTD_LOG_DISCARD_OVERFLOW
}
wrtd_log_dsc_reason
;
...
...
hdl/testbench/include/wrtd_rule.svh
View file @
a0d2fba5
...
...
@@ -37,18 +37,21 @@ class WrtdRule extends WrtdRepCap;
protected
uint32_t
delay_ns
;
protected
uint32_t
hold_off_ns
;
protected
uint32_t
resync_period_ns
;
protected
uint32_t
resync_
delay_ns
;
protected
uint32_t
resync_
factor
;
int
hash_chain
;
protected
uint32_t
rx_events
;
protected
WrtdTstamp
rx_last
;
protected
uint32_t
tx_events
;
protected
WrtdTstamp
tx_last
;
protected
uint32_t
lat_min_ns
;
protected
uint32_t
lat_max_ns
;
protected
uint32_t
lat_lo_ns
;
protected
uint32_t
lat_hi_ns
;
protected
uint32_t
lat_nbr
;
protected
uint32_t
miss_holdoff
;
protected
uint32_t
miss_late
;
protected
uint32_t
miss_nosync
;
protected
uint32_t
miss_overflow
;
protected
WrtdTstamp
miss_last
;
protected
WrtdTstamp
hold_off
;
protected
uint32_t
seq
;
...
...
@@ -79,7 +82,7 @@ class WrtdRule extends WrtdRepCap;
this
.
delay_ns
=
0
;
this
.
hold_off_ns
=
0
;
this
.
resync_period_ns
=
0
;
this
.
resync_
delay_ns
=
0
;
this
.
resync_
factor
=
0
;
this
.
hash_chain
=
-
1
;
endfunction
// clear
...
...
@@ -96,21 +99,24 @@ class WrtdRule extends WrtdRepCap;
ret
[
14
]
=
this
.
delay_ns
;
ret
[
15
]
=
this
.
hold_off_ns
;
ret
[
16
]
=
this
.
resync_period_ns
;
ret
[
17
]
=
this
.
resync_
delay_ns
;
ret
[
17
]
=
this
.
resync_
factor
;
ret
[
18
]
=
this
.
hash_chain
;
ret
[
19
]
=
this
.
rx_events
;
ret
[
20
:
22
]
=
this
.
rx_last
.
data_pack
()
;
ret
[
23
]
=
this
.
tx_events
;
ret
[
24
:
26
]
=
this
.
tx_last
.
data_pack
()
;
ret
[
27
]
=
this
.
lat_max_ns
;
ret
[
28
]
=
this
.
lat_lo_ns
;
ret
[
29
]
=
this
.
lat_hi_ns
;
ret
[
30
]
=
this
.
lat_nbr
;
ret
[
31
]
=
this
.
miss_holdoff
;
ret
[
32
]
=
this
.
miss_late
;
ret
[
33
:
35
]
=
this
.
miss_last
.
data_pack
()
;
ret
[
36
:
38
]
=
this
.
hold_off
.
data_pack
()
;
ret
[
39
]
=
this
.
seq
;
ret
[
27
]
=
this
.
lat_min_ns
;
ret
[
28
]
=
this
.
lat_max_ns
;
ret
[
29
]
=
this
.
lat_lo_ns
;
ret
[
30
]
=
this
.
lat_hi_ns
;
ret
[
31
]
=
this
.
lat_nbr
;
ret
[
32
]
=
this
.
miss_holdoff
;
ret
[
33
]
=
this
.
miss_late
;
ret
[
34
]
=
this
.
miss_nosync
;
ret
[
35
]
=
this
.
miss_overflow
;
ret
[
36
:
38
]
=
this
.
miss_last
.
data_pack
()
;
ret
[
39
:
41
]
=
this
.
hold_off
.
data_pack
()
;
ret
[
42
]
=
this
.
seq
;
return
ret
;
endfunction
// data_pack
...
...
@@ -126,21 +132,24 @@ class WrtdRule extends WrtdRepCap;
this
.
delay_ns
=
data
[
14
]
;
this
.
hold_off_ns
=
data
[
15
]
;
this
.
resync_period_ns
=
data
[
16
]
;
this
.
resync_
delay_ns
=
data
[
17
]
;
this
.
resync_
factor
=
data
[
17
]
;
this
.
hash_chain
=
data
[
18
]
;
this
.
rx_events
=
data
[
19
]
;
this
.
rx_last
.
data_unpack
(
data
[
20
:
22
]
)
;
this
.
tx_events
=
data
[
23
]
;
this
.
tx_last
.
data_unpack
(
data
[
24
:
26
]
)
;
this
.
lat_max_ns
=
data
[
27
]
;
this
.
lat_lo_ns
=
data
[
28
]
;
this
.
lat_hi_ns
=
data
[
29
]
;
this
.
lat_nbr
=
data
[
30
]
;
this
.
miss_holdoff
=
data
[
31
]
;
this
.
miss_late
=
data
[
32
]
;
this
.
miss_last
.
data_unpack
(
data
[
33
:
35
]
)
;
this
.
hold_off
.
data_unpack
(
data
[
36
:
38
]
)
;
this
.
seq
=
data
[
39
]
;
this
.
lat_min_ns
=
data
[
27
]
;
this
.
lat_max_ns
=
data
[
28
]
;
this
.
lat_lo_ns
=
data
[
29
]
;
this
.
lat_hi_ns
=
data
[
30
]
;
this
.
lat_nbr
=
data
[
31
]
;
this
.
miss_holdoff
=
data
[
32
]
;
this
.
miss_late
=
data
[
33
]
;
this
.
miss_nosync
=
data
[
34
]
;
this
.
miss_overflow
=
data
[
35
]
;
this
.
miss_last
.
data_unpack
(
data
[
36
:
38
]
)
;
this
.
hold_off
.
data_unpack
(
data
[
39
:
41
]
)
;
this
.
seq
=
data
[
42
]
;
endfunction
// data_unpack
function
string
get_src
(
)
;
...
...
software/firmware/adc/wrtd-adcin.c
View file @
a0d2fba5
...
...
@@ -94,7 +94,8 @@ static void adcin_input(struct wrtd_adcin_dev *adcin)
ev
.
flags
=
0
;
wrtd_log
(
WRTD_LOG_MSG_EV_GENERATED
,
WRTD_LOG_GENERATED_DEVICE
+
(
i
*
8
),
&
ev
,
NULL
);
WRTD_LOG_GENERATED_DEVICE
+
(
i
*
8
),
NULL
,
&
ev
,
NULL
);
/* Pass to wrtd. */
wrtd_route_in
(
&
ev
);
...
...
software/firmware/adc/wrtd-adcout.c
View file @
a0d2fba5
...
...
@@ -93,7 +93,7 @@ static void adcout_drop_trigger(struct wrtd_adcout_dev *dev,
/* Disarm the ADC output */
adcout_writel
(
dev
,
0
,
ALT_TRIGIN_CTRL
);
wrtd_log
(
WRTD_LOG_MSG_EV_DISCARDED
,
reason
,
ev
,
now
);
wrtd_log
(
WRTD_LOG_MSG_EV_DISCARDED
,
reason
,
NULL
,
ev
,
now
);
}
...
...
@@ -127,7 +127,9 @@ static void adcout_output (struct wrtd_adcout_dev *dev)
}
}
else
{
/* Has been triggered. */
wrtd_log
(
WRTD_LOG_MSG_EV_CONSUMED
,
WRTD_LOG_CONSUMED_DONE
,
ev
,
NULL
);
wrtd_log
(
WRTD_LOG_MSG_EV_CONSUMED
,
WRTD_LOG_CONSUMED_DONE
,
NULL
,
ev
,
NULL
);
adcout_out_queue_pop
(
q
);
dev
->
idle
=
1
;
...
...
@@ -153,7 +155,8 @@ static void adcout_output (struct wrtd_adcout_dev *dev)
adcout_writel
(
dev
,
ts
->
ns
/
8
,
ALT_TRIGIN_CYCLES
);
adcout_writel
(
dev
,
ALT_TRIGIN_CTRL_ENABLE
,
ALT_TRIGIN_CTRL
);
wrtd_log
(
WRTD_LOG_MSG_EV_CONSUMED
,
WRTD_LOG_CONSUMED_START
,
ev
,
NULL
);
wrtd_log
(
WRTD_LOG_MSG_EV_CONSUMED
,
WRTD_LOG_CONSUMED_START
,
NULL
,
ev
,
NULL
);
ts_add2_ns
(
ts
,
8000
);
...
...
@@ -166,21 +169,19 @@ static void adcout_output (struct wrtd_adcout_dev *dev)
dev
->
idle
=
0
;
}
static
void
adcout_local_output
(
struct
wrtd_adcout_dev
*
dev
,
static
int
adcout_local_output
(
struct
wrtd_adcout_dev
*
dev
,
struct
wrtd_event
*
ev
,
unsigned
ch
)
{
struct
wrtd_event
*
pq_ev
;
pq_ev
=
adcout_out_queue_push
(
&
dev
->
queue
);
if
(
!
pq_ev
)
{
/* overflow.
FIXME: stats ? */
wrtd_log
(
WRTD_LOG_MSG_EV_DISCARDED
,
WRTD_LOG_DISCARD_OVERFLOW
,
ev
,
NULL
);
return
;
return
-
EOVERFLOW
;
}
*
pq_ev
=
*
ev
;
return
0
;
}
static
void
adcout_init
(
struct
wrtd_adcout_dev
*
dev
)
...
...
software/firmware/adc/wrtd-rt-adc.c
View file @
a0d2fba5
...
...
@@ -92,10 +92,9 @@ static inline int wr_sync_timeout(void)
#endif
}
static
void
wrtd_local_output
(
struct
wrtd_event
*
ev
,
unsigned
ch
)
static
int
wrtd_local_output
(
struct
wrtd_event
*
ev
,
unsigned
ch
)
{
adcout_local_output
(
&
adcout0
,
ev
,
ch
);
return
;
return
adcout_local_output
(
&
adcout0
,
ev
,
ch
);
}
static
int
wrtd_user_init
(
void
)
...
...
software/firmware/common/wrtd-rt-common.h
View file @
a0d2fba5
...
...
@@ -29,8 +29,8 @@ static int wr_link_up(void);
static
int
wr_time_locked
(
void
);
static
int
wr_time_ready
(
void
);
static
void
wr_enable_lock
(
int
enable
);
static
int
wrtd_local_output
(
struct
wrtd_event
*
ev
,
unsigned
ch
);
static
int
wr_sync_timeout
(
void
);
static
void
wrtd_local_output
(
struct
wrtd_event
*
ev
,
unsigned
ch
);
static
int
wrtd_user_init
(
void
);
static
void
wrtd_io
(
void
);
...
...
@@ -136,14 +136,13 @@ struct loopback_queue {
SMEM
struct
loopback_queue
lqueues
[
NBR_CPUS
];
static
void
wrtd_remote_output
(
struct
wrtd_event
*
ev
,
static
int
wrtd_remote_output
(
struct
wrtd_event
*
ev
,
unsigned
dest_cpu
,
unsigned
ch
)
{
volatile
struct
loopback_queue
*
q
=
&
lqueues
[
dest_cpu
];
if
(
q
->
count
>=
LOOPBACK_QUEUE_SIZE
)
{
/* FIXME: log. */
return
;
return
-
EOVERFLOW
;
}
/* Get lock. */
...
...
@@ -160,6 +159,8 @@ static void wrtd_remote_output(struct wrtd_event *ev,
q
->
write_idx
=
(
q
->
write_idx
+
1
)
&
(
LOOPBACK_QUEUE_SIZE
-
1
);
smem_atomic_add
(
&
q
->
count
,
1
);
q
->
lock
=
0
;
return
0
;
}
static
void
wrtd_recv_loopback
(
void
)
...
...
@@ -234,13 +235,36 @@ static void ts_now(struct wrtd_tstamp *now)
}
static
void
wrtd_log
(
uint32_t
type
,
uint32_t
reason
,
struct
wrtd_rule
*
rule
,
const
struct
wrtd_event
*
ev
,
const
struct
wrtd_tstamp
*
ts
)
{
struct
wrtd_log_entry
*
log
;
struct
trtl_fw_msg
msg
;
struct
wrtd_tstamp
now
;
int
ret
;
/* First, handle statistics */
if
((
type
==
WRTD_LOG_MSG_EV_DISCARDED
)
&&
(
rule
!=
NULL
))
{
rule
->
stat
.
miss_last
=
ev
->
ts
;
switch
(
reason
)
{
case
WRTD_LOG_DISCARD_NO_SYNC
:
rule
->
stat
.
miss_nosync
++
;
break
;
case
WRTD_LOG_DISCARD_HOLDOFF
:
rule
->
stat
.
miss_holdoff
++
;
break
;
case
WRTD_LOG_DISCARD_TIMEOUT
:
rule
->
stat
.
miss_late
++
;
break
;
case
WRTD_LOG_DISCARD_OVERFLOW
:
rule
->
stat
.
miss_overflow
++
;
break
;
default:
break
;
}
}
if
(
!
(
root
.
log_flags
&
(
1
<<
type
)))
{
root
.
log_nbr_discarded
++
;
return
;
...
...
@@ -252,6 +276,11 @@ static void wrtd_log(uint32_t type, uint32_t reason,
return
;
}
if
(
ts
==
NULL
)
ts_now
(
&
now
);
else
now
=
*
ts
;
mq_map_out_message
(
TRTL_HMQ
,
WRTD_HMQ
,
&
msg
);
msg
.
header
->
flags
=
0
;
...
...
@@ -265,10 +294,9 @@ static void wrtd_log(uint32_t type, uint32_t reason,
log
->
event
=
*
ev
;
else
memset
(
&
log
->
event
,
0
,
sizeof
(
struct
wrtd_event
));
if
(
ts
!=
NULL
)
log
->
ts
=
*
ts
;
else
memset
(
&
log
->
ts
,
0
,
sizeof
(
struct
wrtd_tstamp
));
log
->
ts
=
now
;
mq_send
(
TRTL_HMQ
,
WRTD_HMQ
);
root
.
log_nbr_sent
++
;
...
...
@@ -290,16 +318,14 @@ static void wrtd_init_tx(void)
rmq_bind_out
(
WRTD_RMQ
,
TRTL_EP_ETH
,
&
addr
);
}
static
void
wrtd_send_network
(
struct
wrtd_event
*
ev
)
static
int
wrtd_send_network
(
struct
wrtd_event
*
ev
)
{
int
ret
;
struct
trtl_fw_msg
fw_msg
;
ret
=
mq_claim
(
TRTL_RMQ
,
WRTD_RMQ
);
if
(
ret
<
0
)
{
/* FIXME: log ? */
pr_error
(
"RMQ full
\n\r
"
);
return
;
return
-
EOVERFLOW
;
}
mq_map_out_message
(
TRTL_RMQ
,
WRTD_RMQ
,
&
fw_msg
);
...
...
@@ -327,7 +353,9 @@ static void wrtd_send_network(struct wrtd_event *ev)
mq_send
(
TRTL_RMQ
,
WRTD_RMQ
);
wrtd_log
(
WRTD_LOG_MSG_EV_NETWORK
,
WRTD_LOG_NETWORK_TX
,
ev
,
NULL
);
wrtd_log
(
WRTD_LOG_MSG_EV_NETWORK
,
WRTD_LOG_NETWORK_TX
,
NULL
,
ev
,
NULL
);
return
0
;
}
#endif
...
...
@@ -346,9 +374,9 @@ static void wrtd_route(struct wrtd_rule *rule, const struct wrtd_event *ev)
one. */
if
(
rule
->
conf
.
hold_off_ns
)
{
if
(
ts_cmp
(
&
ev
->
ts
,
&
rule
->
stat
.
hold_off
)
<
0
)
{
rule
->
stat
.
miss_holdoff
++
;
rule
->
stat
.
miss_last
=
ev
->
ts
;
wrtd_log
(
WRTD_LOG_MSG_EV_DISCARDED
,
0
,
ev
,
NULL
);
wrtd_log
(
WRTD_LOG_MSG_EV_DISCARDED
,
WRTD_LOG_DISCARD_HOLDOFF
,
rule
,
ev
,
NULL
);
return
;
}
...
...
@@ -396,8 +424,11 @@ static void wrtd_route(struct wrtd_rule *rule, const struct wrtd_event *ev)
if
(
r
!=
0
)
ts_add2_ns
(
&
tev
.
ts
,
rule
->
conf
.
resync_period_ns
-
r
);
tev
.
ts
.
frac
=
0
;
if
(
rule
->
conf
.
resync_factor
)
ts_add2_ns
(
&
tev
.
ts
,
rule
->
conf
.
resync_period_ns
*
rule
->
conf
.
resync_factor
);
}
ts_add2_ns
(
&
tev
.
ts
,
rule
->
conf
.
resync_delay_ns
);
/* Check with current time. */
if
(
!
rule
->
conf
.
send_late
)
{
...
...
@@ -405,9 +436,9 @@ static void wrtd_route(struct wrtd_rule *rule, const struct wrtd_event *ev)
||
(
tev
.
ts
.
seconds
==
now
.
seconds
&&
tev
.
ts
.
ns
<
now
.
ns
))
{
/* Too late... */
rule
->
stat
.
miss_late
++
;
rule
->
stat
.
miss_last
=
ev
->
ts
;
wrtd_log
(
WRTD_LOG_MSG_EV_DISCARDED
,
0
,
ev
,
&
now
);
wrtd_log
(
WRTD_LOG_MSG_EV_DISCARDED
,
WRTD_LOG_DISCARD_TIMEOUT
,
rule
,
ev
,
&
now
);
return
;
}
}
...
...
@@ -423,29 +454,45 @@ static void wrtd_route(struct wrtd_rule *rule, const struct wrtd_event *ev)
memcpy
(
tev
.
id
,
rule
->
conf
.
dest_id
,
WRTD_ID_LEN
);
tev
.
seq
=
rule
->
stat
.
seq
++
;
/* Send. */
rule
->
stat
.
tx_events
++
;
rule
->
stat
.
tx_last
=
ev
->
ts
;
uint32_t
res
=
0
;
/* Check timing. */
if
(
!
wr_is_timing_ok
())
{
wrtd_log
(
WRTD_LOG_MSG_EV_DISCARDED
,
WRTD_LOG_DISCARD_NO_SYNC
,
rule
,
ev
,
&
now
);
return
;
}
/* Send. */
if
(
rule
->
conf
.
dest_ch
==
WRTD_DEST_CH_NET
)
{
#if WRTD_NET_TX > 0
wrtd_send_network
(
&
tev
);
res
=
wrtd_send_network
(
&
tev
);
#else
wrtd_remote_output
res
=
wrtd_remote_output
(
&
tev
,
rule
->
conf
.
dest_cpu
,
WRTD_DEST_CH_NET
);
#endif
}
else
{
if
(
rule
->
conf
.
dest_cpu
!=
WRTD_DEST_CPU_LOCAL
)
{
#if NBR_CPUS > 1
wrtd_remote_output
res
=
wrtd_remote_output
(
&
tev
,
rule
->
conf
.
dest_cpu
,
rule
->
conf
.
dest_ch
);
#endif
}
else
{
/* Local delivery. */
wrtd_local_output
(
&
tev
,
rule
->
conf
.
dest_ch
);
res
=
wrtd_local_output
(
&
tev
,
rule
->
conf
.
dest_ch
);
}
}
if
(
res
==
-
EOVERFLOW
)
{
wrtd_log
(
WRTD_LOG_MSG_EV_DISCARDED
,
WRTD_LOG_DISCARD_OVERFLOW
,
rule
,
ev
,
&
now
);
}
else
if
(
res
==
0
)
{
rule
->
stat
.
tx_events
++
;
rule
->
stat
.
tx_last
=
ev
->
ts
;
}
}
#if WRTD_LOCAL_RX > 0 || WRTD_NET_RX > 0 || NBR_ALARMS > 0
...
...
@@ -507,11 +554,10 @@ static void wrtd_recv_network(void)
mq_discard
(
TRTL_RMQ
,
WRTD_RMQ
);
wrtd_log
(
WRTD_LOG_MSG_EV_NETWORK
,
WRTD_LOG_NETWORK_RX
,
&
ev
,
NULL
);
wrtd_log
(
WRTD_LOG_MSG_EV_NETWORK
,
WRTD_LOG_NETWORK_RX
,
NULL
,
&
ev
,
NULL
);
wrtd_route_in
(
&
ev
);
/* FIXME: counter ? */
}
#endif
...
...
@@ -530,11 +576,11 @@ static void wrtd_alarms(void)
if
(
!
al
->
enabled
)
continue
;
if
(
ts_cmp
(
&
al
->
setup_time
,
&
now
)
>
0
)
if
(
ts_cmp
(
&
al
->
event
.
ts
,
&
now
)
>
0
)
continue
;
wrtd_log
(
WRTD_LOG_MSG_EV_GENERATED
,
WRTD_LOG_GENERATED_ALARM
,
&
al
->
event
,
&
now
);
NULL
,
&
al
->
event
,
&
now
);
/* Trigger. */
wrtd_route_in
(
&
al
->
event
);
...
...
@@ -553,7 +599,6 @@ static void wrtd_alarms(void)
continue
;
}
ts_add2_ns
(
&
al
->
event
.
ts
,
al
->
period_ns
);
ts_add2_ns
(
&
al
->
setup_time
,
al
->
period_ns
);
}
}
#endif
...
...
software/firmware/fd/wrtd-fd.c
View file @
a0d2fba5
...
...
@@ -184,7 +184,7 @@ static void drop_trigger(struct wrtd_fd_channel *out,
/* Disarm the FD output */
fd_ch_writel
(
out
,
FD_DCR_MODE
,
FD_REG_DCR
);
wrtd_log
(
WRTD_LOG_MSG_EV_DISCARDED
,
reason
,
ev
,
NULL
);
wrtd_log
(
WRTD_LOG_MSG_EV_DISCARDED
,
reason
,
NULL
,
ev
,
NULL
);
}
...
...
@@ -217,7 +217,8 @@ static void fd_output (struct wrtd_fd_dev *fd, unsigned channel)
}
else
{
/* Has been triggered. */
wrtd_log
(
WRTD_LOG_MSG_EV_CONSUMED
,
WRTD_LOG_CONSUMED_DONE
,
ev
,
NULL
);
WRTD_LOG_CONSUMED_DONE
,
NULL
,
ev
,
NULL
);
pulse_queue_pop
(
q
);
out
->
idle
=
1
;
...
...
@@ -256,7 +257,8 @@ static void fd_output (struct wrtd_fd_dev *fd, unsigned channel)
fd_ch_writel
(
out
,
FD_DCR_MODE
|
FD_DCR_PG_ARM
|
FD_DCR_ENABLE
,
FD_REG_DCR
);
wrtd_log
(
WRTD_LOG_MSG_EV_CONSUMED
,
WRTD_LOG_CONSUMED_START
,
ev
,
NULL
);
wrtd_log
(
WRTD_LOG_MSG_EV_CONSUMED
,
WRTD_LOG_CONSUMED_START
,
NULL
,
ev
,
NULL
);
ts_add2_ns
(
ts
,
8000
);
...
...
@@ -269,7 +271,7 @@ static void fd_output (struct wrtd_fd_dev *fd, unsigned channel)
out
->
idle
=
0
;
}
static
void
fd_local_output
(
struct
wrtd_fd_dev
*
fd
,
static
int
fd_local_output
(
struct
wrtd_fd_dev
*
fd
,
struct
wrtd_event
*
ev
,
unsigned
ch
)
{
struct
wrtd_fd_channel
*
out
=
&
fd
->
channels
[
ch
];
...
...
@@ -277,14 +279,12 @@ static void fd_local_output(struct wrtd_fd_dev *fd,
pq_ev
=
pulse_queue_push
(
&
out
->
queue
);
if
(
!
pq_ev
)
{
/* overflow.
FIXME: stats ? */
wrtd_log
(
WRTD_LOG_MSG_EV_DISCARDED
,
WRTD_LOG_DISCARD_OVERFLOW
,
ev
,
NULL
);
return
;
return
-
EOVERFLOW
;
}
*
pq_ev
=
*
ev
;
return
0
;
}
static
void
fd_outputs
(
struct
wrtd_fd_dev
*
fd
)
...
...
software/firmware/fd/wrtd-rt-fd.c
View file @
a0d2fba5
...
...
@@ -64,9 +64,9 @@ static inline int wr_sync_timeout(void)
#endif
}
static
void
wrtd_local_output
(
struct
wrtd_event
*
ev
,
unsigned
ch
)
static
int
wrtd_local_output
(
struct
wrtd_event
*
ev
,
unsigned
ch
)
{
fd_local_output
(
&
fd0
,
ev
,
ch
);
return
fd_local_output
(
&
fd0
,
ev
,
ch
);
}
/**
...
...
software/firmware/tdc/wrtd-rt-tdc.c
View file @
a0d2fba5
...
...
@@ -65,10 +65,10 @@ static inline int wr_sync_timeout(void)
#endif
}
static
void
wrtd_local_output
(
struct
wrtd_event
*
ev
,
unsigned
ch
)
static
int
wrtd_local_output
(
struct
wrtd_event
*
ev
,
unsigned
ch
)
{
/* No output. */
return
;
return
0
;
}
static
int
wrtd_user_init
(
void
)
...
...
software/firmware/tdc/wrtd-tdc.c
View file @
a0d2fba5
...
...
@@ -274,7 +274,8 @@ static void tdc_input(struct wrtd_tdc_dev *tdc)
ev
.
flags
=
0
;
wrtd_log
(
WRTD_LOG_MSG_EV_GENERATED
,
WRTD_LOG_GENERATED_DEVICE
+
(
channel
*
8
),
&
ev
,
NULL
);
WRTD_LOG_GENERATED_DEVICE
+
(
channel
*
8
),
NULL
,
&
ev
,
NULL
);
/* Pass to wrtd. */
wrtd_route_in
(
&
ev
);
...
...
software/include/wrtd-common.h
View file @
a0d2fba5
...
...
@@ -85,7 +85,7 @@ struct wrtd_rule_config {
uint32_t
hold_off_ns
;
uint32_t
resync_period_ns
;
uint32_t
resync_
delay_ns
;
uint32_t
resync_
factor
;
/* Next rule id for the same hash; -1 for last. */
int32_t
hash_chain
;
...
...
@@ -99,6 +99,7 @@ struct wrtd_rule_stats {
struct
wrtd_tstamp
tx_last
;
/* Latency. */
uint32_t
lat_min_ns
;
uint32_t
lat_max_ns
;
uint32_t
lat_lo_ns
;
uint32_t
lat_hi_ns
;
...
...
@@ -106,6 +107,8 @@ struct wrtd_rule_stats {
uint32_t
miss_holdoff
;
uint32_t
miss_late
;
uint32_t
miss_nosync
;
uint32_t
miss_overflow
;
struct
wrtd_tstamp
miss_last
;
/* Events that occur before this time are discarded. */
...
...
@@ -121,9 +124,6 @@ struct wrtd_rule {
};
struct
wrtd_alarm
{
/* Time when to generate the event. */
struct
wrtd_tstamp
setup_time
;
/* Next time and id. */
struct
wrtd_event
event
;
...
...
@@ -256,6 +256,8 @@ enum wrtd_log_reason_type {
/* For DISCARDED: */
/* Not synchronized. */
WRTD_LOG_DISCARD_NO_SYNC
=
1
,
/* Hold-off violation. */
WRTD_LOG_DISCARD_HOLDOFF
,
/* Timeout: event after time. */
WRTD_LOG_DISCARD_TIMEOUT
,
/* No space in a queue. */
...
...
software/lib/libwrtd-attributes.c
View file @
a0d2fba5
...
...
@@ -32,20 +32,32 @@ enum wrtd_status wrtd_alarm_check_disabled(struct wrtd_dev *wrtd, unsigned idx)
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_set_alarm_time
(
struct
wrtd_dev
*
wrtd
,
enum
wrtd_status
wrtd_rule_check_disabled
(
struct
wrtd_dev
*
wrtd
,
unsigned
idx
)
{
if
(
wrtd
->
rules
[
idx
].
rule
.
conf
.
enabled
)
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_RESOURCE_ACTIVE
,
"rule is enabled"
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_set_alarm_period
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
const
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
if
(
value
->
seconds
!=
0
)
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_INVALID_VALUE
,
"alarm period is too large (>1s)"
);
status
=
wrtd_find_alarm
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
status
=
wrtd_alarm_check_disabled
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
wrtd
->
alarms
[
idx
].
alarm
.
event
.
ts
=
*
value
;
wrtd
->
alarms
[
idx
].
alarm
.
period_ns
=
value
->
ns
;
status
=
wrtd_write_alarm
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
...
...
@@ -53,32 +65,23 @@ enum wrtd_status wrtd_attr_set_alarm_time(struct wrtd_dev *wrtd,
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_
s
et_alarm_period
(
struct
wrtd_dev
*
wrtd
,
enum
wrtd_status
wrtd_attr_
g
et_alarm_period
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
const
struct
wrtd_tstamp
*
value
)
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
if
(
value
->
seconds
!=
0
)
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_INVALID_VALUE
,
"alarm period is too large (>1s)"
);
status
=
wrtd_find_alarm
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
status
=
wrtd_alarm_check_disabled
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
wrtd
->
alarms
[
idx
].
alarm
.
period_ns
=
value
->
ns
;
status
=
wrtd_write_alarm
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
memset
(
value
,
0
,
sizeof
(
struct
wrtd_tstamp
));
wrtd_ts_add_ns
(
value
,
wrtd
->
alarms
[
idx
].
alarm
.
period_ns
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_set_alarm_
setup_
time
(
struct
wrtd_dev
*
wrtd
,
enum
wrtd_status
wrtd_attr_set_alarm_time
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
const
struct
wrtd_tstamp
*
value
)
{
...
...
@@ -91,7 +94,7 @@ enum wrtd_status wrtd_attr_set_alarm_setup_time(struct wrtd_dev *wrtd,
status
=
wrtd_alarm_check_disabled
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
wrtd
->
alarms
[
idx
].
alarm
.
setup_time
=
*
value
;
wrtd
->
alarms
[
idx
].
alarm
.
event
.
ts
=
*
value
;
status
=
wrtd_write_alarm
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
...
...
@@ -99,6 +102,21 @@ enum wrtd_status wrtd_attr_set_alarm_setup_time(struct wrtd_dev *wrtd,
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_alarm_time
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_alarm
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
alarms
[
idx
].
alarm
.
event
.
ts
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_set_alarm_enable
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
bool
value
)
...
...
@@ -137,12 +155,12 @@ enum wrtd_status wrtd_attr_get_alarm_enable(struct wrtd_dev *wrtd,
enum
wrtd_status
wrtd_attr_set_alarm_repeat_count
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
int32_t
count
)
int32_t
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
if
(
count
<
0
)
if
(
value
<
0
)
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_INVALID_VALUE
,
"alarm repeat count < 0"
);
...
...
@@ -152,7 +170,7 @@ enum wrtd_status wrtd_attr_set_alarm_repeat_count(struct wrtd_dev *wrtd,
status
=
wrtd_alarm_check_disabled
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
wrtd
->
alarms
[
idx
].
alarm
.
repeat_count
=
count
==
0
?
0
:
count
+
1
;
wrtd
->
alarms
[
idx
].
alarm
.
repeat_count
=
value
==
0
?
0
:
value
+
1
;
status
=
wrtd_write_alarm
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
...
...
@@ -160,6 +178,61 @@ enum wrtd_status wrtd_attr_set_alarm_repeat_count(struct wrtd_dev *wrtd,
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_alarm_repeat_count
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
int32_t
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_alarm
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
alarms
[
idx
].
alarm
.
repeat_count
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_set_rule_repeat_count
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
int32_t
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
if
(
value
<
0
)
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_INVALID_VALUE
,
"rule repeat count < 0"
);
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
status
=
wrtd_rule_check_disabled
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
wrtd
->
rules
[
idx
].
rule
.
conf
.
repeat_count
=
value
==
0
?
0
:
value
+
1
;
status
=
wrtd_write_rule
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_rule_repeat_count
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
int32_t
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
rules
[
idx
].
rule
.
conf
.
repeat_count
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_set_log_enable
(
struct
wrtd_dev
*
wrtd
,
bool
value
)
{
...
...
@@ -178,14 +251,55 @@ enum wrtd_status wrtd_attr_set_log_enable(struct wrtd_dev *wrtd,
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_rule_check_disabled
(
struct
wrtd_dev
*
wrtd
,
unsigned
idx
)
enum
wrtd_status
wrtd_attr_get_log_enable
(
struct
wrtd_dev
*
wrtd
,
bool
*
value
)
{
if
(
wrtd
->
rules
[
idx
].
rule
.
conf
.
enabled
)
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_RESOURCE_ACTIVE
,
"rule is enabled"
);
enum
wrtd_status
status
;
status
=
wrtd_fill_roots
(
wrtd
);
WRTD_RETURN_IF_ERROR
(
status
);
/* all cpus have the same flags, it's enough to read one */
*
value
=
wrtd
->
roots
[
0
].
log_flags
!=
0
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_log_empty
(
struct
wrtd_dev
*
wrtd
,
bool
*
value
)
{
struct
polltrtl
p
[
WRTD_MAX_CPUS
];
int
ret
,
i
;
for
(
i
=
0
;
i
<
wrtd
->
nbr_cpus
;
++
i
)
{
p
[
i
].
trtl
=
wrtd
->
trtl
;
p
[
i
].
idx_hmq
=
WRTD_HMQ
;
p
[
i
].
idx_cpu
=
i
;
p
[
i
].
events
=
POLLIN
;
}
ret
=
trtl_msg_poll
(
p
,
wrtd
->
nbr_cpus
,
0
);
if
(
ret
<
0
)
return
WRTD_ERROR_UNEXPECTED_RESPONSE
;
*
value
=
(
ret
==
0
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_time_sync
(
struct
wrtd_dev
*
wrtd
,
bool
*
value
)
{
struct
wrtd_config_msg
msg
;
enum
wrtd_status
status
;
status
=
wrtd_msg_get_config
(
wrtd
,
0
,
&
msg
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
(
msg
.
sync_flag
!=
0
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_find_rule_check
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
...
...
@@ -203,11 +317,11 @@ enum wrtd_status wrtd_find_rule_check(struct wrtd_dev *wrtd,
}
enum
wrtd_status
wrtd_attr_get_rule_count
(
struct
wrtd_dev
*
wrtd
,
unsigned
*
value
)
int32_t
*
value
)
{
enum
wrtd_status
status
;
unsigned
i
;
unsigned
res
;
int32_t
res
;
status
=
wrtd_fill_rules
(
wrtd
);
WRTD_RETURN_IF_ERROR
(
status
);
...
...
@@ -323,9 +437,9 @@ enum wrtd_status wrtd_attr_set_rule_delay(struct wrtd_dev *wrtd,
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_rule_
enable
(
struct
wrtd_dev
*
wrtd
,
enum
wrtd_status
wrtd_attr_get_rule_
delay
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
bool
*
value
)
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
...
...
@@ -333,7 +447,338 @@ enum wrtd_status wrtd_attr_get_rule_enable(struct wrtd_dev *wrtd,
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
rules
[
idx
].
rule
.
conf
.
enabled
!=
0
;
memset
(
value
,
0
,
sizeof
(
struct
wrtd_tstamp
));
wrtd_ts_add_ns
(
value
,
wrtd
->
rules
[
idx
].
rule
.
conf
.
delay_ns
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_set_rule_holdoff
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
const
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
if
(
value
->
seconds
!=
0
)
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_INVALID_VALUE
,
"rule holdoff is too large (>1s)"
);
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
status
=
wrtd_rule_check_disabled
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
wrtd
->
rules
[
idx
].
rule
.
conf
.
hold_off_ns
=
value
->
ns
;
status
=
wrtd_write_rule
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_rule_holdoff
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
memset
(
value
,
0
,
sizeof
(
struct
wrtd_tstamp
));
wrtd_ts_add_ns
(
value
,
wrtd
->
rules
[
idx
].
rule
.
conf
.
hold_off_ns
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_set_rule_resync_period
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
const
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
if
(
value
->
seconds
!=
0
)
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_INVALID_VALUE
,
"rule resync period is too large (>1s)"
);
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
status
=
wrtd_rule_check_disabled
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
wrtd
->
rules
[
idx
].
rule
.
conf
.
resync_period_ns
=
value
->
ns
;
status
=
wrtd_write_rule
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_rule_resync_period
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
memset
(
value
,
0
,
sizeof
(
struct
wrtd_tstamp
));
wrtd_ts_add_ns
(
value
,
wrtd
->
rules
[
idx
].
rule
.
conf
.
resync_period_ns
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_stat_rule_rx_last
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
rules
[
idx
].
rule
.
stat
.
rx_last
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_stat_rule_tx_last
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
rules
[
idx
].
rule
.
stat
.
tx_last
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_stat_rule_missed_last
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
rules
[
idx
].
rule
.
stat
.
miss_last
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_stat_rule_rx_latency_min
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
memset
(
value
,
0
,
sizeof
(
struct
wrtd_tstamp
));
wrtd_ts_add_ns
(
value
,
wrtd
->
rules
[
idx
].
rule
.
stat
.
lat_min_ns
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_stat_rule_rx_latency_max
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
memset
(
value
,
0
,
sizeof
(
struct
wrtd_tstamp
));
wrtd_ts_add_ns
(
value
,
wrtd
->
rules
[
idx
].
rule
.
stat
.
lat_max_ns
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_stat_rule_rx_latency_avg
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
uint64_t
latency
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
latency
=
wrtd
->
rules
[
idx
].
rule
.
stat
.
lat_hi_ns
;
latency
<<=
32
;
latency
|=
wrtd
->
rules
[
idx
].
rule
.
stat
.
lat_lo_ns
;
latency
/=
wrtd
->
rules
[
idx
].
rule
.
stat
.
lat_nbr
;
memset
(
value
,
0
,
sizeof
(
struct
wrtd_tstamp
));
wrtd_ts_add_ns
(
value
,
latency
&
0xffffffff
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_stat_rule_rx_period_avg
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
unsigned
int
period
;
struct
wrtd_tstamp
last
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
last
=
wrtd
->
rules
[
idx
].
rule
.
stat
.
rx_last
;
period
=
(
last
.
seconds
*
1000000000
+
last
.
ns
);
period
/=
wrtd
->
rules
[
idx
].
rule
.
stat
.
rx_events
;
memset
(
value
,
0
,
sizeof
(
struct
wrtd_tstamp
));
wrtd_ts_add_ns
(
value
,
period
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_set_rule_resync_factor
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
int32_t
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
status
=
wrtd_rule_check_disabled
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
wrtd
->
rules
[
idx
].
rule
.
conf
.
resync_factor
=
value
;
status
=
wrtd_write_rule
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_rule_resync_factor
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
int32_t
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
rules
[
idx
].
rule
.
conf
.
resync_factor
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_stat_rule_rx_events
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
int32_t
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
rules
[
idx
].
rule
.
stat
.
rx_events
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_stat_rule_tx_events
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
int32_t
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
rules
[
idx
].
rule
.
stat
.
tx_events
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_stat_rule_missed_late
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
int32_t
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
rules
[
idx
].
rule
.
stat
.
miss_late
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_stat_rule_missed_holdoff
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
int32_t
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
rules
[
idx
].
rule
.
stat
.
miss_holdoff
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_stat_rule_missed_nosync
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
int32_t
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
rules
[
idx
].
rule
.
stat
.
miss_nosync
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_stat_rule_missed_overflow
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
int32_t
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
rules
[
idx
].
rule
.
stat
.
miss_overflow
;
return
WRTD_SUCCESS
;
}
...
...
@@ -358,6 +803,59 @@ enum wrtd_status wrtd_attr_set_rule_enable(struct wrtd_dev *wrtd,
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_rule_enable
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
bool
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
rules
[
idx
].
rule
.
conf
.
enabled
!=
0
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_set_rule_send_late
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
bool
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
status
=
wrtd_rule_check_disabled
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
if
(
wrtd
->
rules
[
idx
].
rule
.
conf
.
send_late
!=
value
)
{
wrtd
->
rules
[
idx
].
rule
.
conf
.
send_late
=
value
;
status
=
wrtd_write_rule
(
wrtd
,
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
}
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_get_rule_send_late
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
bool
*
value
)
{
enum
wrtd_status
status
;
unsigned
int
idx
;
status
=
wrtd_find_rule
(
wrtd
,
rep_cap_id
,
&
idx
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
wrtd
->
rules
[
idx
].
rule
.
conf
.
send_late
!=
0
;
return
WRTD_SUCCESS
;
}
enum
wrtd_status
wrtd_attr_global
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
)
{
...
...
@@ -379,33 +877,60 @@ enum wrtd_status wrtd_get_attr_int32(struct wrtd_dev *wrtd,
switch
(
id
)
{
case
WRTD_MAJOR_VERSION
:
status
=
wrtd_attr_global
(
wrtd
,
rep_cap_id
);
status
=
wrtd_attr_global
(
wrtd
,
rep_cap_id
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
WRTD_VERSION_MAJOR
;
return
WRTD_SUCCESS
;
case
WRTD_MINOR_VERSION
:
status
=
wrtd_attr_global
(
wrtd
,
rep_cap_id
);
status
=
wrtd_attr_global
(
wrtd
,
rep_cap_id
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
WRTD_VERSION_MINOR
;
return
WRTD_SUCCESS
;
case
WRTD_ATTR_ALARM_COUNT
:
status
=
wrtd_attr_global
(
wrtd
,
rep_cap_id
);
status
=
wrtd_attr_global
(
wrtd
,
rep_cap_id
);
WRTD_RETURN_IF_ERROR
(
status
);
status
=
wrtd_attr_get_alarm_count
(
wrtd
,
value
);
status
=
wrtd_attr_get_alarm_count
(
wrtd
,
value
);
WRTD_RETURN_IF_ERROR
(
status
);
return
WRTD_SUCCESS
;
case
WRTD_ATTR_ALARM_REPEAT_COUNT
:
return
wrtd_attr_get_alarm_repeat_count
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_RULE_COUNT
:
{
unsigned
val
;
status
=
wrtd_attr_global
(
wrtd
,
rep_cap_id
);
status
=
wrtd_attr_global
(
wrtd
,
rep_cap_id
);
WRTD_RETURN_IF_ERROR
(
status
);
status
=
wrtd_attr_get_rule_count
(
wrtd
,
&
val
);
status
=
wrtd_attr_get_rule_count
(
wrtd
,
value
);
WRTD_RETURN_IF_ERROR
(
status
);
*
value
=
val
;
return
WRTD_SUCCESS
;
}
case
WRTD_ATTR_RULE_REPEAT_COUNT
:
return
wrtd_attr_get_rule_repeat_count
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_RULE_RESYNC_FACTOR
:
return
wrtd_attr_get_rule_resync_factor
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_STAT_RULE_RX_EVENTS
:
return
wrtd_attr_get_stat_rule_rx_events
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_STAT_RULE_TX_EVENTS
:
return
wrtd_attr_get_stat_rule_tx_events
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_STAT_RULE_MISSED_LATE
:
return
wrtd_attr_get_stat_rule_missed_late
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_STAT_RULE_MISSED_HOLDOFF
:
return
wrtd_attr_get_stat_rule_missed_holdoff
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_STAT_RULE_MISSED_NOSYNC
:
return
wrtd_attr_get_stat_rule_missed_holdoff
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_STAT_RULE_MISSED_OVERFLOW
:
return
wrtd_attr_get_stat_rule_missed_overflow
(
wrtd
,
rep_cap_id
,
value
);
default:
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_INVALID_ATTRIBUTE
,
...
...
@@ -425,13 +950,84 @@ enum wrtd_status wrtd_set_attr_tstamp(struct wrtd_dev *wrtd,
switch
(
id
)
{
case
WRTD_ATTR_ALARM_TIME
:
return
wrtd_attr_set_alarm_time
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_ALARM_SETUP_TIME
:
return
wrtd_attr_set_alarm_setup_time
(
wrtd
,
rep_cap_id
,
value
);
return
wrtd_attr_set_alarm_time
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_ALARM_PERIOD
:
return
wrtd_attr_set_alarm_period
(
wrtd
,
rep_cap_id
,
value
);
return
wrtd_attr_set_alarm_period
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_RULE_DELAY
:
return
wrtd_attr_set_rule_delay
(
wrtd
,
rep_cap_id
,
value
);
return
wrtd_attr_set_rule_delay
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_RULE_HOLDOFF
:
return
wrtd_attr_set_rule_holdoff
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_RULE_RESYNC_PERIOD
:
return
wrtd_attr_set_rule_resync_period
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_STAT_RULE_RX_LAST
:
case
WRTD_ATTR_STAT_RULE_TX_LAST
:
case
WRTD_ATTR_STAT_RULE_MISSED_LAST
:
case
WRTD_ATTR_STAT_RULE_RX_LATENCY_MIN
:
case
WRTD_ATTR_STAT_RULE_RX_LATENCY_MAX
:
case
WRTD_ATTR_STAT_RULE_RX_LATENCY_AVG
:
case
WRTD_ATTR_STAT_RULE_RX_PERIOD_AVG
:
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_ATTR_NOT_WRITEABLE
,
"attribute %u is not writeable"
,
id
);
default:
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_INVALID_ATTRIBUTE
,
"tstamp attribute %u is not known"
,
id
);
}
}
enum
wrtd_status
wrtd_get_attr_tstamp
(
struct
wrtd_dev
*
wrtd
,
const
char
*
rep_cap_id
,
enum
wrtd_attr
id
,
struct
wrtd_tstamp
*
value
)
{
enum
wrtd_status
status
;
status
=
wrtd_validate_id
(
wrtd
,
rep_cap_id
);
WRTD_RETURN_IF_ERROR
(
status
);
switch
(
id
)
{
case
WRTD_ATTR_ALARM_TIME
:
return
wrtd_attr_get_alarm_time
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_ALARM_PERIOD
:
return
wrtd_attr_get_alarm_period
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_RULE_DELAY
:
return
wrtd_attr_get_rule_delay
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_RULE_HOLDOFF
:
return
wrtd_attr_get_rule_holdoff
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_RULE_RESYNC_PERIOD
:
return
wrtd_attr_get_rule_resync_period
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_STAT_RULE_RX_LAST
:
return
wrtd_attr_get_stat_rule_rx_last
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_STAT_RULE_TX_LAST
:
return
wrtd_attr_get_stat_rule_tx_last
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_STAT_RULE_MISSED_LAST
:
return
wrtd_attr_get_stat_rule_missed_last
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_STAT_RULE_RX_LATENCY_MIN
:
return
wrtd_attr_get_stat_rule_rx_latency_min
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_STAT_RULE_RX_LATENCY_MAX
:
return
wrtd_attr_get_stat_rule_rx_latency_max
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_STAT_RULE_RX_LATENCY_AVG
:
return
wrtd_attr_get_stat_rule_rx_latency_avg
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_STAT_RULE_RX_PERIOD_AVG
:
return
wrtd_attr_get_stat_rule_rx_period_avg
(
wrtd
,
rep_cap_id
,
value
);
default:
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_INVALID_ATTRIBUTE
,
...
...
@@ -451,13 +1047,25 @@ enum wrtd_status wrtd_set_attr_bool(struct wrtd_dev *wrtd,
switch
(
id
)
{
case
WRTD_ATTR_EVENT_LOG_ENABLED
:
status
=
wrtd_attr_global
(
wrtd
,
rep_cap_id
);
status
=
wrtd_attr_global
(
wrtd
,
rep_cap_id
);
WRTD_RETURN_IF_ERROR
(
status
);
return
wrtd_attr_set_log_enable
(
wrtd
,
value
);
return
wrtd_attr_set_log_enable
(
wrtd
,
value
);
case
WRTD_ATTR_ALARM_ENABLED
:
return
wrtd_attr_set_alarm_enable
(
wrtd
,
rep_cap_id
,
value
);
return
wrtd_attr_set_alarm_enable
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_RULE_ENABLED
:
return
wrtd_attr_set_rule_enable
(
wrtd
,
rep_cap_id
,
value
);
return
wrtd_attr_set_rule_enable
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_RULE_SEND_LATE
:
return
wrtd_attr_set_rule_send_late
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_EVENT_LOG_EMPTY
:
case
WRTD_ATTR_IS_TIME_SYNCHRONIZED
:
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_ATTR_NOT_WRITEABLE
,
"attribute %u is not writeable"
,
id
);
default:
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_INVALID_ATTRIBUTE
,
...
...
@@ -476,10 +1084,33 @@ enum wrtd_status wrtd_get_attr_bool(struct wrtd_dev *wrtd,
WRTD_RETURN_IF_ERROR
(
status
);
switch
(
id
)
{
case
WRTD_ATTR_EVENT_LOG_ENABLED
:
status
=
wrtd_attr_global
(
wrtd
,
rep_cap_id
);
WRTD_RETURN_IF_ERROR
(
status
);
return
wrtd_attr_get_log_enable
(
wrtd
,
value
);
case
WRTD_ATTR_EVENT_LOG_EMPTY
:
status
=
wrtd_attr_global
(
wrtd
,
rep_cap_id
);
WRTD_RETURN_IF_ERROR
(
status
);
return
wrtd_attr_get_log_empty
(
wrtd
,
value
);
case
WRTD_ATTR_IS_TIME_SYNCHRONIZED
:
status
=
wrtd_attr_global
(
wrtd
,
rep_cap_id
);
WRTD_RETURN_IF_ERROR
(
status
);
return
wrtd_attr_get_time_sync
(
wrtd
,
value
);
case
WRTD_ATTR_ALARM_ENABLED
:
return
wrtd_attr_get_alarm_enable
(
wrtd
,
rep_cap_id
,
value
);
return
wrtd_attr_get_alarm_enable
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_RULE_ENABLED
:
return
wrtd_attr_get_rule_enable
(
wrtd
,
rep_cap_id
,
value
);
return
wrtd_attr_get_rule_enable
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_RULE_SEND_LATE
:
return
wrtd_attr_get_rule_send_late
(
wrtd
,
rep_cap_id
,
value
);
default:
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_INVALID_ATTRIBUTE
,
...
...
@@ -501,6 +1132,25 @@ enum wrtd_status wrtd_set_attr_int32(struct wrtd_dev *wrtd,
case
WRTD_ATTR_ALARM_REPEAT_COUNT
:
return
wrtd_attr_set_alarm_repeat_count
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_RULE_REPEAT_COUNT
:
return
wrtd_attr_set_rule_repeat_count
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_ATTR_RULE_RESYNC_FACTOR
:
return
wrtd_attr_set_rule_resync_factor
(
wrtd
,
rep_cap_id
,
value
);
case
WRTD_MAJOR_VERSION
:
case
WRTD_MINOR_VERSION
:
case
WRTD_ATTR_ALARM_COUNT
:
case
WRTD_ATTR_RULE_COUNT
:
case
WRTD_ATTR_STAT_RULE_RX_EVENTS
:
case
WRTD_ATTR_STAT_RULE_TX_EVENTS
:
case
WRTD_ATTR_STAT_RULE_MISSED_LATE
:
case
WRTD_ATTR_STAT_RULE_MISSED_HOLDOFF
:
case
WRTD_ATTR_STAT_RULE_MISSED_NOSYNC
:
case
WRTD_ATTR_STAT_RULE_MISSED_OVERFLOW
:
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_ATTR_NOT_WRITEABLE
,
"attribute %u is not writeable"
,
id
);
default:
return
wrtd_return_error
(
wrtd
,
WRTD_ERROR_INVALID_ATTRIBUTE
,
...
...
software/lib/libwrtd-private.h
View file @
a0d2fba5
...
...
@@ -7,6 +7,16 @@
#define WRTD_RETURN_IF_ERROR(status) if(status != WRTD_SUCCESS) return status
/* Add nanoseconds to an existing wrtd timestamp */
static
inline
void
wrtd_ts_add_ns
(
struct
wrtd_tstamp
*
ts
,
uint32_t
ns
)
{
ts
->
ns
+=
ns
;
while
(
ts
->
ns
>=
1000000000
)
{
ts
->
ns
-=
1000000000
;
ts
->
seconds
++
;
}
}
/* Alarm when in user space. */
struct
wrtd_lib_alarm
{
/* CPU on which the alarm is. */
...
...
@@ -136,7 +146,7 @@ enum wrtd_status wrtd_fill_rules(struct wrtd_dev *wrtd);
/* Count number of rules. */
enum
wrtd_status
wrtd_attr_get_rule_count
(
struct
wrtd_dev
*
wrtd
,
unsigned
*
value
);
int32_t
*
value
);
/* Reconfigure route tables and write-back rules. */
enum
wrtd_status
wrtd_reconfigure
(
struct
wrtd_dev
*
wrtd
);
...
...
software/lib/libwrtd-rules.c
View file @
a0d2fba5
...
...
@@ -45,10 +45,12 @@ static enum wrtd_status wrtd_reconfigure_alloc_map(struct wrtd_dev *wrtd,
unsigned
n
;
unsigned
i
;
unsigned
ch_in_idx
,
ch_out_idx
;
int32_t
nrules
;
/* 1. Count number of rules. */
status
=
wrtd_attr_get_rule_count
(
wrtd
,
&
map
->
nbr_
rules
);
status
=
wrtd_attr_get_rule_count
(
wrtd
,
&
n
rules
);
WRTD_RETURN_IF_ERROR
(
status
);
map
->
nbr_rules
=
nrules
;
/* Count number of devices. */
n
=
0
;
...
...
software/lib/libwrtd.h
View file @
a0d2fba5
...
...
@@ -77,12 +77,12 @@ enum wrtd_status {
*/
enum
wrtd_attr
{
__WRTD_ATTR_BASE
=
950000
,
WRTD_MAJOR_VERSION
,
// RO, int32
WRTD_MINOR_VERSION
,
// RO, int32
WRTD_ATTR_EVENT_LOG_E
NTRY_COUNT
,
// RO, int32
WRTD_ATTR_EVENT_LOG_E
MPTY
,
// RO, bool
WRTD_ATTR_EVENT_LOG_ENABLED
,
//RW, bool
// TODO: add log levels/masks here
WRTD_ATTR_IS_TIME_MASTER
,
// RO, bool
// TODO: WRTD_ATTR_IS_TIME_MASTER, // RO, bool
WRTD_ATTR_IS_TIME_SYNCHRONIZED
,
// RO, bool
// Number of alarms (global attribute).
...
...
@@ -91,7 +91,7 @@ enum wrtd_attr {
// Enable/disable an alarm.
WRTD_ATTR_ALARM_ENABLED
,
//RW, bool
// Specifies at what time to trigger the alarm
WRTD_ATTR_ALARM_
SETUP_
TIME
,
//RW, tstamp
WRTD_ATTR_ALARM_TIME
,
//RW, tstamp
// Specifies the alarm period. 0 means no repetitions.
WRTD_ATTR_ALARM_PERIOD
,
//RW, tstamp
// Specifies the number of times the alarm will occur at the period specified by
...
...
@@ -122,24 +122,21 @@ enum wrtd_attr {
WRTD_ATTR_RULE_RESYNC_PERIOD
,
//RW, tstamp
WRTD_ATTR_RULE_RESYNC_FACTOR
,
//RW, int32
// TODO: add __ boundaries between groups to make it easier
// to do input validation
/* Statistics */
WRTD_ATTR_STAT_RULE_RX_EVENTS
,
//RO, int32
WRTD_ATTR_STAT_RULE_RX_LAST
,
//RO, tstamp
WRTD_ATTR_STAT_RULE_TX_EVENTS
,
//RO, int32
WRTD_ATTR_STAT_RULE_TX_LAST
,
//RO, tstamp
WRTD_ATTR_STAT_RULE_MISSED_EVENTS_LATE
,
//RO, int32
WRTD_ATTR_STAT_RULE_MISSED_EVENTS_HOLDOFF
,
//RO, int32
WRTD_ATTR_STAT_RULE_MISSED_EVENTS_OVERFLOW
,
//RO, int32
WRTD_ATTR_STAT_RULE_MISSED_LATE
,
//RO, int32
WRTD_ATTR_STAT_RULE_MISSED_HOLDOFF
,
//RO, int32
WRTD_ATTR_STAT_RULE_MISSED_NOSYNC
,
//RO, int32
WRTD_ATTR_STAT_RULE_MISSED_OVERFLOW
,
//RO, int32
WRTD_ATTR_STAT_RULE_MISSED_LAST
,
//RO, tstamp
WRTD_ATTR_STAT_RULE_RX_LATENCY_MIN
,
//RO, tstamp
WRTD_ATTR_STAT_RULE_RX_LATENCY_MAX
,
//RO, tstamp
WRTD_ATTR_STAT_RULE_RX_LATENCY_AVG
,
//RO, tstamp
WRTD_ATTR_STAT_RULE_RX_PERIOD_AVG
,
//RO, tstamp
/* Latency and period (excluding events discarded due to holdoff). */
WRTD_ATTR_STAT_RULE_RX_LATENCY_MIN
,
//RO, tstamp (maybe ns only valid)
WRTD_ATTR_STAT_RULE_RX_LATENCY_MAX
,
//RO, tstamp (maybe ns only valid)
WRTD_ATTR_STAT_RULE_RX_LATENCY_AVG
,
//RO, tstamp (maybe ns only valid)
WRTD_ATTR_STAT_RULE_RX_PERIOD_MIN
,
//RO, tstamp (maybe ns only valid)
WRTD_ATTR_STAT_RULE_RX_PERIOD_MAX
,
//RO, tstamp (maybe ns only valid)
WRTD_ATTR_STAT_RULE_RX_PERIOD_AVG
,
//RO, tstamp (maybe ns only valid)
__WRTD_ATTR_MAX_NUMBER
,
};
...
...
@@ -156,7 +153,6 @@ enum wrtd_attr {
* Set of functions to manage the basic device and library configuration.
* @{
*/
// Ideally, also be able to list possible names
extern
enum
wrtd_status
wrtd_init
(
const
char
*
resource_name
,
bool
reset
,
const
char
*
options_str
,
...
...
@@ -173,18 +169,6 @@ extern enum wrtd_status wrtd_error_message(struct wrtd_dev *dev,
/* Attributes. */
extern
enum
wrtd_status
wrtd_get_attr_int32
(
struct
wrtd_dev
*
dev
,
const
char
*
rep_cap_id
,
enum
wrtd_attr
id
,
int32_t
*
value
);
extern
enum
wrtd_status
wrtd_set_attr_int32
(
struct
wrtd_dev
*
dev
,
const
char
*
rep_cap_id
,
enum
wrtd_attr
id
,
int32_t
value
);
extern
enum
wrtd_status
wrtd_set_attr_int64
(
struct
wrtd_dev
*
dev
,
const
char
*
rep_cap_id
,
enum
wrtd_attr
id
,
int64_t
value
);
extern
enum
wrtd_status
wrtd_get_attr_bool
(
struct
wrtd_dev
*
dev
,
const
char
*
rep_cap_id
,
enum
wrtd_attr
id
,
...
...
@@ -193,6 +177,14 @@ extern enum wrtd_status wrtd_set_attr_bool(struct wrtd_dev *dev,
const
char
*
rep_cap_id
,
enum
wrtd_attr
id
,
bool
value
);
extern
enum
wrtd_status
wrtd_get_attr_int32
(
struct
wrtd_dev
*
dev
,
const
char
*
rep_cap_id
,
enum
wrtd_attr
id
,
int32_t
*
value
);
extern
enum
wrtd_status
wrtd_set_attr_int32
(
struct
wrtd_dev
*
dev
,
const
char
*
rep_cap_id
,
enum
wrtd_attr
id
,
int32_t
value
);
extern
enum
wrtd_status
wrtd_get_attr_tstamp
(
struct
wrtd_dev
*
dev
,
const
char
*
rep_cap_id
,
enum
wrtd_attr
id
,
...
...
@@ -205,10 +197,6 @@ extern enum wrtd_status wrtd_set_attr_string(struct wrtd_dev *dev,
const
char
*
rep_cap_id
,
enum
wrtd_attr
id
,
const
char
*
value
);
extern
enum
wrtd_status
wrtd_get_attr_int64
(
struct
wrtd_dev
*
dev
,
const
char
*
rep_cap_id
,
enum
wrtd_attr
id
,
int64_t
*
value
);
extern
enum
wrtd_status
wrtd_get_attr_string
(
struct
wrtd_dev
*
dev
,
const
char
*
rep_cap_id
,
enum
wrtd_attr
id
,
...
...
@@ -289,34 +277,6 @@ extern enum wrtd_status wrtd_get_rule_id(struct wrtd_dev *dev,
extern
enum
wrtd_status
wrtd_reset_rule_stats
(
struct
wrtd_dev
*
dev
,
const
char
*
rep_cap_id
);
/**@}*/
// ===========================================================================
// BEGIN DEPRECATED
// ===========================================================================
/**
* Status description for an input channel
*/
struct
wrtd_input_state
{
struct
wrtd_tstamp
tdc_timebase_offset
;
/**< TDC time base offset */
};
/**
* Status description for an output channel
*/
struct
wrtd_output_state
{
struct
wrtd_tstamp
pulse_width
;
/**< Pulse width */
};
/**@}*/
/**@}*/
// ===========================================================================
// END DEPRECATED
// ===========================================================================
#ifdef __cplusplus
};
...
...
software/tools/wrtd-config.c
View file @
a0d2fba5
...
...
@@ -98,9 +98,6 @@ static void disp_alarm(const struct wrtd_alarm *alarm)
" enabled: %d
\n
"
,
alarm
->
enabled
);
printf
(
" next time: "
);
print_ts
(
&
alarm
->
event
.
ts
);
printf
(
"
\n
"
" setup time: "
);
print_ts
(
&
alarm
->
setup_time
);
printf
(
"
\n
"
" repeat count: %d
\n
"
,
alarm
->
repeat_count
);
printf
(
" period: "
);
...
...
@@ -142,8 +139,8 @@ static void disp_rule_conf(const struct wrtd_rule *rule, unsigned nbr_rules)
" resync_period_ns: "
);
print_ns
(
cfg
->
resync_period_ns
);
printf
(
"
\n
"
" resync_
delay_ns
: "
);
print_ns
(
cfg
->
resync_
delay_ns
);
" resync_
factor
: "
);
print_ns
(
cfg
->
resync_
factor
);
printf
(
"
\n
"
);
}
...
...
@@ -493,7 +490,7 @@ static enum wrtd_status wrtd_cmd_set_alarm(struct wrtd_dev *wrtd,
ts_sub_ps
(
&
ts
,
setup
);
status
=
wrtd_set_attr_tstamp
(
wrtd
,
id
,
WRTD_ATTR_ALARM_
SETUP_
TIME
,
&
ts
);
WRTD_ATTR_ALARM_TIME
,
&
ts
);
WRTD_RETURN_IF_ERROR
(
status
);
/* Set repeat count. */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment