Commit d9d20c8b authored by Alessandro Rubini's avatar Alessandro Rubini

general: use an ELF section for tasks

This allows several functions to be static in the files where they
are defined. See temperature.c for an example.

But mainly, the idea is allowing ease addition of features (likely
Kconfig'd ones) for specific WR users, without any modification to the
main function and other generic code.  This will happen soon for snmp,
for example.

We may push this a little further, by moving all shell stuff into
shell.c, the ptp task within ppsi itself, and so on. But now my time
is over.
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent e24e51a0
......@@ -15,4 +15,10 @@ SECTIONS
KEEP(*(.temp))
__temp_end = .;
}
.task : {
__task_begin = .;
KEEP(*(.task0))
KEEP(*(.task))
__task_end = .;
}
}
......@@ -85,7 +85,7 @@ extern int wrc_temp_format(char *buffer, int len)
/*
* The task
*/
void wrc_temp_init(void)
static void wrc_temp_init(void)
{
struct wrc_temp *ta;
......@@ -94,7 +94,7 @@ void wrc_temp_init(void)
ta->read(ta);
}
int wrc_temp_refresh(void)
static int wrc_temp_refresh(void)
{
struct wrc_temp *ta;
int ret = 0;
......@@ -104,6 +104,12 @@ int wrc_temp_refresh(void)
return (ret > 0);
}
DEFINE_WRC_TASK(temp) = {
.name = "temperature",
.init = wrc_temp_init,
.job = wrc_temp_refresh,
};
/*
* The shell command
*/
......
......@@ -111,22 +111,6 @@ void enable_irq(void)
int wrc_mon_gui(void)
{ printf("%s\n", __func__); return 0;}
int wrc_log_stats(void)
{
static uint32_t last_jiffies;
if (!wrc_stat_running)
return 0;
if (!last_jiffies)
last_jiffies = timer_get_tics() - 1 - wrc_ui_refperiod;
if (time_before(timer_get_tics(), last_jiffies + wrc_ui_refperiod))
return 0;
last_jiffies = timer_get_tics();
printf("%s\n", __func__);
return 1;
}
void sdb_find_devices(void)
{ printf("%s\n", __func__); }
......
......@@ -25,11 +25,6 @@ struct wrc_temp {
static struct wrc_temp __wrc_temp_ ## _name \
__attribute__((section(".temp"), __used__))
/* the task */
extern void wrc_temp_init(void);
extern int wrc_temp_refresh(void);
/* lib functions */
extern uint32_t wrc_temp_get(char *name);
struct wrc_onetemp *wrc_temp_getnext(struct wrc_onetemp *);
......
......@@ -23,5 +23,17 @@ struct wrc_task {
unsigned long nanos;
};
/* Put the tasks in their own section */
#define DEFINE_WRC_TASK(_name) \
static struct wrc_task __task_ ## _name \
__attribute__((section(".task"), used, aligned(sizeof(unsigned long))))
/* Task 0 must be first, sorry! */
#define DEFINE_WRC_TASK0(_name) \
static struct wrc_task __task_ ## _name \
__attribute__((section(".task0"), used, aligned(sizeof(unsigned long))))
extern struct wrc_task __task_begin[];
extern struct wrc_task __task_end[];
#define for_each_task(t) for ((t) = __task_begin; (t) < __task_end; (t)++)
#endif /* __WRC_TASK_H__ */
......@@ -39,7 +39,6 @@ extern int wrc_vlan_number;
int wrc_mon_gui(void);
void shell_init(void);
int wrc_log_stats(void);
/* This header is included by softpll: manage wrc/wrs difference */
#ifdef CONFIG_WR_NODE
......@@ -56,7 +55,6 @@ extern int abs(int val);
/* The following from ptp-noposix */
extern void wr_servo_reset(void);
int update_rx_queues(void);
/* refresh period for _gui_ and _stat_ commands */
extern int wrc_ui_refperiod;
......
......@@ -34,7 +34,7 @@ static struct wrpc_socket *arp_socket;
#define ARP_TPA (ARP_THA+6)
#define ARP_END (ARP_TPA+4)
void arp_init(void)
static void arp_init(void)
{
struct wr_sockaddr saddr;
......@@ -88,7 +88,7 @@ static int process_arp(uint8_t * buf, int len)
return ARP_END;
}
int arp_poll(void)
static int arp_poll(void)
{
uint8_t buf[ARP_END + 100];
struct wr_sockaddr addr;
......@@ -105,3 +105,10 @@ int arp_poll(void)
}
return 0;
}
DEFINE_WRC_TASK(arp) = {
.name = "arp",
.enable = &link_status,
.init = arp_init,
.job = arp_poll,
};
......@@ -69,7 +69,7 @@ unsigned int ipv4_checksum(unsigned short *buf, int shorts)
return (~sum & 0xffff);
}
void ipv4_init(void)
static void ipv4_init(void)
{
struct wr_sockaddr saddr;
......@@ -164,7 +164,7 @@ static int rdate_poll(void)
return 1;
}
int ipv4_poll(void)
static int ipv4_poll(void)
{
int ret = 0;
......@@ -186,6 +186,13 @@ void getIP(unsigned char *IP)
memcpy(IP, myIP, 4);
}
DEFINE_WRC_TASK(ipv4) = {
.name = "ipv4",
.enable = &link_status,
.init = ipv4_init,
.job = ipv4_poll,
};
void setIP(unsigned char *IP)
{
volatile unsigned int *eb_ip =
......
......@@ -36,15 +36,9 @@
#define UDP_CHECKSUM (UDP_LENGTH+2)
#define UDP_END (UDP_CHECKSUM+2)
void ipv4_init(void);
int ipv4_poll(void);
/* Internal to IP stack: */
unsigned int ipv4_checksum(unsigned short *buf, int shorts);
void arp_init(void);
int arp_poll(void);
enum ip_status {
IP_TRAINING,
IP_OK_BOOTP,
......
......@@ -308,8 +308,7 @@ int ptpd_netif_sendto(struct wrpc_socket * sock, struct wr_sockaddr *to, void *d
return rval;
}
int update_rx_queues()
static int update_rx_queues(void)
{
struct wrpc_socket *s = NULL, *raws = NULL, *udps = NULL;
struct sockq *q;
......@@ -402,3 +401,8 @@ int update_rx_queues()
q->avail, q->n, q_required);
return 1;
}
DEFINE_WRC_TASK(net_bh) = {
.name = "net-bh",
.enable = &link_status,
.job = update_rx_queues,
};
......@@ -286,7 +286,7 @@ static void wrc_mon_std_servo(void)
/* internal "last", exported to shell command */
uint32_t wrc_stats_last;
int wrc_log_stats(void)
static int wrc_log_stats(void)
{
struct hal_port_state state;
int tx, rx;
......@@ -360,3 +360,7 @@ int wrc_log_stats(void)
return 1;
}
DEFINE_WRC_TASK(stats) = {
.name = "stats",
.job = wrc_log_stats,
};
......@@ -15,22 +15,17 @@ 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;
for_each_task(t)
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;
for_each_task(t)
pp_printf(" %9li %9li.%06li %s\n", t->nrun,
t->seconds, t->nanos/1000, t->name);
}
return 0;
}
......
......@@ -105,6 +105,11 @@ static void wrc_initialize(void)
shw_pps_gen_get_time(NULL, &prev_nanos_for_profile);
}
DEFINE_WRC_TASK0(idle) = {
.name = "idle",
.init = wrc_initialize,
};
int link_status;
static int wrc_check_link(void)
......@@ -133,6 +138,10 @@ static int wrc_check_link(void)
return rv;
}
DEFINE_WRC_TASK(link) = {
.name = "check-link",
.job = wrc_check_link,
};
static int ui_update(void)
{
......@@ -182,56 +191,26 @@ static int update_uptime(void)
}
return 0;
}
struct wrc_task wrc_tasks[] = {
{
.name = "idle",
.init = wrc_initialize,
}, {
DEFINE_WRC_TASK(uptime) = {
.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,
}, {
};
DEFINE_WRC_TASK(ptp) = {
.name = "ptp",
.job = wrc_ptp_update,
}, {
};
DEFINE_WRC_TASK(shell) = {
.name = "shell+gui",
.init = shell_boot_script,
.job = ui_update,
}, {
.name = "stats",
.job = wrc_log_stats,
}, {
};
DEFINE_WRC_TASK(spll) = {
.name = "spll-bh",
.job = spll_update,
}, {
.name = "temperature",
.init = wrc_temp_init,
.job = wrc_temp_refresh,
#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
}
};
int wrc_n_tasks = ARRAY_SIZE(wrc_tasks);
/* Account the time to either this task or task 0 */
static void account_task(struct wrc_task *t, int done_sth)
{
......@@ -239,7 +218,7 @@ static void account_task(struct wrc_task *t, int done_sth)
signed int delta;
if (!done_sth)
t = wrc_tasks;
t = __task_begin; /* task 0 is special */
shw_pps_gen_get_time(NULL, &nanos);
delta = nanos - prev_nanos_for_profile;
if (delta < 0)
......@@ -270,19 +249,18 @@ static void wrc_run_task(struct wrc_task *t)
int main(void)
{
int i;
struct wrc_task *t;
check_reset();
/* initialization of individual tasks */
for (i = 0; i < wrc_n_tasks; i++)
if (wrc_tasks[i].init)
wrc_tasks[i].init();
for_each_task(t)
if (t->init)
t->init();
for (;;) {
/* run your tasks */
for (i = 0; i < wrc_n_tasks; i++)
wrc_run_task(wrc_tasks + i);
for_each_task(t)
wrc_run_task(t);
/* 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