Implemented read command.
This commit is contained in:
parent
ef03cae7b2
commit
f775e52fb6
310
main.c
310
main.c
|
@ -63,6 +63,53 @@ char *get_arg(char **text)
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct command {
|
||||||
|
const char *name;
|
||||||
|
int (*func)(char **arg);
|
||||||
|
const char *help;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct command all_commands[];
|
||||||
|
|
||||||
|
const struct command *find_command(const char *name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; all_commands[i].name; i++)
|
||||||
|
if (!strcasecmp(name, all_commands[i].name))
|
||||||
|
return &all_commands[i];
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int process_command(char *arg)
|
||||||
|
{
|
||||||
|
const char *cmd_text;
|
||||||
|
int len = strlen(arg);
|
||||||
|
|
||||||
|
while (len && isspace(arg[len - 1]))
|
||||||
|
len--;
|
||||||
|
arg[len] = 0;
|
||||||
|
|
||||||
|
cmd_text = get_arg(&arg);
|
||||||
|
if (cmd_text) {
|
||||||
|
const struct command *cmd = find_command(cmd_text);
|
||||||
|
|
||||||
|
if (cmd)
|
||||||
|
return cmd->func(&arg);
|
||||||
|
|
||||||
|
fprintf(stderr, "unknown command: %s (try \"help\")\n",
|
||||||
|
cmd_text);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Command definitions
|
||||||
|
*/
|
||||||
|
|
||||||
#define REG_COLUMNS 4
|
#define REG_COLUMNS 4
|
||||||
#define REG_ROWS ((DEVICE_NUM_REGS + REG_COLUMNS - 1) / REG_COLUMNS)
|
#define REG_ROWS ((DEVICE_NUM_REGS + REG_COLUMNS - 1) / REG_COLUMNS)
|
||||||
|
|
||||||
|
@ -84,16 +131,6 @@ static void show_regs(u_int16_t *regs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct command {
|
|
||||||
const char *name;
|
|
||||||
int (*func)(char **arg);
|
|
||||||
const char *help;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct command all_commands[];
|
|
||||||
|
|
||||||
static int cmd_help(char **arg);
|
|
||||||
|
|
||||||
static int cmd_md(char **arg)
|
static int cmd_md(char **arg)
|
||||||
{
|
{
|
||||||
char *off_text = get_arg(arg);
|
char *off_text = get_arg(arg);
|
||||||
|
@ -272,10 +309,6 @@ static int cmd_dis(char **arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
|
||||||
* Hex dumper
|
|
||||||
*/
|
|
||||||
|
|
||||||
static FILE *hexout_file;
|
static FILE *hexout_file;
|
||||||
static u_int16_t hexout_addr;
|
static u_int16_t hexout_addr;
|
||||||
static u_int8_t hexout_buf[16];
|
static u_int8_t hexout_buf[16];
|
||||||
|
@ -391,8 +424,13 @@ static int cmd_hexout(char **arg)
|
||||||
off += count;
|
off += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
hexout_flush();
|
if (hexout_flush() < 0)
|
||||||
fclose(hexout_file);
|
goto fail;
|
||||||
|
if (fclose(hexout_file) < 0) {
|
||||||
|
perror("hexout: error on close");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -510,10 +548,6 @@ static int cmd_step(char **arg)
|
||||||
return cmd_regs(NULL);
|
return cmd_regs(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
|
||||||
* Flash image programming state machine.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static u_int8_t prog_buf[128];
|
static u_int8_t prog_buf[128];
|
||||||
static u_int16_t prog_addr;
|
static u_int16_t prog_addr;
|
||||||
static int prog_len;
|
static int prog_len;
|
||||||
|
@ -702,6 +736,103 @@ static int cmd_gdb(char **arg)
|
||||||
return gdb_server(msp430_dev, port);
|
return gdb_server(msp430_dev, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cmd_help(char **arg)
|
||||||
|
{
|
||||||
|
char *topic = get_arg(arg);
|
||||||
|
|
||||||
|
if (topic) {
|
||||||
|
const struct command *cmd = find_command(topic);
|
||||||
|
|
||||||
|
if (!cmd) {
|
||||||
|
fprintf(stderr, "help: unknown command: %s\n", topic);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs(cmd->help, stdout);
|
||||||
|
} else {
|
||||||
|
int i;
|
||||||
|
int max_len = 0;
|
||||||
|
int rows, cols;
|
||||||
|
int total = 0;
|
||||||
|
|
||||||
|
for (i = 0; all_commands[i].name; i++) {
|
||||||
|
int len = strlen(all_commands[i].name);
|
||||||
|
|
||||||
|
if (len > max_len)
|
||||||
|
max_len = len;
|
||||||
|
total++;
|
||||||
|
}
|
||||||
|
|
||||||
|
max_len += 2;
|
||||||
|
cols = 72 / max_len;
|
||||||
|
rows = (total + cols - 1) / cols;
|
||||||
|
|
||||||
|
printf("Available commands:\n");
|
||||||
|
for (i = 0; i < rows; i++) {
|
||||||
|
int j;
|
||||||
|
|
||||||
|
printf(" ");
|
||||||
|
for (j = 0; j < cols; j++) {
|
||||||
|
int k = j * rows + i;
|
||||||
|
const struct command *cmd = &all_commands[k];
|
||||||
|
|
||||||
|
if (k >= total)
|
||||||
|
break;
|
||||||
|
|
||||||
|
printf("%s", cmd->name);
|
||||||
|
for (k = strlen(cmd->name); k < max_len; k++)
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Type \"help <command>\" for more information.\n");
|
||||||
|
printf("Press Ctrl+D to quit.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_read(char **arg)
|
||||||
|
{
|
||||||
|
char *filename = get_arg(arg);
|
||||||
|
FILE *in;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
if (!filename) {
|
||||||
|
fprintf(stderr, "read: filename must be specified\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
in = fopen(filename, "r");
|
||||||
|
if (!in) {
|
||||||
|
fprintf(stderr, "read: can't open %s: %s\n",
|
||||||
|
filename, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (fgets(buf, sizeof(buf), in)) {
|
||||||
|
char *cmd = buf;
|
||||||
|
|
||||||
|
while (*cmd && isspace(*cmd))
|
||||||
|
cmd++;
|
||||||
|
|
||||||
|
if (*cmd == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (process_command(cmd) < 0) {
|
||||||
|
fprintf(stderr, "read: error processing %s\n",
|
||||||
|
filename);
|
||||||
|
fclose(in);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(in);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct command all_commands[] = {
|
static const struct command all_commands[] = {
|
||||||
{"=", cmd_eval,
|
{"=", cmd_eval,
|
||||||
"= <expression>\n"
|
"= <expression>\n"
|
||||||
|
@ -737,6 +868,9 @@ static const struct command all_commands[] = {
|
||||||
"prog <filename>\n"
|
"prog <filename>\n"
|
||||||
" Erase the device and flash the data contained in a binary file. This\n"
|
" Erase the device and flash the data contained in a binary file. This\n"
|
||||||
" command also loads symbols from the file, if available.\n"},
|
" command also loads symbols from the file, if available.\n"},
|
||||||
|
{"read", cmd_read,
|
||||||
|
"read <filename>\n"
|
||||||
|
" Read commands from a file and evaluate them.\n"},
|
||||||
{"regs", cmd_regs,
|
{"regs", cmd_regs,
|
||||||
"regs\n"
|
"regs\n"
|
||||||
" Read and display the current register contents.\n"},
|
" Read and display the current register contents.\n"},
|
||||||
|
@ -756,120 +890,9 @@ static const struct command all_commands[] = {
|
||||||
{"syms", cmd_syms,
|
{"syms", cmd_syms,
|
||||||
"syms <filename>\n"
|
"syms <filename>\n"
|
||||||
" Load symbols from the given file.\n"},
|
" Load symbols from the given file.\n"},
|
||||||
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct command *find_command(const char *name)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LEN(all_commands); i++)
|
|
||||||
if (!strcasecmp(name, all_commands[i].name))
|
|
||||||
return &all_commands[i];
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cmd_help(char **arg)
|
|
||||||
{
|
|
||||||
char *topic = get_arg(arg);
|
|
||||||
|
|
||||||
if (topic) {
|
|
||||||
const struct command *cmd = find_command(topic);
|
|
||||||
|
|
||||||
if (!cmd) {
|
|
||||||
fprintf(stderr, "help: unknown command: %s\n", topic);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fputs(cmd->help, stdout);
|
|
||||||
} else {
|
|
||||||
int i;
|
|
||||||
int max_len = 0;
|
|
||||||
int rows, cols;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LEN(all_commands); i++) {
|
|
||||||
int len = strlen(all_commands[i].name);
|
|
||||||
|
|
||||||
if (len > max_len)
|
|
||||||
max_len = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
max_len += 2;
|
|
||||||
cols = 72 / max_len;
|
|
||||||
rows = (ARRAY_LEN(all_commands) + cols - 1) / cols;
|
|
||||||
|
|
||||||
printf("Available commands:\n");
|
|
||||||
for (i = 0; i < rows; i++) {
|
|
||||||
int j;
|
|
||||||
|
|
||||||
printf(" ");
|
|
||||||
for (j = 0; j < cols; j++) {
|
|
||||||
int k = j * rows + i;
|
|
||||||
const struct command *cmd = &all_commands[k];
|
|
||||||
|
|
||||||
if (k >= ARRAY_LEN(all_commands))
|
|
||||||
break;
|
|
||||||
|
|
||||||
printf("%s", cmd->name);
|
|
||||||
for (k = strlen(cmd->name); k < max_len; k++)
|
|
||||||
printf(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Type \"help <command>\" for more information.\n");
|
|
||||||
printf("Press Ctrl+D to quit.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void process_command(char *arg)
|
|
||||||
{
|
|
||||||
const char *cmd_text;
|
|
||||||
|
|
||||||
cmd_text = get_arg(&arg);
|
|
||||||
if (cmd_text) {
|
|
||||||
const struct command *cmd = find_command(cmd_text);
|
|
||||||
|
|
||||||
if (cmd)
|
|
||||||
cmd->func(&arg);
|
|
||||||
else
|
|
||||||
fprintf(stderr, "unknown command: %s (try \"help\")\n",
|
|
||||||
cmd_text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void reader_loop(void)
|
|
||||||
{
|
|
||||||
printf("\n");
|
|
||||||
cmd_help(NULL);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
char buf[128];
|
|
||||||
int len;
|
|
||||||
|
|
||||||
printf("(mspdebug) ");
|
|
||||||
fflush(stdout);
|
|
||||||
if (!fgets(buf, sizeof(buf), stdin)) {
|
|
||||||
if (feof(stdin))
|
|
||||||
break;
|
|
||||||
printf("\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = strlen(buf);
|
|
||||||
while (len && isspace(buf[len - 1]))
|
|
||||||
len--;
|
|
||||||
buf[len] = 0;
|
|
||||||
|
|
||||||
process_command(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void usage(const char *progname)
|
static void usage(const char *progname)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@ -898,6 +921,29 @@ static void usage(const char *progname)
|
||||||
progname, progname, progname, progname);
|
progname, progname, progname, progname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void reader_loop(void)
|
||||||
|
{
|
||||||
|
printf("\n");
|
||||||
|
cmd_help(NULL);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
char buf[128];
|
||||||
|
|
||||||
|
printf("(mspdebug) ");
|
||||||
|
fflush(stdout);
|
||||||
|
if (!fgets(buf, sizeof(buf), stdin)) {
|
||||||
|
if (feof(stdin))
|
||||||
|
break;
|
||||||
|
printf("\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
process_command(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
#define MODE_RF2500 0x01
|
#define MODE_RF2500 0x01
|
||||||
#define MODE_UIF 0x02
|
#define MODE_UIF 0x02
|
||||||
#define MODE_UIF_BSL 0x04
|
#define MODE_UIF_BSL 0x04
|
||||||
|
|
|
@ -145,6 +145,11 @@ from the file into the symbol table (discarding any existing symbols),
|
||||||
if they are present.
|
if they are present.
|
||||||
|
|
||||||
The CPU is reset and halted before and after programming.
|
The CPU is reset and halted before and after programming.
|
||||||
|
.IP "read \fIfilename\fR"
|
||||||
|
Read commands from the given file, line by line and process each one.
|
||||||
|
Any lines whose first non-space character is \fB#\fR are ignored. If
|
||||||
|
an error occurs while processing a command, the rest of the file is not
|
||||||
|
processed.
|
||||||
.IP "regs"
|
.IP "regs"
|
||||||
Show the current value of all CPU registers in the device under test.
|
Show the current value of all CPU registers in the device under test.
|
||||||
.IP "reset"
|
.IP "reset"
|
||||||
|
|
Loading…
Reference in New Issue