Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
P
PPSi
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
50
Issues
50
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
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
PPSi
Commits
5d9b4c65
Commit
5d9b4c65
authored
Nov 08, 2022
by
Adam Wujek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
arch-unix: fix architecture
Signed-off-by:
Adam Wujek
<
dev_public@wujek.eu
>
parent
c3672fd9
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
209 additions
and
41 deletions
+209
-41
Makefile
arch-unix/Makefile
+5
-1
main-loop.c
arch-unix/main-loop.c
+40
-26
unix-startup.c
arch-unix/unix-startup.c
+164
-14
No files found.
arch-unix/Makefile
View file @
5d9b4c65
...
...
@@ -4,6 +4,9 @@ A := arch-$(ARCH)
CFLAGS
+=
-Itools
# needed for --gc-sections option of ld
PPSI_O_LDFLAGS
=
--entry
=
main
OBJ-y
+=
$A
/unix-startup.o
\
$A
/main-loop.o
\
$A
/unix-io.o
\
...
...
@@ -14,7 +17,8 @@ OBJ-y += $A/unix-startup.o \
lib/dump-funcs.o
\
lib/drop.o
\
lib/assert.o
\
lib/div64.o
lib/div64.o
\
lib/time-arith.o
# The user can set TIME=, but we pick unix time by default
TIME
?=
unix
...
...
arch-unix/main-loop.c
View file @
5d9b4c65
/*
* Copyright (C) 2011 CERN (www.cern.ch)
* Copyright (C) 2011
-2022
CERN (www.cern.ch)
* Author: Alessandro Rubini
*
* Released to the public domain
...
...
@@ -24,8 +24,26 @@ static int run_all_state_machines(struct pp_globals *ppg)
int
j
;
int
delay_ms
=
0
,
delay_ms_j
;
/* TODO: check if in GM mode and initialized */
for
(
j
=
0
;
j
<
ppg
->
nlinks
;
j
++
)
{
struct
pp_instance
*
ppi
=
INST
(
ppg
,
j
);
int
old_lu
=
ppi
->
link_up
;
/* TODO: add the proper discovery of link_up */
ppi
->
link_up
=
1
;
if
(
old_lu
!=
ppi
->
link_up
)
{
pp_diag
(
ppi
,
fsm
,
1
,
"iface %s went %s
\n
"
,
ppi
->
iface_name
,
ppi
->
link_up
?
"up"
:
"down"
);
if
(
ppi
->
link_up
)
{
ppi
->
state
=
PPS_INITIALIZING
;
/* TODO: Get calibration values here */
}
}
delay_ms_j
=
pp_state_machine
(
ppi
,
NULL
,
0
);
/* delay_ms is the least delay_ms among all instances */
...
...
@@ -35,6 +53,22 @@ static int run_all_state_machines(struct pp_globals *ppg)
delay_ms
=
delay_ms_j
;
}
/* BMCA must run at least once per announce interval 9.2.6.8 */
if
(
pp_gtimeout
(
ppg
,
PP_TO_BMC
))
{
/* Calculation of erbest, ebest, ... */
bmc_calculate_ebest
(
ppg
);
pp_gtimeout_reset
(
ppg
,
PP_TO_BMC
);
delay_ms
=
0
;
/* TODO: Check PLL state if needed/available */
}
else
{
/* check if the BMC timeout is the next to run */
int
delay_bmca
;
if
((
delay_bmca
=
pp_gnext_delay_1
(
ppg
,
PP_TO_BMC
))
<
delay_ms
)
delay_ms
=
delay_bmca
;
}
return
delay_ms
;
}
...
...
@@ -48,8 +82,6 @@ void unix_main_loop(struct pp_globals *ppg)
for
(
j
=
0
;
j
<
ppg
->
nlinks
;
j
++
)
{
ppi
=
INST
(
ppg
,
j
);
/* just tell that the links are up */
ppi
->
link_up
=
TRUE
;
/*
* The main loop here is based on select. While we are not
...
...
@@ -62,32 +94,14 @@ void unix_main_loop(struct pp_globals *ppg)
delay_ms
=
run_all_state_machines
(
ppg
);
while
(
1
)
{
int
i
;
/*
* If Ebest was changed in previous loop, run best
* master clock before checking for new packets, which
* would affect port state again
*/
if
(
ppg
->
ebest_updated
)
{
for
(
j
=
0
;
j
<
ppg
->
nlinks
;
j
++
)
{
int
new_state
;
struct
pp_instance
*
ppi
=
INST
(
ppg
,
j
);
new_state
=
bmc
(
ppi
);
if
(
new_state
!=
ppi
->
state
)
{
ppi
->
state
=
new_state
;
ppi
->
is_new_state
=
1
;
}
}
ppg
->
ebest_updated
=
0
;
}
int
packet_available
;
i
=
unix_net_ops
.
check_packet
(
ppg
,
delay_ms
);
packet_available
=
unix_net_ops
.
check_packet
(
ppg
,
delay_ms
);
if
(
i
<
0
)
if
(
packet_available
<
0
)
continue
;
if
(
i
==
0
)
{
if
(
packet_available
==
0
)
{
delay_ms
=
run_all_state_machines
(
ppg
);
continue
;
}
...
...
@@ -99,7 +113,7 @@ void unix_main_loop(struct pp_globals *ppg)
delay_ms
=
-
1
;
for
(
j
=
0
;
j
<
ppg
->
nlinks
;
j
++
)
{
int
tmp_d
;
int
tmp_d
,
i
;
ppi
=
INST
(
ppg
,
j
);
if
((
ppi
->
ch
[
PP_NP_GEN
].
pkt_present
)
||
...
...
arch-unix/unix-startup.c
View file @
5d9b4c65
/*
* Copyright (C) 2011 CERN (www.cern.ch)
* Copyright (C) 2011
-2022
CERN (www.cern.ch)
* Author: Alessandro Rubini
*
* Released to the public domain
...
...
@@ -23,16 +23,36 @@
#include <ppsi/ppsi.h>
#include "ppsi-unix.h"
char
*
format_hex
(
char
*
s
,
const
unsigned
char
*
mac
,
int
cnt
);
char
*
format_hex8
(
char
*
s
,
const
unsigned
char
*
mac
);
/* ppg and fields */
static
struct
pp_globals
ppg_static
;
static
defaultDS_t
defaultDS
;
static
currentDS_t
currentDS
;
static
parentDS_t
parentDS
;
static
timePropertiesDS_t
timePropertiesDS
;
static
struct
pp_servo
servo
;
extern
struct
pp_ext_hooks
pp_hooks
;
/**
* Enable/disable asymmetry correction
*/
static
void
enable_asymmetryCorrection
(
struct
pp_instance
*
ppi
,
Boolean
enable
)
{
if
((
ppi
->
asymmetryCorrectionPortDS
.
enable
=
enable
)
==
TRUE
)
{
/* Enabled: The delay asymmetry will be calculated */
ppi
->
asymmetryCorrectionPortDS
.
scaledDelayCoefficient
=
(
ppi
->
cfg
.
scaledDelayCoefficient
!=
0
)
?
ppi
->
cfg
.
scaledDelayCoefficient
:
(
RelativeDifference
)(
ppi
->
cfg
.
delayCoefficient
*
REL_DIFF_TWO_POW_FRACBITS
);
ppi
->
portDS
->
delayAsymCoeff
=
pp_servo_calculateDelayAsymCoefficient
(
ppi
->
asymmetryCorrectionPortDS
.
scaledDelayCoefficient
);
}
ppi
->
asymmetryCorrectionPortDS
.
constantAsymmetry
=
picos_to_interval
(
ppi
->
cfg
.
constantAsymmetry_ps
);
}
int
main
(
int
argc
,
char
**
argv
)
{
struct
pp_globals
*
ppg
;
...
...
@@ -45,12 +65,20 @@ int main(int argc, char **argv)
pp_printf
(
"PPSi. Commit %s, built on "
__DATE__
"
\n
"
,
PPSI_VERSION
);
/* So far allow more than one instance of PPSi running on the same
* machine.
TODO: to be considered to allow only one instance of PPSi to run
* at the same time.
* Potential problems my be in:
* shmem (not used in arch-unix)
* race of setting of time if more than one instance run as slave
*/
ppg
=
&
ppg_static
;
ppg
->
defaultDS
=
&
defaultDS
;
ppg
->
currentDS
=
&
currentDS
;
ppg
->
parentDS
=
&
parentDS
;
ppg
->
timePropertiesDS
=
&
timePropertiesDS
;
ppg
->
servo
=
&
servo
;
ppg
->
rt_opts
=
&
__pp_default_rt_opts
;
/* We are hosted, so we can allocate */
...
...
@@ -63,17 +91,17 @@ int main(int argc, char **argv)
exit
(
1
);
}
/*
Before the configuration is parsed, set default
s */
/*
Set default configuration value for all instance
s */
for
(
i
=
0
;
i
<
ppg
->
max_links
;
i
++
)
{
ppi
=
INST
(
ppg
,
i
);
ppi
->
proto
=
PP_DEFAULT_PROTO
;
ppi
->
role
=
PP_DEFAULT_ROLE
;
ppi
->
delayMechanism
=
MECH_E2E
;
memcpy
(
&
INST
(
ppg
,
i
)
->
cfg
,
&
__pp_default_instance_cfg
,
sizeof
(
__pp_default_instance_cfg
));
}
/* Set offset here, so config parsing can override it */
if
(
adjtimex
(
&
t
)
>=
0
)
timePropertiesDS
.
currentUtcOffset
=
t
.
tai
;
memset
(
&
t
,
0
,
sizeof
(
t
));
if
(
adjtimex
(
&
t
)
>=
0
)
{
ppg
->
timePropertiesDS
->
currentUtcOffset
=
(
Integer16
)
t
.
tai
;
}
if
(
pp_parse_cmdline
(
ppg
,
argc
,
argv
)
!=
0
)
return
-
1
;
...
...
@@ -81,6 +109,8 @@ int main(int argc, char **argv)
/* If no item has been parsed, provide a default file or string */
if
(
ppg
->
cfg
.
cfg_items
==
0
)
pp_config_file
(
ppg
,
0
,
PP_DEFAULT_CONFIGFILE
);
/* No config found, add default */
if
(
ppg
->
cfg
.
cfg_items
==
0
)
pp_config_string
(
ppg
,
strdup
(
"link 0; iface eth0; proto udp"
));
...
...
@@ -95,21 +125,113 @@ int main(int argc, char **argv)
ppi
->
iface_name
=
ppi
->
cfg
.
iface_name
;
ppi
->
port_name
=
ppi
->
cfg
.
port_name
;
ppi
->
delayMechanism
=
ppi
->
cfg
.
delayMechanism
;
ppi
->
ext_hooks
=
&
pp_hooks
;
ppi
->
portDS
=
calloc
(
1
,
sizeof
(
*
ppi
->
portDS
));
ppi
->
servo
=
calloc
(
1
,
sizeof
(
*
ppi
->
servo
));
ppi
->
ext_hooks
=
&
pp_hooks
;
ppi
->
ptp_support
=
TRUE
;
if
(
ppi
->
portDS
)
{
switch
(
ppi
->
cfg
.
profile
)
{
case
PPSI_PROFILE_WR
:
#if CONFIG_HAS_PROFILE_WR
ppi
->
protocol_extension
=
PPSI_EXT_WR
;
/* Add WR extension portDS */
if
(
!
(
ppi
->
portDS
->
ext_dsport
=
wrs_shm_alloc
(
ppsi_head
,
sizeof
(
struct
wr_dsport
))
)
)
{
goto
exit_out_of_memory
;
}
/* Allocate WR data extension */
if
(
!
(
ppi
->
ext_data
=
wrs_shm_alloc
(
ppsi_head
,
sizeof
(
struct
wr_data
))
)
)
{
goto
exit_out_of_memory
;
}
/* Set WR extension hooks */
ppi
->
ext_hooks
=
&
wr_ext_hooks
;
enable_asymmetryCorrection
(
ppi
,
TRUE
);
#else
fprintf
(
stderr
,
"ppsi: Profile WR not supported"
);
exit
(
1
);
#endif
break
;
case
PPSI_PROFILE_HA
:
#if CONFIG_HAS_PROFILE_HA
if
(
!
enable_l1Sync
(
ppi
,
TRUE
))
goto
exit_out_of_memory
;
/* Force mandatory attributes - Do not take care of the configuration */
L1E_DSPOR_BS
(
ppi
)
->
rxCoherentIsRequired
=
TRUE
;
L1E_DSPOR_BS
(
ppi
)
->
txCoherentIsRequired
=
TRUE
;
L1E_DSPOR_BS
(
ppi
)
->
congruentIsRequired
=
TRUE
;
L1E_DSPOR_BS
(
ppi
)
->
L1SyncEnabled
=
TRUE
;
L1E_DSPOR_BS
(
ppi
)
->
optParamsEnabled
=
FALSE
;
enable_asymmetryCorrection
(
ppi
,
TRUE
);
#else
fprintf
(
stderr
,
"ppsi: Profile HA not supported"
);
exit
(
1
);
#endif
break
;
case
PPSI_PROFILE_PTP
:
/* Do not take care of L1SYNC */
enable_asymmetryCorrection
(
ppi
,
ppi
->
cfg
.
asymmetryCorrectionEnable
);
ppi
->
protocol_extension
=
PPSI_EXT_NONE
;
break
;
case
PPSI_PROFILE_CUSTOM
:
#if CONFIG_HAS_PROFILE_CUSTOM
ppi
->
protocol_extension
=
PPSI_EXT_NONE
;
/* can be changed ...*/
#if CONFIG_HAS_EXT_L1SYNC
if
(
ppi
->
cfg
.
l1SyncEnabled
)
{
if
(
!
enable_l1Sync
(
ppi
,
TRUE
))
goto
exit_out_of_memory
;
/* Read L1SYNC parameters */
L1E_DSPOR_BS
(
ppi
)
->
rxCoherentIsRequired
=
ppi
->
cfg
.
l1SyncRxCoherencyIsRequired
;
L1E_DSPOR_BS
(
ppi
)
->
txCoherentIsRequired
=
ppi
->
cfg
.
l1SyncTxCoherencyIsRequired
;
L1E_DSPOR_BS
(
ppi
)
->
congruentIsRequired
=
ppi
->
cfg
.
l1SyncCongruencyIsRequired
;
L1E_DSPOR_BS
(
ppi
)
->
optParamsEnabled
=
ppi
->
cfg
.
l1SyncOptParamsEnabled
;
if
(
L1E_DSPOR_BS
(
ppi
)
->
optParamsEnabled
)
{
L1E_DSPOR_OP
(
ppi
)
->
timestampsCorrectedTx
=
ppi
->
cfg
.
l1SyncOptParamsTimestampsCorrectedTx
;
}
}
enable_asymmetryCorrection
(
ppi
,
ppi
->
cfg
.
asymmetryCorrectionEnable
);
#endif
#else
fprintf
(
stderr
,
"ppsi: Profile CUSTOM not supported"
);
exit
(
1
);
#endif
break
;
}
/* Parameters profile independent */
ppi
->
timestampCorrectionPortDS
.
egressLatency
=
picos_to_interval
(
ppi
->
cfg
.
egressLatency_ps
);
ppi
->
timestampCorrectionPortDS
.
ingressLatency
=
picos_to_interval
(
ppi
->
cfg
.
ingressLatency_ps
);
ppi
->
timestampCorrectionPortDS
.
messageTimestampPointLatency
=
0
;
ppi
->
portDS
->
masterOnly
=
ppi
->
cfg
.
masterOnly
;
/* can be overridden in pp_init_globals() */
}
else
{
goto
exit_out_of_memory
;
}
/* The following default names depend on TIME= at build time */
ppi
->
n_ops
=
&
DEFAULT_NET_OPS
;
ppi
->
t_ops
=
&
DEFAULT_TIME_OPS
;
ppi
->
portDS
=
calloc
(
1
,
sizeof
(
*
ppi
->
portDS
));
ppi
->
__tx_buffer
=
malloc
(
PP_MAX_FRAME_LENGTH
);
ppi
->
__rx_buffer
=
malloc
(
PP_MAX_FRAME_LENGTH
);
if
(
!
ppi
->
portDS
||
!
ppi
->
__tx_buffer
||
!
ppi
->
__rx_buffer
)
{
fprintf
(
stderr
,
"ppsi: out of memory
\n
"
);
exit
(
1
);
goto
exit_out_of_memory
;
}
}
pp_init_globals
(
ppg
,
&
__pp_default_rt_opts
);
seed
=
time
(
NULL
);
...
...
@@ -119,4 +241,32 @@ int main(int argc, char **argv)
unix_main_loop
(
ppg
);
return
0
;
/* never reached */
exit_out_of_memory:
fprintf
(
stderr
,
"ppsi: out of memory
\n
"
);
exit
(
1
);
}
char
*
format_hex
(
char
*
s
,
const
unsigned
char
*
mac
,
int
cnt
)
{
int
i
;
*
s
=
'\0'
;
for
(
i
=
0
;
i
<
cnt
;
i
++
)
{
pp_sprintf
(
s
,
"%s%02x:"
,
s
,
mac
[
i
]);
}
/* remove last colon */
s
[
cnt
*
3
-
1
]
=
'\0'
;
/* cnt * strlen("FF:") - 1 */
return
s
;
}
char
*
format_hex8
(
char
*
s
,
const
unsigned
char
*
mac
)
{
return
format_hex
(
s
,
mac
,
8
);
}
char
*
format_mac
(
char
*
s
,
const
unsigned
char
*
mac
)
{
format_hex
(
s
,
mac
,
6
);
return
s
;
}
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