Commit a9ce831d authored by Alessandro Rubini's avatar Alessandro Rubini

shell: reorganize parsing using .cmd ELF section

This commit creates a .cmd section, so there is no global list of
commands in shell.c any more, and no ifdef in the code for conditional
commands.  Also, (unrelated) makes shell errors slightly more friendly.

The technique is widely used, in the Linux kernel and all boot
loaders, as well as a lot of my own personal code, so this is safe
(and tested).

As a side effect, this allows (in later commits) to move the "verbose"
ppsi-specific command back to ppsi/arch-wrpc/ where it really belongs.
It allows new commands to be easily added by just adding their
respective file to the build.

Even though this increases code size by around 50 lines, it makes it
more modular and only costs 8 bytes in the final executable (in my
configuration: 128 bytes less of text and 136 bytes more of data).
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent eb9d18a4
......@@ -10,26 +10,16 @@ extern int wrc_ui_mode;
const char *fromhex(const char *hex, int *v);
const char *fromdec(const char *dec, int *v);
int cmd_gui(const char *args[]);
int cmd_pll(const char *args[]);
int cmd_sfp(const char *args[]);
int cmd_version(const char *args[]);
int cmd_stat(const char *args[]);
int cmd_ptp(const char *args[]);
int cmd_sfp(const char *args[]);
int cmd_mode(const char *args[]);
int cmd_calib(const char *args[]);
int cmd_time(const char *args[]);
int cmd_ip(const char *args[]);
int cmd_verbose(const char *args[]);
int cmd_sdb(const char *args[]);
int cmd_mac(const char *args[]);
int cmd_init(const char *args[]);
int cmd_ptrack(const char *args[]);
int cmd_env(const char *args[]);
int cmd_saveenv(const char *args[]);
int cmd_set(const char *args[]);
struct wrc_shell_cmd {
char *name;
int (*exec) (const char *args[]);
};
extern struct wrc_shell_cmd __cmd_begin[], __cmd_end[];
/* Put the structures in their own section */
#define DEFINE_WRC_COMMAND(_name) \
static struct wrc_shell_cmd __wrc_cmd_ ## _name \
__attribute__((section(".cmd"), __used__))
char *env_get(const char *var);
int env_set(const char *var, const char *value);
......
......@@ -21,7 +21,7 @@
extern int measure_t24p(uint32_t *value);
int cmd_calib(const char *args[])
static int cmd_calibration(const char *args[])
{
uint32_t trans;
......@@ -47,3 +47,8 @@ int cmd_calib(const char *args[])
return 0;
}
DEFINE_WRC_COMMAND(calibration) = {
.name = "calibration",
.exec = cmd_calibration,
};
......@@ -5,8 +5,13 @@
#include "shell.h"
int cmd_gui(const char *args[])
static int cmd_gui(const char *args[])
{
wrc_ui_mode = UI_GUI_MODE;
return 0;
}
DEFINE_WRC_COMMAND(gui) = {
.name = "gui",
.exec = cmd_gui,
};
......@@ -14,7 +14,7 @@
#include "syscon.h"
#include "i2c.h"
int cmd_init(const char *args[])
static int cmd_init(const char *args[])
{
if (!mi2c_devprobe(WRPC_FMC_I2C, FMC_EEPROM_ADR)) {
mprintf("EEPROM not found..\n");
......@@ -39,3 +39,8 @@ int cmd_init(const char *args[])
return 0;
}
DEFINE_WRC_COMMAND(init) = {
.name = "init",
.exec = cmd_init,
};
......@@ -28,7 +28,7 @@ static void decode_ip(const char *str, unsigned char *ip)
}
}
int cmd_ip(const char *args[])
static int cmd_ip(const char *args[])
{
unsigned char ip[4];
......@@ -49,3 +49,8 @@ int cmd_ip(const char *args[])
}
return 0;
}
DEFINE_WRC_COMMAND(ip) = {
.name = "ip",
.exec = cmd_ip,
};
......@@ -30,7 +30,7 @@ static void decode_mac(const char *str, unsigned char *mac)
}
}
int cmd_mac(const char *args[])
static int cmd_mac(const char *args[])
{
unsigned char mac[6];
......@@ -56,3 +56,8 @@ int cmd_mac(const char *args[])
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return 0;
}
DEFINE_WRC_COMMAND(mac) = {
.name = "mac",
.exec = cmd_mac,
};
......@@ -18,7 +18,7 @@
#include "shell.h"
#include "wrc_ptp.h"
int cmd_mode(const char *args[])
static int cmd_mode(const char *args[])
{
int mode;
static const char *modes[] =
......@@ -36,3 +36,8 @@ int cmd_mode(const char *args[])
}
return wrc_ptp_set_mode(mode);
}
DEFINE_WRC_COMMAND(mode) = {
.name = "mode",
.exec = cmd_mode,
};
......@@ -14,7 +14,7 @@
#include "softpll_ng.h"
#include "shell.h"
int cmd_pll(const char *args[])
static int cmd_pll(const char *args[])
{
int cur, tgt;
......@@ -56,3 +56,8 @@ int cmd_pll(const char *args[])
return 0;
}
DEFINE_WRC_COMMAND(pll) = {
.name = "pll",
.exec = cmd_pll,
};
......@@ -8,7 +8,7 @@
#include "wrc_ptp.h"
#include "shell.h"
int cmd_ptp(const char *args[])
static int cmd_ptp(const char *args[])
{
if (!strcasecmp(args[0], "start"))
return wrc_ptp_start();
......@@ -19,3 +19,8 @@ int cmd_ptp(const char *args[])
return 0;
}
DEFINE_WRC_COMMAND(ptp) = {
.name = "ptp",
.exec = cmd_ptp,
};
......@@ -14,7 +14,7 @@
extern int wrc_phase_tracking;
int cmd_ptrack(const char *args[])
static int cmd_ptrack(const char *args[])
{
if (args[0] && !strcasecmp(args[0], "enable")) {
wr_servo_enable_tracking(1);
......@@ -28,3 +28,8 @@ int cmd_ptrack(const char *args[])
return 0;
}
DEFINE_WRC_COMMAND(ptrack) = {
.name = "ptrack",
.exec = cmd_ptrack,
};
......@@ -2,8 +2,13 @@
#include "syscon.h"
#include "hw/memlayout.h"
int cmd_sdb(const char *args[])
static int cmd_sdb(const char *args[])
{
sdb_print_devices();
return 0;
}
DEFINE_WRC_COMMAND(sdb) = {
.name = "sdb",
.exec = cmd_sdb,
};
......@@ -30,7 +30,7 @@
#include "sfp.h"
int cmd_sfp(const char *args[])
static int cmd_sfp(const char *args[])
{
int8_t sfpcount = 1, i, temp;
struct s_sfpinfo sfp;
......@@ -112,3 +112,8 @@ int cmd_sfp(const char *args[])
return 0;
}
DEFINE_WRC_COMMAND(sfp) = {
.name = "sfp",
.exec = cmd_sfp,
};
......@@ -3,7 +3,7 @@
#include <string.h>
#include <wrc.h>
int cmd_stat(const char *args[])
static int cmd_stat(const char *args[])
{
if (!strcasecmp(args[0], "cont")) {
wrc_ui_mode = UI_STAT_MODE;
......@@ -14,3 +14,8 @@ int cmd_stat(const char *args[])
return 0;
}
DEFINE_WRC_COMMAND(stat) = {
.name = "stat",
.exec = cmd_stat,
};
......@@ -24,7 +24,7 @@
#include "wrc_ptp.h"
#include "pps_gen.h"
int cmd_time(const char *args[])
static int cmd_time(const char *args[])
{
uint64_t sec;
uint32_t nsec;
......@@ -47,3 +47,8 @@ int cmd_time(const char *args[])
return 0;
}
DEFINE_WRC_COMMAND(time) = {
.name = "time",
.exec = cmd_time,
};
......@@ -8,10 +8,11 @@
*/
#include <wrc.h>
#include <shell.h>
extern int pp_diag_verbosity;
int cmd_verbose(const char *args[])
static int cmd_verbose(const char *args[])
{
int v;
v = args[0][0] - '0';
......@@ -25,3 +26,8 @@ int cmd_verbose(const char *args[])
pp_diag_verbosity = v;
return 0;
}
DEFINE_WRC_COMMAND(verbose) = {
.name = "verbose",
.exec = cmd_verbose,
};
......@@ -5,9 +5,14 @@
extern const char *build_revision, *build_date;
int cmd_version(const char *args[])
static int cmd_ver(const char *args[])
{
mprintf("WR Core build: %s%s (memory size: %d kB)\n",
build_revision, build_date, sysc_get_memsize());
return 0;
}
DEFINE_WRC_COMMAND(ver) = {
.name = "ver",
.exec = cmd_ver,
};
......@@ -9,8 +9,8 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <wrc.h>
#include <wrc.h>
#include "shell.h"
#define SH_ENVIRON_SIZE 256
......@@ -89,7 +89,7 @@ int env_set(const char *var, const char *value)
return 0;
}
int cmd_env(const char *args[])
static int cmd_env(const char *args[])
{
char *p = env_buf;
......@@ -102,16 +102,32 @@ int cmd_env(const char *args[])
return 0;
}
int cmd_saveenv(const char *args[])
DEFINE_WRC_COMMAND(env) = {
.name = "env",
.exec = cmd_env,
};
static int cmd_saveenv(const char *args[])
{
return -ENOTSUP;
}
int cmd_set(const char *args[])
DEFINE_WRC_COMMAND(saveenv) = {
.name = "saveenv",
.exec = cmd_saveenv,
};
static int cmd_set(const char *args[])
{
if (!args[1])
return -EINVAL;
return env_set(args[0], args[1]);
}
DEFINE_WRC_COMMAND(set) = {
.name = "set",
.exec = cmd_set,
};
......@@ -39,38 +39,6 @@
#define KEY_BACKSPACE (127)
#define KEY_DELETE (126)
struct shell_cmd {
char *name;
int (*exec) (const char *args[]);
};
static const struct shell_cmd cmds_list[] = {
{"pll", cmd_pll},
{"gui", cmd_gui},
{"ver", cmd_version},
{"stat", cmd_stat},
{"ptp", cmd_ptp},
{"mode", cmd_mode},
{"calibration", cmd_calib},
{"set", cmd_set},
{"env", cmd_env},
{"saveenv", cmd_saveenv},
{"time", cmd_time},
{"sfp", cmd_sfp},
{"init", cmd_init},
{"ptrack", cmd_ptrack},
#ifdef CONFIG_ETHERBONE
{"ip", cmd_ip},
#endif
#if (defined CONFIG_PPSI) && (defined CONFIG_PPSI_RUNTIME_VERBOSITY)
{"verbose", cmd_verbose},
#endif
{"mac", cmd_mac},
{"sdb", cmd_sdb},
{NULL, NULL}
};
static char cmd_buf[SH_MAX_LINE_LEN + 1];
static int cmd_pos = 0, cmd_len = 0;
static int state = SH_PROMPT;
......@@ -106,7 +74,8 @@ static void esc(char code)
static int _shell_exec()
{
char *tokptr[SH_MAX_ARGS + 1];
int n = 0, i = 0;
struct wrc_shell_cmd *p;
int n = 0, i = 0, rv;
memset(tokptr, 0, sizeof(tokptr));
......@@ -134,15 +103,16 @@ static int _shell_exec()
if (*tokptr[0] == '#')
return 0;
for (i = 0; cmds_list[i].name; i++)
if (!strcasecmp(cmds_list[i].name, tokptr[0])) {
int rv = cmds_list[i].exec((const char **)tokptr + 1);
for (p = __cmd_begin; p < __cmd_end; p++)
if (!strcasecmp(p->name, tokptr[0])) {
rv = p->exec((const char **)(tokptr + 1));
if (rv < 0)
mprintf("Err %d\n", rv);
mprintf("Coomand \"%s\": error %d\n",
p->name, rv);
return rv;
}
mprintf("Unrecognized command.\n");
mprintf("Unrecognized command \"%s\".\n", tokptr[0]);
return -EINVAL;
}
......
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