Commit a86255d3 authored by Alessandro Rubini's avatar Alessandro Rubini

Merge branch 'profiling'

This branch introduces the "ps" command, based on a restructuring of
how main() calls the various activities.
parents c3c9d67a b15f0668
......@@ -758,6 +758,12 @@ of the tools used to build and run it, you can write to our mailing list
@sc{wrpc}. It is an optional command, enabled at build time by
@t{CONFIG_CMD_CONFIG}
@item @code{ps} @tab prints the list of running tasks (processes) in the CPU.
For each task you get the number of iterations and the CPU time consumed
since boot or last reset of values
@item @code{ps reset} @tab zeroes the profiling information reported by
the @code{ps} command
@item @code{verbose <digits>} @tab sets PPSi verbosity. See the PPSi manual
about the meaning of the digits (hint: @t{verbose 1111} is a good first bet to
see how the @sc{ptp} system is working)
......
......@@ -18,10 +18,11 @@
#define PTPD_SOCK_UDP 0 /* wrong name, it should be "WRPC" */
#define PTPD_SOCK_RAW_ETHERNET 1 /* but used in ppsi, which I won't change */
extern int link_status;
#define LINK_DOWN 0
#define LINK_WENT_UP 1
#define LINK_WENT_DOWN 2
#define LINK_UP 3
#define LINK_DOWN 4
// GCC-specific
#ifndef PACKED
......
......@@ -35,8 +35,8 @@ int env_set(const char *var, const char *value);
void env_init(void);
int shell_exec(const char *buf);
void shell_interactive(void);
int shell_interactive(void);
int shell_boot_script(void);
void shell_boot_script(void);
#endif
/*
* This work is part of the White Rabbit project
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#ifndef __WRC_TASK_H__
#define __WRC_TASK_H__
/*
* A task is a data structure, but currently suboptimal.
* FIXME: init must return int, and both should get a pointer to data
* FIXME: provide a jiffy-based period.
*/
struct wrc_task {
char *name;
int *enable; /* A global enable variable */
void (*init)(void);
int (*job)(void);
/* And we keep statistics about cpu usage */
unsigned long nrun;
unsigned long seconds;
unsigned long nanos;
};
#endif /* __WRC_TASK_H__ */
......@@ -17,6 +17,7 @@
#include <pp-printf.h>
#include <util.h>
#include <trace.h>
#include <wrc-task.h>
#define vprintf pp_vprintf
#define sprintf pp_sprintf
......@@ -34,7 +35,7 @@
# define is_wr_node 1
#endif
void wrc_mon_gui(void);
int wrc_mon_gui(void);
void shell_init(void);
int wrc_log_stats(void);
......@@ -53,7 +54,7 @@ extern int abs(int val);
/* The following from ptp-noposix */
extern void wr_servo_reset(void);
void update_rx_queues(void);
int update_rx_queues(void);
/* refresh period for _gui_ and _stat_ commands */
extern int wrc_ui_refperiod;
......
......@@ -88,17 +88,20 @@ static int process_arp(uint8_t * buf, int len)
return ARP_END;
}
void arp_poll(void)
int arp_poll(void)
{
uint8_t buf[ARP_END + 100];
struct wr_sockaddr addr;
int len;
if (ip_status == IP_TRAINING)
return; /* can't do ARP w/o an address... */
return 0; /* can't do ARP w/o an address... */
if ((len = ptpd_netif_recvfrom(arp_socket,
&addr, buf, sizeof(buf), 0)) > 0)
&addr, buf, sizeof(buf), 0)) > 0) {
if ((len = process_arp(buf, len)) > 0)
ptpd_netif_sendto(arp_socket, &addr, buf, len, 0);
return 1;
}
return 0;
}
......@@ -51,8 +51,8 @@ static struct wrpc_socket *rdate_socket;
void __attribute__((weak)) syslog_init(void)
{ }
void __attribute__((weak)) syslog_poll(int l_status)
{ }
int __attribute__((weak)) syslog_poll(void)
{ return 0; }
unsigned int ipv4_checksum(unsigned short *buf, int shorts)
{
......@@ -94,11 +94,11 @@ static int bootp_retry = 0;
static uint32_t bootp_tics;
/* receive bootp through the UDP mechanism */
static void bootp_poll(void)
static int bootp_poll(void)
{
struct wr_sockaddr addr;
uint8_t buf[400];
int len;
int len, ret = 0;
if (!bootp_tics) /* first time ever */
bootp_tics = timer_get_tics() - 1;
......@@ -107,20 +107,21 @@ static void bootp_poll(void)
buf, sizeof(buf), NULL);
if (ip_status != IP_TRAINING)
return;
return 0;
if (len > 0)
process_bootp(buf, len);
ret = process_bootp(buf, len);
if (time_before(timer_get_tics(), bootp_tics))
return;
return ret;
len = prepare_bootp(&addr, buf, ++bootp_retry);
ptpd_netif_sendto(bootp_socket, &addr, buf, len, 0);
bootp_tics = timer_get_tics() + TICS_PER_SECOND;
return 1;
}
static void icmp_poll(void)
static int icmp_poll(void)
{
struct wr_sockaddr addr;
uint8_t buf[128];
......@@ -129,15 +130,16 @@ static void icmp_poll(void)
len = ptpd_netif_recvfrom(icmp_socket, &addr,
buf, sizeof(buf), NULL);
if (len <= 0)
return;
return 0;
if (ip_status == IP_TRAINING)
return;
return 0;
if ((len = process_icmp(buf, len)) > 0)
ptpd_netif_sendto(icmp_socket, &addr, buf, len, 0);
return 1;
}
static void rdate_poll(void)
static int rdate_poll(void)
{
struct wr_sockaddr addr;
uint64_t secs;
......@@ -148,7 +150,7 @@ static void rdate_poll(void)
len = ptpd_netif_recvfrom(rdate_socket, &addr,
buf, sizeof(buf), NULL);
if (len <= 0)
return;
return 0;
shw_pps_gen_get_time(&secs, NULL);
result = htonl((uint32_t)(secs + 2208988800LL));
......@@ -159,20 +161,24 @@ static void rdate_poll(void)
fill_udp(buf, len, NULL);
ptpd_netif_sendto(rdate_socket, &addr, buf, len, 0);
return 1;
}
void ipv4_poll(int l_status)
int ipv4_poll(void)
{
if (l_status == LINK_WENT_UP && ip_status == IP_OK_BOOTP)
int ret = 0;
if (link_status == LINK_WENT_UP && ip_status == IP_OK_BOOTP)
ip_status = IP_TRAINING;
bootp_poll();
ret = bootp_poll();
ret += icmp_poll();
icmp_poll();
ret += rdate_poll();
rdate_poll();
ret += syslog_poll();
syslog_poll(l_status);
return ret != 0;
}
void getIP(unsigned char *IP)
......
......@@ -34,13 +34,13 @@
#define UDP_END (UDP_CHECKSUM+2)
void ipv4_init(void);
void ipv4_poll(int l_status);
int ipv4_poll(void);
/* Internal to IP stack: */
unsigned int ipv4_checksum(unsigned short *buf, int shorts);
void arp_init(void);
void arp_poll(void);
int arp_poll(void);
enum ip_status {
IP_TRAINING,
......@@ -66,6 +66,6 @@ struct wr_udp_addr {
void fill_udp(uint8_t * buf, int len, struct wr_udp_addr *uaddr);
void syslog_init(void);
void syslog_poll(int l_status);
int syslog_poll(void);
#endif
......@@ -308,7 +308,7 @@ int ptpd_netif_sendto(struct wrpc_socket * sock, struct wr_sockaddr *to, void *d
}
void update_rx_queues()
int update_rx_queues()
{
struct wrpc_socket *s = NULL;
struct sockq *q;
......@@ -323,7 +323,7 @@ void update_rx_queues()
&hwts);
if (recvd <= 0) /* No data received? */
return;
return 0;
for (i = 0; i < ARRAY_SIZE(socks); i++) {
s = socks[i];
......@@ -352,7 +352,7 @@ void update_rx_queues()
if (i == ARRAY_SIZE(socks)) {
net_verbose("%s: could not find socket for packet\n",
__FUNCTION__);
return;
return 1;
}
q = &s->queue;
......@@ -363,7 +363,7 @@ void update_rx_queues()
net_verbose
("%s: queue for socket full; [avail %d required %d]\n",
__FUNCTION__, q->avail, q_required);
return;
return 1;
}
size = recvd;
......@@ -383,4 +383,5 @@ void update_rx_queues()
ntohs(s->bind_addr.ethertype),
s->bind_addr.udpport,
q->avail, q->n, q_required);
return 1;
}
......@@ -55,7 +55,7 @@ DEFINE_WRC_COMMAND(mac) = {
};
void syslog_poll(int l_status)
int syslog_poll(void)
{
struct wr_sockaddr addr;
char buf[256];
......@@ -67,9 +67,9 @@ void syslog_poll(int l_status)
int len = 0;
if (ip_status == IP_TRAINING)
return;
return 0;
if (!syslog_addr.daddr)
return;
return 0;
if (!tics) {
/* first time ever, or new syslog server */
......@@ -86,9 +86,9 @@ void syslog_poll(int l_status)
goto send;
}
if (l_status == LINK_WENT_DOWN)
if (link_status == LINK_WENT_DOWN)
down_tics = timer_get_tics();
if (l_status == LINK_UP && down_tics) {
if (link_status == LINK_UP && down_tics) {
down_tics = timer_get_tics() - down_tics;
shw_pps_gen_get_time(&secs, NULL);
getIP(ip);
......@@ -101,7 +101,7 @@ void syslog_poll(int l_status)
goto send;
}
return;
return 0;
send:
len += UDP_END;
......@@ -109,5 +109,6 @@ send:
fill_udp((void *)buf, len, &syslog_addr);
memcpy(&addr.mac, syslog_mac, 6);
ptpd_netif_sendto(syslog_socket, &addr, buf, len, 0);
return 1;
}
......@@ -81,7 +81,7 @@ static int wrc_mon_status(void)
return 1;
}
void wrc_mon_gui(void)
int wrc_mon_gui(void)
{
static uint32_t last_jiffies;
static uint32_t last_servo_count;
......@@ -100,7 +100,7 @@ void wrc_mon_gui(void)
last_jiffies = timer_get_tics() - 1 - wrc_ui_refperiod;
if (time_before(timer_get_tics(), last_jiffies + wrc_ui_refperiod)
&& last_servo_count == s->update_count)
return;
return 0;
last_jiffies = timer_get_tics();
last_servo_count = s->update_count;
......@@ -130,7 +130,7 @@ void wrc_mon_gui(void)
if (!WR_DSPOR(ppi)->wrModeOn) {
wrc_mon_std_servo();
return;
return 1;
}
switch (ptp_mode) {
......@@ -174,7 +174,7 @@ void wrc_mon_gui(void)
}
if (wrc_mon_status() == 0)
return;
return 1;
cprintf(C_GREY, "Servo state: ");
cprintf(C_WHITE, "%s\n", s->servo_state_name);
......@@ -247,7 +247,7 @@ void wrc_mon_gui(void)
pp_printf("--");
return;
return 1;
}
static inline void cprintf_ti(int color, struct TimeInternal *ti)
......@@ -301,6 +301,9 @@ int wrc_log_stats(void)
&((struct wr_data *)ppi->ext_data)->servo_state;
static uint32_t last_jiffies;
if (!wrc_stat_running)
return 0;
if (!last_jiffies)
last_jiffies = timer_get_tics() - 1 - wrc_ui_refperiod;
/* stats update condition for Slave mode */
......@@ -363,5 +366,5 @@ int wrc_log_stats(void)
pp_printf("\n");
return 0;
return 1;
}
ppsi @ 908e88d6
Subproject commit 43635331c54fa906bf54ad75e3087e336bdc7799
Subproject commit 908e88d63cb4cd0f89e4e1ceee2d8d31f1c9be5e
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2016 GSI (www.gsi.de)
* Author: Alessandro Rubini <a.rubini@gsi.de>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <wrc.h>
#include <string.h>
#include <shell.h>
extern struct wrc_task wrc_tasks[];
extern int wrc_n_tasks;
static int cmd_ps(const char *args[])
{
int i;
struct wrc_task *t;
if (args[0] && !strcasecmp(args[0], "reset")) {
for (i = 0; i < wrc_n_tasks; i++) {
t = wrc_tasks + i;
t->nrun = t->seconds = t->nanos = 0;
}
return 0;
}
pp_printf(" iterations seconds.micros name\n");
for (i = 0; i < wrc_n_tasks; i++) {
t = wrc_tasks + i;
pp_printf(" %9li %9li.%06li %s\n", t->nrun,
t->seconds, t->nanos/1000, t->name);
}
return 0;
}
DEFINE_WRC_COMMAND(ps) = {
.name = "ps",
.exec = cmd_ps,
};
......@@ -128,7 +128,7 @@ void shell_init()
state = SH_PROMPT;
}
void shell_interactive()
int shell_interactive()
{
int c;
switch (state) {
......@@ -137,13 +137,13 @@ void shell_interactive()
cmd_pos = 0;
cmd_len = 0;
state = SH_INPUT;
break;
return 1;
case SH_INPUT:
c = uart_read_byte();
if (c < 0)
return;
return 0;
if (c == 27 || ((current_key & ESCAPE_FLAG) && c == 91))
current_key = ESCAPE_FLAG;
......@@ -201,14 +201,15 @@ void shell_interactive()
}
current_key = 0;
}
break;
return 1;
case SH_EXEC:
cmd_buf[cmd_len] = 0;
_shell_exec();
state = SH_PROMPT;
break;
return 1;
}
return 0;
}
const char *fromhex(const char *hex, int *v)
......@@ -247,12 +248,12 @@ const char *fromdec(const char *dec, int *v)
return dec;
}
int shell_boot_script(void)
void shell_boot_script(void)
{
uint8_t next = 0;
if (!has_eeprom)
return -1;
return;
while (1) {
cmd_len = storage_init_readcmd((uint8_t *)cmd_buf,
......@@ -269,5 +270,5 @@ int shell_boot_script(void)
next = 1;
}
return 0;
return;
}
......@@ -14,6 +14,7 @@ obj-$(CONFIG_WR_NODE) += \
shell/cmd_init.o \
shell/cmd_ptrack.o \
shell/cmd_help.o \
shell/cmd_ps.o \
shell/cmd_refresh.o
obj-$(CONFIG_IP) += shell/cmd_ip.o
......
......@@ -534,6 +534,7 @@ static inline void aux_set_channel_status(int channel, int locked)
static int spll_update_aux_clocks(void)
{
int ch;
int done_sth = 0;
for (ch = 1; ch < spll_n_chan_out; ch++)
{
......@@ -545,6 +546,7 @@ static int spll_update_aux_clocks(void)
spll_stop_channel(ch);
aux_set_channel_status(ch, 0);
s->seq_state = AUX_DISABLED;
done_sth++;
}
switch (s->seq_state) {
......@@ -553,6 +555,7 @@ static int spll_update_aux_clocks(void)
pll_verbose("softpll: enabled aux channel %d\n", ch);
spll_start_channel(ch);
s->seq_state = AUX_LOCK_PLL;
done_sth++;
}
break;
......@@ -561,8 +564,8 @@ static int spll_update_aux_clocks(void)
pll_verbose ("softpll: channel %d locked [aligning @ %d ps]\n", ch, softpll.mpll_shift_ps);
set_phase_shift(ch, softpll.mpll_shift_ps);
s->seq_state = AUX_ALIGN_PHASE;
done_sth++;
}
break;
case AUX_ALIGN_PHASE:
......@@ -570,6 +573,7 @@ static int spll_update_aux_clocks(void)
pll_verbose("softpll: channel %d phase aligned\n", ch);
aux_set_channel_status(ch, 1);
s->seq_state = AUX_READY;
done_sth++;
}
break;
......@@ -578,11 +582,12 @@ static int spll_update_aux_clocks(void)
pll_verbose("softpll: aux channel %d or mpll lost lock\n", ch);
aux_set_channel_status(ch, 0);
s->seq_state = AUX_DISABLED;
done_sth++;
}
break;
}
}
return 0;
return done_sth != 0;
}
int spll_get_aux_status(int channel)
......@@ -625,14 +630,16 @@ void spll_set_dac(int index, int value)
}
}
void spll_update()
int spll_update()
{
int ret = 0;
switch(softpll.mode) {
case SPLL_MODE_GRAND_MASTER:
external_align_fsm(&softpll.ext);
ret = external_align_fsm(&softpll.ext);
break;
}
spll_update_aux_clocks();
ret += spll_update_aux_clocks();
/* currently we have statistics only in the switch */
if (is_wr_switch) {
......@@ -648,6 +655,7 @@ void spll_update()
stats.del_cnt = softpll.delock_count;
stats.sequence++;
}
return ret != 0;
}
static int spll_measure_frequency(int osc)
......
......@@ -105,7 +105,7 @@ int spll_read_ptracker(int ref_channel, int32_t *phase_ps, int *enabled);
/* Calls non-realtime update state machine. Must be called regularly (although
* it is not time-critical) in the main loop of the program if aux clocks or
* external reference are used in the design. */
void spll_update(void);
int spll_update(void);
/* Returns the status of given aux clock output (SPLL_AUX_) */
int spll_get_aux_status(int out_channel);
......
......@@ -94,11 +94,11 @@ static int align_sample(int channel, int *v)
return 0; // sample not valid
}
void external_align_fsm(volatile struct spll_external_state *s)
int external_align_fsm(volatile struct spll_external_state *s)
{
int v;
switch(s->align_state) {
int v, done_sth = 0;
switch(s->align_state) {
case ALIGN_STATE_EXT_OFF:
break;
......@@ -106,6 +106,7 @@ void external_align_fsm(volatile struct spll_external_state *s)
if( !(SPLL->ECCR & SPLL_ECCR_EXT_REF_STOPPED) ) {
SPLL->ECCR |= SPLL_ECCR_EXT_REF_PLLRST;
s->align_state = ALIGN_STATE_WAIT_PLOCK;
done_sth++;
}
break;
......@@ -115,6 +116,7 @@ void external_align_fsm(volatile struct spll_external_state *s)
s->align_state = ALIGN_STATE_WAIT_CLKIN;
else if( SPLL->ECCR & SPLL_ECCR_EXT_REF_LOCKED )
s->align_state = ALIGN_STATE_START;
done_sth++;
break;
case ALIGN_STATE_START:
......@@ -123,6 +125,7 @@ void external_align_fsm(volatile struct spll_external_state *s)
mpll_start(s->main);
enable_irq();
s->align_state = ALIGN_STATE_START_MAIN;
done_sth++;
}
break;
......@@ -130,10 +133,11 @@ void external_align_fsm(volatile struct spll_external_state *s)
SPLL->AL_CR = 2;
if(s->helper->ld.locked && s->main->ld.locked) {
PPSG->CR = PPSG_CR_CNT_EN | PPSG_CR_PWIDTH_W(10);
PPSG->ADJ_NSEC = 3;
PPSG->ESCR = PPSG_ESCR_SYNC;
s->align_state = ALIGN_STATE_INIT_CSYNC;
pll_verbose("EXT: DMTD locked.\n");
PPSG->ADJ_NSEC = 3;
PPSG->ESCR = PPSG_ESCR_SYNC;
s->align_state = ALIGN_STATE_INIT_CSYNC;
pll_verbose("EXT: DMTD locked.\n");
done_sth++;
}
break;
......@@ -142,6 +146,7 @@ void external_align_fsm(volatile struct spll_external_state *s)
PPSG->ESCR = PPSG_ESCR_PPS_VALID; // enable PPS output (even though it's not aligned yet)
s->align_timer = timer_get_tics() + 2 * TICS_PER_SECOND;
s->align_state = ALIGN_STATE_WAIT_CSYNC;
done_sth++;
}
break;
......@@ -150,6 +155,7 @@ void external_align_fsm(volatile struct spll_external_state *s)
s->align_state = ALIGN_STATE_START_ALIGNMENT;
s->align_shift = 0;
pll_verbose("EXT: CSync complete.\n");
done_sth++;
}
break;
......@@ -166,6 +172,7 @@ void external_align_fsm(volatile struct spll_external_state *s)
pll_verbose("EXT: Align target %d, step %d.\n", s->align_target, s->align_step);
s->align_state = ALIGN_STATE_WAIT_SAMPLE;
done_sth++;
}
break;
......@@ -180,6 +187,7 @@ void external_align_fsm(volatile struct spll_external_state *s)
mpll_set_phase_shift(s->main, s->align_shift);
s->align_state = ALIGN_STATE_COMPENSATE_DELAY;
}
done_sth++;
}
break;
......@@ -187,16 +195,19 @@ void external_align_fsm(volatile struct spll_external_state *s)
if(!mpll_shifter_busy(s->main)) {
pll_verbose("EXT: Align done.\n");
s->align_state = ALIGN_STATE_LOCKED;
done_sth++;
}
break;
case ALIGN_STATE_LOCKED:
if(!external_locked(s)) {
s->align_state = ALIGN_STATE_WAIT_CLKIN;
done_sth++;
}
break;
default:
break;
}
return done_sth != 0;
}
......@@ -35,6 +35,6 @@ void external_start(struct spll_external_state *s);
int external_locked(volatile struct spll_external_state *s);
void external_align_fsm(volatile struct spll_external_state *s);
int external_align_fsm(volatile struct spll_external_state *s);
#endif // __SPLL_EXTERNAL_H
......@@ -44,6 +44,8 @@ int32_t sfp_deltaTx = 0;
int32_t sfp_deltaRx = 0;
uint32_t cal_phase_transition = 2389;
static uint32_t prev_nanos_for_profile;
static void wrc_initialize(void)
{
uint8_t mac_addr[6];
......@@ -89,51 +91,62 @@ static void wrc_initialize(void)
//try reading t24 phase transition from EEPROM
calib_t24p(WRC_MODE_MASTER, &cal_phase_transition);
spll_very_init();
usleep_init();
shell_init();
if (HAS_IP) {
ipv4_init();
arp_init();
}
wrc_ui_mode = UI_SHELL_MODE;
_endram = ENDRAM_MAGIC;
wrc_ptp_set_mode(WRC_MODE_SLAVE);
wrc_ptp_start();
shw_pps_gen_get_time(NULL, &prev_nanos_for_profile);
}
int link_status;
static int wrc_check_link(void)
{
static int prev_link_state = -1;
int link_state = ep_link_up(NULL);
static int prev_state = -1;
int state = ep_link_up(NULL);
int rv = 0;
if (!prev_link_state && link_state) {
if (!prev_state && state) {
wrc_verbose("Link up.\n");
gpio_out(GPIO_LED_LINK, 1);
rv = LINK_WENT_UP;
} else if (prev_link_state && !link_state) {
link_status = LINK_WENT_UP;
rv = 1;
} else if (prev_state && !state) {
wrc_verbose("Link down.\n");
gpio_out(GPIO_LED_LINK, 0);
rv = LINK_WENT_DOWN;
link_status = LINK_WENT_DOWN;
rv = 1;
/* special case */
spll_init(SPLL_MODE_FREE_RUNNING_MASTER, 0, 1);
shw_pps_gen_enable_output(0);
} else
rv = (link_state ? LINK_UP : LINK_DOWN);
prev_link_state = link_state;
link_status = (state ? LINK_UP : LINK_DOWN);
prev_state = state;
return rv;
}
int wrc_man_phase = 0;
static void ui_update(void)
static int ui_update(void)
{
int ret;
if (wrc_ui_mode == UI_GUI_MODE) {
wrc_mon_gui();
ret = wrc_mon_gui();
if (uart_read_byte() == 27 || wrc_ui_refperiod == 0) {
shell_init();
wrc_ui_mode = UI_SHELL_MODE;
}
} else {
shell_interactive();
ret = shell_interactive();
}
/* Stats is asynchronous now. It's not a different mode, but a flag */
if (wrc_stat_running)
wrc_log_stats();
return ret;
}
/* initialize functions to be called after reset in check_reset function */
......@@ -146,58 +159,127 @@ void init_hw_after_reset(void)
timer_init(1);
}
int main(void)
/* count uptime, in seconds, for remote polling */
static uint32_t uptime_lastj;
static void init_uptime(void)
{
uptime_lastj = timer_get_tics();
}
static int update_uptime(void)
{
extern uint32_t uptime_sec;
uint32_t j, lastj, fraction = 0;
uint32_t j;
static uint32_t fraction = 0;
check_reset();
wrc_ui_mode = UI_SHELL_MODE;
_endram = ENDRAM_MAGIC;
j = timer_get_tics();
fraction += j - uptime_lastj;
uptime_lastj = j;
if (fraction > TICS_PER_SECOND) {
fraction -= TICS_PER_SECOND;
uptime_sec++;
return 1;
}
return 0;
}
wrc_initialize();
usleep_init();
shell_init();
struct wrc_task wrc_tasks[] = {
{
.name = "idle",
.init = wrc_initialize,
}, {
.name = "uptime",
.init = init_uptime,
.job = update_uptime,
}, {
.name = "check-link",
.job = wrc_check_link,
}, {
.name = "net-bh",
.enable = &link_status,
.job = update_rx_queues,
}, {
.name = "ptp",
.job = wrc_ptp_update,
}, {
.name = "shell+gui",
.init = shell_boot_script,
.job = ui_update,
}, {
.name = "stats",
.job = wrc_log_stats,
}, {
.name = "spll-bh",
.job = spll_update,
#ifdef CONFIG_IP
}, {
.name = "ipv4",
.enable = &link_status,
.init = ipv4_init,
.job = ipv4_poll,
}, {
.name = "arp",
.enable = &link_status,
.init = arp_init,
.job = arp_poll,
#endif
}
};
wrc_ptp_set_mode(WRC_MODE_SLAVE);
wrc_ptp_start();
int wrc_n_tasks = ARRAY_SIZE(wrc_tasks);
//try to read and execute init script from EEPROM
shell_boot_script();
lastj = timer_get_tics();
/* Account the time to either this task or task 0 */
static void account_task(struct wrc_task *t, int done_sth)
{
uint32_t nanos;
signed int delta;
for (;;) {
int l_status = wrc_check_link();
/* count uptime, in seconds, for remote polling */
j = timer_get_tics();
fraction += j -lastj;
lastj = j;
while (fraction > TICS_PER_SECOND) {
fraction -= TICS_PER_SECOND;
uptime_sec++;
}
if (!done_sth)
t = wrc_tasks;
shw_pps_gen_get_time(NULL, &nanos);
delta = nanos - prev_nanos_for_profile;
if (delta < 0)
delta += 1000 * 1000 * 1000;
switch (l_status) {
case LINK_WENT_DOWN:
if (wrc_ptp_get_mode() == WRC_MODE_SLAVE) {
spll_init(SPLL_MODE_FREE_RUNNING_MASTER, 0, 1);
shw_pps_gen_enable_output(0);
}
/* fall through */
case LINK_WENT_UP:
case LINK_UP:
update_rx_queues();
if (HAS_IP) {
ipv4_poll(l_status);
arp_poll();
}
break;
}
t->nanos += delta;
if (t-> nanos > 1000 * 1000 * 1000) {
t->nanos -= 1000 * 1000 * 1000;
t->seconds++;
}
prev_nanos_for_profile = nanos;
}
/* Run a task with profiling */
static void wrc_run_task(struct wrc_task *t)
{
int done_sth = 0;
if (!t->job) /* idle task, just count iterations */
t->nrun++;
else if (!t->enable || *t->enable) {
/* either enabled or without a check variable */
done_sth = t->job();
t->nrun += done_sth;
}
account_task(t, done_sth);
}
int main(void)
{
int i;
check_reset();
/* initialization of individual tasks */
for (i = 0; i < wrc_n_tasks; i++)
if (wrc_tasks[i].init)
wrc_tasks[i].init();
for (;;) {
/* run your tasks */
for (i = 0; i < wrc_n_tasks; i++)
wrc_run_task(wrc_tasks + i);
ui_update();
wrc_ptp_update();
spll_update();
/* better safe than sorry */
check_stack();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment