Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • project/ppsi
1 result
Show changes
Commits on Source (10)
......@@ -60,8 +60,16 @@ static inline wrs_arch_data_t *WRS_ARCH_G(struct pp_globals *ppg)
}
extern void wrs_main_loop(struct pp_globals *ppg);
extern void wrs_init_ipcserver(struct minipc_ch *ppsi_ch);
void set_param_global_prio1(struct pp_globals *ppg, int prio1);
void set_param_global_prio2(struct pp_globals *ppg, int prio2);
void set_param_inst_logMinDelayReqInterval(struct pp_instance *ppi,
int logMinDelayReqInterval);
void set_param_inst_logMinPdelayReqInterval(struct pp_instance *ppi,
int logMinPdelayReqInterval);
void set_param_inst_logSyncInterval(struct pp_instance *ppi,
int logSyncInterval);
extern void wrs_init_ipcserver(struct pp_globals *ppg, struct minipc_ch *ppsi_ch);
/* wrs-calibration.c */
int wrs_read_calibration_data(struct pp_instance *ppi, TimeInterval *scaledBitSlide,
......
......@@ -4,8 +4,24 @@
#include <stdio.h>
#include <stdlib.h>
#define PPSIEXP_COMMAND_WR_TRACKING 1
#define PPSIEXP_COMMAND_L1SYNC_TRACKING 2
#define PPSIEXP_COMMAND_WR_TRACKING 1
#define PPSIEXP_COMMAND_L1SYNC_TRACKING 2
/* Return values */
#define PPSIEXP_RET_OK 0
#define PPSIEXP_RET_ERROR_CMD 1
#define PPSIEXP_RET_ERROR_VAL 2
#define PPSIEXP_RET_ERROR_INSTANCE 3
/* Commands for ppsiexp_update_param_cmd */
#define PPSIEXP_PARAM_PRIORITY1_CMD 1
#define PPSIEXP_PARAM_PRIORITY2_CMD 2
/* Commands for ppsiexp_update_param_instance_cmd */
#define PPSIEXP_PARAM_INST_DELAY_REQ_INT_CMD 1
#define PPSIEXP_PARAM_INST_SYNC_INT_CMD 2
#define PPSI_INSTANCE_USE_PORT 0x80000000
/* Export structures, shared by server and client for argument matching */
#ifdef PPSI_EXPORT_STRUCTURES
......@@ -20,6 +36,27 @@ struct minipc_pd __rpcdef_cmd = {
},
};
#endif /* PTP_EXPORT_STRUCTURES */
struct minipc_pd ppsiexp_update_param_cmd = {
.name = "params",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* Command/parameter */
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* New value */
MINIPC_ARG_END,
},
};
struct minipc_pd ppsiexp_update_param_instance_cmd = {
.name = "instance param",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* Command/parameter */
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* Instance */
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* New value */
MINIPC_ARG_END,
},
};
#endif /* PPSI_EXPORT_STRUCTURES */
#endif /* __PPSI_EXPORTS_H */
/*
* Copyright (C) 2013 CERN (www.cern.ch)
* Copyright (C) 2013-2023 CERN (www.cern.ch)
* Author: Aurelio Colosimo
* Author: Adam Wujek
*
* Released to the public domain
* Released according to the GNU LGPL, version 2.1 or any later version.
*/
#include <ppsi/ppsi.h>
......@@ -11,6 +12,10 @@
#define PPSI_EXPORT_STRUCTURES
#include <ppsi_exports.h>
static struct pp_globals *ppg_local;
/* Execute command coming ipc */
static int wrsipc_cmd(int cmd, int value)
{
......@@ -39,10 +44,170 @@ static int export_cmd(const struct minipc_pd *pd,
return 0;
}
static int update_param_cmd(const struct minipc_pd *pd, uint32_t *args,
void *ret)
{
int rval = PPSIEXP_RET_OK;
int param_type = args[0];
int param_val = args[1];
switch (param_type) {
case PPSIEXP_PARAM_PRIORITY1_CMD:
pp_diag(NULL, config, 2,
"%s: cmd %d (PPSIEXP_PARAM_PRIORITY1_CMD) value %d\n",
__func__, param_type, param_val);
if (!in_range(param_val, PP_MIN_PRIORITY1, PP_MAX_PRIORITY1)) {
pp_diag(NULL, config, 1,
"Param update Error: value of "
"priority1 (%d) not in range! "
"cmd %d (PPSIEXP_PARAM_PRIORITY1_CMD)\n",
param_val, param_type);
rval = PPSIEXP_RET_ERROR_VAL;
break;
}
set_param_global_prio1(ppg_local, param_val);
break;
case PPSIEXP_PARAM_PRIORITY2_CMD:
pp_diag(NULL, config, 2,
"%s: cmd %d (PPSIEXP_PARAM_PRIORITY2_CMD) value %d\n",
__func__, param_type, param_val);
if (!in_range(param_val, PP_MIN_PRIORITY2, PP_MAX_PRIORITY2)) {
pp_diag(NULL, config, 1,
"Param update Error: value of "
"priority2 (%d) not in range! "
"cmd %d (PPSIEXP_PARAM_PRIORITY2_CMD)\n",
param_val, param_type);
rval = PPSIEXP_RET_ERROR_VAL;
break;
}
set_param_global_prio2(ppg_local, param_val);
break;
default:
pp_diag(NULL, config, 1,
"Param update Error: not supported param cmd %d value "
"%d\n",
param_type, param_val);
rval = PPSIEXP_RET_ERROR_CMD;
break;
}
*(int *)ret = rval;
return 0;
}
static int update_param_instance(struct pp_instance *ppi, int ppi_i,
int param_type, int param_val)
{
int rval = PPSIEXP_RET_OK;
switch (param_type) {
case PPSIEXP_PARAM_INST_DELAY_REQ_INT_CMD:
pp_diag(ppi, config, 2,
"%s: cmd %d (PPSIEXP_PARAM_INST_DELAY_REQ_INT_CMD) "
"instance %d, port %s, value %d\n", __func__,
param_type, ppi_i, ppi->iface_name, param_val);
if (!check_range_inst_logMinDelayReqInterval(ppi->cfg.profile,
param_val)) {
pp_diag(ppi, config, 1,
"Param update Error: value of "
"logMinDelayReqInterval (%d) not in range! "
"cmd %d (PPSIEXP_PARAM_INST_DELAY_REQ_INT_CMD) "
"instance %d, port %s\n",
param_val, param_type, ppi_i, ppi->iface_name);
rval = PPSIEXP_RET_ERROR_VAL;
break;
}
set_param_inst_logMinDelayReqInterval(ppi, param_val);
break;
case PPSIEXP_PARAM_INST_SYNC_INT_CMD:
pp_diag(ppi, config, 2,
"%s: cmd %d (PPSIEXP_PARAM_INST_SYNC_INT_CMD) "
"instance %d, port %s, value %d\n", __func__,
param_type, ppi_i, ppi->iface_name, param_val);
if (!check_range_inst_logSyncInterval(ppi->cfg.profile,
param_val)) {
pp_diag(ppi, config, 1,
"Param update Error: value of "
"logSyncInterval (%d) not in range! "
"cmd %d (PPSIEXP_PARAM_INST_SYNC_INT_CMD) "
"instance %d, port %s\n",
param_val, param_type, ppi_i, ppi->iface_name);
rval = PPSIEXP_RET_ERROR_VAL;
break;
}
set_param_inst_logSyncInterval(ppi, param_val);
break;
default:
pp_diag(ppi, config, 1,
"Param update Error: not supported param instance cmd "
"%d value %d\n",
param_type, param_val);
rval = PPSIEXP_RET_ERROR_CMD;
break;
}
return rval;
}
static int update_param_instance_cmd(const struct minipc_pd *pd,
uint32_t *args, void *ret)
{
int i;
int rval = PPSIEXP_RET_OK;
int rval_tmp = -1;
int param_type = args[0];
int param_instance = args[1];
int param_val = args[2];
struct pp_instance *ppi;
char iface_name[16];
int all_ports = 0;
if (param_instance & PPSI_INSTANCE_USE_PORT) {
all_ports = (param_instance == PPSI_INSTANCE_USE_PORT);
/* Execute command for all instances in a given interface */
snprintf(iface_name, 16, "wri%d",
param_instance & ~PPSI_INSTANCE_USE_PORT);
for (i = 0; i < get_numberPorts(GDSDEF(ppg_local)); i++) {
ppi = INST(ppg_local, i);
if (!all_ports && strcmp(iface_name, ppi->iface_name))
continue;
rval_tmp = update_param_instance(ppi, i, param_type,
param_val);
if (rval_tmp != PPSIEXP_RET_OK)
rval = rval_tmp;
}
/* If rval_tmp == -1, no instance found on requested port */
if (rval_tmp == -1)
rval = PPSIEXP_RET_ERROR_INSTANCE;
} else {
ppi = INST(ppg_local, param_instance);
rval = update_param_instance(ppi, param_instance, param_type,
param_val);
}
*(int *)ret = rval;
return 0;
}
/* To be called at startup, right after the creation of server channel */
void wrs_init_ipcserver(struct minipc_ch *ppsi_ch)
void wrs_init_ipcserver(struct pp_globals *ppg, struct minipc_ch *ppsi_ch)
{
ppg_local = ppg;
__rpcdef_cmd.f = export_cmd;
ppsiexp_update_param_cmd.f = update_param_cmd;
ppsiexp_update_param_instance_cmd.f = update_param_instance_cmd;
minipc_export(ppsi_ch, &__rpcdef_cmd);
minipc_export(ppsi_ch, &ppsiexp_update_param_cmd);
minipc_export(ppsi_ch, &ppsiexp_update_param_instance_cmd);
}
......@@ -100,6 +100,61 @@ void enable_asymmetryCorrection(struct pp_instance *ppi, Boolean enable ) {
ppi->asymmetryCorrectionPortDS.constantAsymmetry=picos_to_interval(ppi->cfg.constantAsymmetry_ps);
}
/* Functions to set global parameters */
void set_param_global_prio1(struct pp_globals *ppg, int prio1)
{
ppg->rt_opts->priority1 = prio1;
bmc_apply_configured_device_attributes(ppg);
}
void set_param_global_prio2(struct pp_globals *ppg, int prio2)
{
ppg->rt_opts->priority2 = prio2;
bmc_apply_configured_device_attributes(ppg);
}
/* Functions to set parameters specific to instance */
void set_param_inst_logMinDelayReqInterval(struct pp_instance *ppi,
int logMinDelayReqInterval)
{
int millisec;
DSPOR(ppi)->logMinDelayReqInterval = logMinDelayReqInterval;
ppi->cfg.min_delay_req_interval = logMinDelayReqInterval;
millisec = pp_timeout_log_to_ms(logMinDelayReqInterval);
if (is_delayMechanismE2E(ppi))
pp_timeout_set_rename(ppi, PP_TO_REQUEST, millisec);
}
void set_param_inst_logMinPdelayReqInterval(struct pp_instance *ppi,
int logMinPdelayReqInterval)
{
int millisec;
DSPOR(ppi)->logMinPdelayReqInterval = logMinPdelayReqInterval;
ppi->cfg.min_pdelay_req_interval = logMinPdelayReqInterval;
millisec = pp_timeout_log_to_ms(logMinPdelayReqInterval);
if (is_delayMechanismP2P(ppi))
pp_timeout_set_rename(ppi, PP_TO_REQUEST, millisec);
}
void set_param_inst_logSyncInterval(struct pp_instance *ppi,
int logSyncInterval)
{
int millisec;
DSPOR(ppi)->logSyncInterval = logSyncInterval;
ppi->cfg.sync_interval = logSyncInterval;
millisec = pp_timeout_log_to_ms(logSyncInterval);
pp_timeout_set_rename(ppi, PP_TO_SYNC_SEND, millisec);
}
static char *strCodeOpt="CODEOPT=("
#if CONFIG_HAS_CODEOPT_EPC_ENABLED
" EPC"
......@@ -128,6 +183,10 @@ int main(int argc, char **argv)
pp_printf("PPSi. Commit %s, built on " __DATE__ ", %s\n",
PPSI_VERSION,
strCodeOpt);
/* Check for -h or --help in params list */
pp_parse_cmdline_early(argc, argv);
/* check if there is another instance of PPSi already running */
ppsi_head = wrs_shm_get(wrs_shm_ptp, "", WRS_SHM_READ);
if (!ppsi_head) {
......@@ -208,7 +267,6 @@ int main(int argc, char **argv)
pp_printf("ppsi: could not create minipc server");
exit(1);
}
wrs_init_ipcserver(ppsi_ch);
ppsi_head = wrs_shm_get(wrs_shm_ptp, "ppsi",
WRS_SHM_WRITE | WRS_SHM_LOCKED);
......@@ -449,6 +507,8 @@ int main(int argc, char **argv)
seed = (unsigned long) atoi(getenv("PPSI_DROP_SEED"));
ppsi_drop_init(ppg, seed);
wrs_init_ipcserver(ppg, ppsi_ch);
/* release lock from wrs_shm_get */
wrs_shm_write(ppsi_head, WRS_SHM_WRITE_END);
......
......@@ -24,6 +24,7 @@ CONFIG_E2E=y
# CONFIG_P2P is not set
# CONFIG_E2E_ONLY is not set
CONFIG_HAS_P2P=1
# CONFIG_PTP_OPT_OVERWRITE_ATTRIBUTES is not set
#
# Enabled profiles
......@@ -39,15 +40,15 @@ CONFIG_HAS_PROFILE_PTP=1
CONFIG_HAS_PROFILE_HA=0
CONFIG_HAS_PROFILE_WR=1
CONFIG_HAS_PROFILE_CUSTOM=0
CONFIG_PPSI_VLAN=y
CONFIG_ARCH_SUPPORT_MULTIPLE_VLAN=y
CONFIG_VLAN_ARRAY_SIZE=32
CONFIG_ARCH_SUPPORT_VLAN=y
#
# VLAN
#
CONFIG_SUPPORT_VLAN=y
CONFIG_SUPPORT_MULTIPLE_VLAN=y
CONFIG_PPSI_VLAN=y
CONFIG_MAX_VLANS_PER_PORT=32
CONFIG_VLAN_ARRAY_SIZE=32
# CONFIG_PPSI_ASSERT is not set
CONFIG_NR_FOREIGN_RECORDS=5
# CONFIG_SINGLE_FMASTER is not set
......@@ -62,6 +63,9 @@ CONFIG_SINGLE_INSTANCE_PER_PORT=y
# CONFIG_SINGLE_INSTANCE is not set
# CONFIG_SINGLE_PORT is not set
CONFIG_CODEOPT_SINGLE_INSTANCE_PER_PORT=y
# CONFIG_CODEOPT_EXT_PORT_CONF_FORCE_DISABLED is not set
# CONFIG_CODEOPT_SO_FORCE_DISABLED is not set
# CONFIG_CODEOPT_MO_FORCE_DISABLED is not set
CONFIG_CODEOPT_EPC_SO_DISABLED=y
# CONFIG_CODEOPT_EPC_ENABLED is not set
CONFIG_OPTIMIZATION_SPEED=y
......@@ -75,6 +79,10 @@ CONFIG_HAS_WRPC_FAULTS=0
CONFIG_HAS_CODEOPT_SINGLE_FMASTER=0
CONFIG_HAS_CODEOPT_SINGLE_PORT=0
CONFIG_HAS_CODEOPT_SINGLE_INSTANCE_PER_PORT=1
CONFIG_HAS_CODEOPT_CODEOPT_WRPC_SIZE=0
CONFIG_HAS_CODEOPT_EXT_PORT_CONF_FORCE_DISABLED=0
CONFIG_HAS_CODEOPT_SO_FORCE_DISABLED=0
CONFIG_HAS_CODEOPT_MO_FORCE_DISABLED=0
CONFIG_HAS_CODEOPT_EPC_ENABLED=0
CONFIG_HAS_CODEOPT_SO_ENABLED=0
CONFIG_ARCH_IS_WRS=1
......
......@@ -193,3 +193,10 @@ extern int pp_config_string(struct pp_globals *ppg, char *s);
extern int pp_config_file(struct pp_globals *ppg, int force, char *fname);
extern int f_simple_int(struct pp_argline *l, int lineno,
struct pp_globals *ppg, union pp_cfg_arg *arg);
int in_range(int val, int min, int max);
int check_range_inst_logMinDelayReqInterval(int profile,
int logMinDelayReqInterval);
int check_range_inst_logMinPdelayReqInterval(int profile,
int logMinPdelayReqInterval);
int check_range_inst_logSyncInterval(int profile, int logSyncInterval);
......@@ -51,14 +51,26 @@
#define PP_MIN_MIN_DELAY_REQ_INTERVAL 0
#define PP_MAX_MIN_DELAY_REQ_INTERVAL 5
#define PP_DEFAULT_MIN_DELAY_REQ_INTERVAL_CUSTOM PP_DEFAULT_MIN_DELAY_REQ_INTERVAL
#define PP_MIN_MIN_DELAY_REQ_INTERVAL_CUSTOM -6
#define PP_MAX_MIN_DELAY_REQ_INTERVAL_CUSTOM PP_MAX_MIN_DELAY_REQ_INTERVAL
#define PP_DEFAULT_MIN_PDELAY_REQ_INTERVAL 0
#define PP_MIN_MIN_PDELAY_REQ_INTERVAL 0
#define PP_MAX_MIN_PDELAY_REQ_INTERVAL 5
#define PP_DEFAULT_MIN_PDELAY_REQ_INTERVAL_CUSTOM PP_DEFAULT_MIN_PDELAY_REQ_INTERVAL
#define PP_MIN_MIN_PDELAY_REQ_INTERVAL_CUSTOM -6
#define PP_MAX_MIN_PDELAY_REQ_INTERVAL_CUSTOM PP_MAX_MIN_PDELAY_REQ_INTERVAL
#define PP_DEFAULT_SYNC_INTERVAL 0 /* -7 in 802.1AS */
#define PP_MIN_SYNC_INTERVAL -1
#define PP_MAX_SYNC_INTERVAL 1
#define PP_DEFAULT_SYNC_INTERVAL_CUSTOM PP_DEFAULT_SYNC_INTERVAL
#define PP_MIN_SYNC_INTERVAL_CUSTOM -6
#define PP_MAX_SYNC_INTERVAL_CUSTOM PP_MAX_SYNC_INTERVAL
/* Min/max values for delay coefficient */
#define PP_MIN_DELAY_COEFFICIENT_AS_RELDIFF (((int64_t)-1)<<REL_DIFF_FRACBITS)
#define PP_MAX_DELAY_COEFFICIENT_AS_RELDIFF (((int64_t) 1)<<REL_DIFF_FRACBITS)
......
......@@ -305,6 +305,7 @@ extern const struct pp_time_operations unix_time_ops;
extern int pp_init_globals(struct pp_globals *ppg, struct pp_runtime_opts *opts);
extern int pp_close_globals(struct pp_globals *ppg);
extern void pp_parse_cmdline_early(int argc, char **argv);
extern int pp_parse_cmdline(struct pp_globals *ppg, int argc, char **argv);
......
......@@ -51,6 +51,19 @@ static void cmd_line_print_help(void)
}
}
/* Check for -h or --help in params list */
void pp_parse_cmdline_early(int argc, char **argv)
{
int i;
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
cmd_line_print_help();
exit(1);
}
}
}
int pp_parse_cmdline(struct pp_globals *ppg, int argc, char **argv)
{
int i, err = 0;
......@@ -72,22 +85,36 @@ int pp_parse_cmdline(struct pp_globals *ppg, int argc, char **argv)
switch (a[1]) {
case 'd':
/* Use the general flags, per-instance TBD */
a = argv[++i];
if (!(a = argv[++i])) {
err = 1;
break;
}
pp_global_d_flags = pp_diag_parse(a);
break;
case 'C':
if (pp_config_string(ppg, argv[++i]) != 0)
if (!(a = argv[++i])) {
err = 1;
break;
}
if (pp_config_string(ppg, a) != 0)
return -1;
break;
case 'f':
if (pp_config_file(ppg, 1, argv[++i]) != 0)
if (!(a = argv[++i])) {
err = 1;
break;
}
if (pp_config_file(ppg, 1, a) != 0)
return -1;
break;
case 't':
GOPTS(ppg)->flags |= PP_FLAG_NO_ADJUST;
break;
case 'w':
a = argv[++i];
if (!(a = argv[++i])) {
err = 1;
break;
}
GOPTS(ppg)->s = atoi(a);
break;
case 'h':
......@@ -96,6 +123,11 @@ int pp_parse_cmdline(struct pp_globals *ppg, int argc, char **argv)
case 'G':
/* gptp_mode not supported: fall through */
default:
err = 1;
break;
}
if (err) {
pp_printf("Wrong parameter!\n\n");
cmd_line_print_help();
return -1;
}
......
......@@ -750,3 +750,49 @@ int pp_config_string(struct pp_globals *ppg, char *s)
return pp_parse_conf(ppg, s, strlen(s));
}
int in_range(int val, int min, int max)
{
if (val < min || val > max)
return 0;
return 1;
}
/* Functions to check ranges of parameters specific to instance */
int check_range_inst_logMinDelayReqInterval(int profile,
int logMinDelayReqInterval)
{
if (profile == PPSI_PROFILE_CUSTOM)
return in_range(logMinDelayReqInterval,
PP_MIN_MIN_DELAY_REQ_INTERVAL_CUSTOM,
PP_MAX_MIN_DELAY_REQ_INTERVAL_CUSTOM);
return in_range(logMinDelayReqInterval,
PP_MIN_MIN_DELAY_REQ_INTERVAL,
PP_MAX_MIN_DELAY_REQ_INTERVAL);
}
int check_range_inst_logMinPdelayReqInterval(int profile,
int logMinPdelayReqInterval)
{
if (profile == PPSI_PROFILE_CUSTOM)
return in_range(logMinPdelayReqInterval,
PP_MIN_MIN_PDELAY_REQ_INTERVAL_CUSTOM,
PP_MAX_MIN_PDELAY_REQ_INTERVAL_CUSTOM);
return in_range(logMinPdelayReqInterval,
PP_MIN_MIN_PDELAY_REQ_INTERVAL,
PP_MAX_MIN_PDELAY_REQ_INTERVAL);
}
int check_range_inst_logSyncInterval(int profile, int logSyncInterval)
{
if (profile == PPSI_PROFILE_CUSTOM)
return in_range(logSyncInterval,
PP_MIN_SYNC_INTERVAL_CUSTOM,
PP_MAX_SYNC_INTERVAL_CUSTOM);
return in_range(logSyncInterval,
PP_MIN_SYNC_INTERVAL,
PP_MAX_SYNC_INTERVAL);
}
ptpdump
adjrate
adjtime
jmptime
chktime
adjrate
pps-out
jmptime
monotonicClock
ppsi_conf
pps-out
ptpdump
......@@ -10,9 +10,18 @@ OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
include ../.config
GIT_VER = $(shell git describe --always --dirty)
GIT_USR = $(shell git config --get user.name)
CFLAGS = -Wall -ggdb -I../include -I../arch-$(CONFIG_ARCH)/include
PROGS = ptpdump adjtime jmptime chktime adjrate monotonicClock
PROGS = \
adjrate \
adjtime \
chktime \
monotonicClock \
ppsi_conf \
ptpdump \
LDFLAGS += -lrt
all: $(PROGS)
......@@ -31,6 +40,14 @@ dump-funcs.o: ../lib/dump-funcs.c
ptpdump: dump-main.o dump-funcs.o
$(CC) $(LDFLAGS) dump-main.o dump-funcs.o -o $@
ppsi_conf: LDFLAGS+=-lminipc
ppsi_conf: CFLAGS+=\
-I../arch-wrs/mini-rpc \
-L../arch-wrs/mini-rpc \
-D__GIT_USR__="\"${GIT_USR}\"" \
-D__GIT_VER__="\"${GIT_VER}\"" \
clean:
rm -f $(PROGS) *.o *~
/*
* Copyright (C) 2022 CERN (www.cern.ch)
* Author: Adam Wujek
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>
#include <ppsi/ppsi.h>
#include <minipc.h>
// #include <ppsi-wrs.h>
#define PPSI_EXPORT_STRUCTURES
#include "ppsi_exports.h"
#define MINIPC_TIMEOUT 5000
static int verbose = 0;
static struct minipc_ch *ptp_ch;
enum input_arg {
arg_help = 'Z' + 1, /* avoid conflicts with short options */
arg_delay_req_interval,
arg_instance,
arg_port,
arg_prio1,
arg_prio2,
arg_sync_interval,
arg_tracking,
arg_verbose,
};
static struct option long_opts[] = {
{"help", no_argument, NULL, arg_help},
{"delay-req-interval", required_argument, NULL, arg_delay_req_interval},
{"instance", required_argument, NULL, arg_instance},
{"ppi", required_argument, NULL, arg_instance},
{"port", required_argument, NULL, arg_port},
{"prio1", required_argument, NULL, arg_prio1},
{"priority1", required_argument, NULL, arg_prio1},
{"prio2", required_argument, NULL, arg_prio2},
{"priority2", required_argument, NULL, arg_prio2},
{"sync-interval", required_argument, NULL, arg_sync_interval},
{"tracking", required_argument, NULL, arg_tracking},
{"verbose", optional_argument, NULL, arg_verbose},
{NULL, 0, NULL, 0}
};
void help(char *prgname)
{
fprintf(stderr, "%s: Use: %s [-v] [-h] [option]\n",
prgname, prgname);
fprintf(stderr,
"The program has the following options:\n"
" -h|--help - print help\n"
" -v|--verbose - verbose output\n"
"Global parameters:\n"
" --prio1=<num>\n"
" --priority1=<num> - set priority 1 to <num>\n"
" --prio2=<num>\n"
" --priority2=<num> - set priority 2 to <num>\n"
" --tracking=<on|off|enable|disable|1|0>\n"
" - enable/disable tracking in servo\n"
"\n"
"Parameters specific for PPSi instance:\n"
" --instance=<num|all>\n"
" --ppi=<num|all> - Select PPSi instance <num> or all instances\n"
" --port=<num|all> - Select all instances on a defined port <num> or all\n"
" instances\n"
" --delay-req-interval=<num>\n"
" - sets logarithm to the base 2 of the mean interval of delay\n"
" request message transmission; used when a port is in Slave state\n"
" --sync-interval=<num>\n"
" - sets logarithm to the base 2 of the mean interval of sync\n"
" message transmission; used when a port is in Master state\n"
"\n\n"
"Version: " __GIT_VER__ " compiled by " __GIT_USR__ " on " __DATE__ ", " __TIME__ "\n"
);
exit(1);
}
void ppsi_connect_minipc(void)
{
if (ptp_ch) {
/* close minipc, if connected before */
minipc_close(ptp_ch);
}
ptp_ch = minipc_client_create("ptpd", 0);
if (!ptp_ch) {
fprintf(stderr, "Can't establish WRIPC connection to the PTP "
"daemon!\n");
exit(1);
}
}
void init_shm(void)
{
ppsi_connect_minipc();
}
static void check_instance(int instance)
{
if (instance == -1) {
fprintf(stderr, "Instance not defined! Please define instance."
"Exiting...\n");
exit (1);
}
}
static void enable_disable_tracking(int onoff) {
int rval;
printf("%s: onoff %d\n", __func__, onoff);
minipc_call(ptp_ch, MINIPC_TIMEOUT, &__rpcdef_cmd, &rval, 1, onoff);
}
static int ppsi_set_param(int param, int val) {
int rval = 0;
printf("%s: set param %d val %d\n", __func__, param, val);
minipc_call(ptp_ch, MINIPC_TIMEOUT, &ppsiexp_update_param_cmd, &rval,
param, val);
return rval;
}
static int ppsi_set_param_instance(int param, int instance, int val)
{
int rval = 0;
printf("%s: set param (%d) for %s %d, val %d\n",
__func__, param,
instance & PPSI_INSTANCE_USE_PORT ? "port" : "instance",
instance & ~PPSI_INSTANCE_USE_PORT, val);
minipc_call(ptp_ch, MINIPC_TIMEOUT, &ppsiexp_update_param_instance_cmd, &rval,
param, instance, val);
return rval;
}
int main(int argc, char *argv[])
{
int opt;
int tmp;
int ret;
int ppsi_instance = -1;
int ppsi_port = -1;
/* If no params print help */
if (argc == 1)
help(argv[0]);
while ((opt = getopt_long(argc, argv, "vh", long_opts, NULL)) != -1) {
if (opt == 'h' || opt == arg_help )
help(argv[0]);
if (opt == '?') {
/* Unrecognized option, exit */
exit(1);
}
if (opt == 'v') {
verbose = 1;
printf("Enable verbose mode\n");
}
if (opt == arg_verbose) {
if (!strcmp(optarg, "off") || !strcmp(optarg, "0")) {
verbose = 0;
printf("Enable verbose mode\n");
} else {
verbose = 1;
printf("Disable verbose mode\n");
}
}
}
init_shm();
/* Reset position of argument for getopt_long */
optind = 0;
while ((opt = getopt_long(argc, argv, "vh", long_opts, NULL)) != -1) {
switch (opt) {
case arg_delay_req_interval:
/* Check if an instance is set. If not exit. */
check_instance(ppsi_instance);
tmp = atoi(optarg);
if (verbose)
printf("Setting delay request interval for "
"%s %d to %d\n",
ppsi_port == -1 ? "instance" : "port",
ppsi_instance & ~PPSI_INSTANCE_USE_PORT,
tmp);
ret = ppsi_set_param_instance(
PPSIEXP_PARAM_INST_DELAY_REQ_INT_CMD,
ppsi_instance,
tmp);
if (ret) {
fprintf(stderr, "Error setting delay request "
"interval for %s %d to %d, ret %d\n",
ppsi_port == -1 ? "instance" : "port",
ppsi_instance & ~PPSI_INSTANCE_USE_PORT,
tmp, ret);
exit (1);
}
break;
case arg_instance:
ppsi_instance = atoi(optarg);
if (ppsi_instance == 0 && strcmp("0", optarg)
&& strcmp("all", optarg)) {
fprintf(stderr, "Wrong instance value: %s\n",
optarg);
exit (1);
}
if (!strcmp("all", optarg)) {
ppsi_port = 0;
ppsi_instance = PPSI_INSTANCE_USE_PORT;
} else {
ppsi_port = -1;
}
if (verbose)
printf("Setting instance to %d%s\n",
ppsi_instance & ~PPSI_INSTANCE_USE_PORT,
ppsi_instance == PPSI_INSTANCE_USE_PORT
? " (all)" : ""
);
break;
case arg_port:
ppsi_instance = atoi(optarg);
if (ppsi_instance == 0 && strcmp("all", optarg)) {
fprintf(stderr, "Wrong port value: %s\n",
optarg);
exit (1);
}
ppsi_port = ppsi_instance;
ppsi_instance |= PPSI_INSTANCE_USE_PORT;
if (verbose)
printf("Setting port to %d%s\n",
ppsi_port,
ppsi_instance == PPSI_INSTANCE_USE_PORT
? " (all)" : ""
);
break;
case arg_prio1:
tmp = atoi(optarg);
if (verbose)
printf("Setting priority1 to %d\n", tmp);
ret = ppsi_set_param(PPSIEXP_PARAM_PRIORITY1_CMD, tmp);
if (ret) {
fprintf(stderr, "Error setting priority1 to "
"%d\n", tmp);
exit (1);
}
break;
case arg_prio2:
tmp = atoi(optarg);
if (verbose)
printf("Setting priority2 to %d\n", tmp);
ret = ppsi_set_param(PPSIEXP_PARAM_PRIORITY2_CMD, tmp);
if (ret) {
fprintf(stderr, "Error setting priority2 to "
"%d\n", tmp);
exit (1);
}
break;
case arg_sync_interval:
/* Check if an instance is set. If not exit. */
check_instance(ppsi_instance);
tmp = atoi(optarg);
if (verbose)
printf("Setting sync interval for %s %d"
"to %d\n",
ppsi_port == -1 ? "instance" : "port",
ppsi_instance & ~PPSI_INSTANCE_USE_PORT,
tmp);
ret = ppsi_set_param_instance(
PPSIEXP_PARAM_INST_SYNC_INT_CMD,
ppsi_instance,
tmp);
if (ret) {
fprintf(stderr, "Error setting sync interval "
"for %s %d to %d, ret %d\n",
ppsi_port == -1 ? "instance" : "port",
ppsi_instance & ~PPSI_INSTANCE_USE_PORT,
tmp, ret);
exit (1);
}
break;
case arg_tracking:
{
int tracking;
if (!strcmp(optarg, "on")
|| !strcmp(optarg, "enable")
|| !strcmp(optarg, "1")
) {
tracking = 1;
} else if (!strcmp(optarg, "off")
|| !strcmp(optarg, "disable")
|| !strcmp(optarg, "0")
) {
tracking = 0;
} else {
fprintf(stderr, "Unknown value (%s) for"
" tracking\n", optarg);
exit (1);
}
if (verbose)
printf("%s tracking\n",
tracking ? "Enable" : "Disable");
enable_disable_tracking(tracking);
break;
}
default:
break;
}
}
return 0;
}