Implemented read command.

This commit is contained in:
Daniel Beer 2010-03-23 15:31:58 +13:00
parent ef03cae7b2
commit f775e52fb6
2 changed files with 183 additions and 132 deletions

310
main.c
View File

@ -63,6 +63,53 @@ char *get_arg(char **text)
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_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)
{
char *off_text = get_arg(arg);
@ -272,10 +309,6 @@ static int cmd_dis(char **arg)
return 0;
}
/************************************************************************
* Hex dumper
*/
static FILE *hexout_file;
static u_int16_t hexout_addr;
static u_int8_t hexout_buf[16];
@ -391,8 +424,13 @@ static int cmd_hexout(char **arg)
off += count;
}
hexout_flush();
fclose(hexout_file);
if (hexout_flush() < 0)
goto fail;
if (fclose(hexout_file) < 0) {
perror("hexout: error on close");
return -1;
}
return 0;
fail:
@ -510,10 +548,6 @@ static int cmd_step(char **arg)
return cmd_regs(NULL);
}
/************************************************************************
* Flash image programming state machine.
*/
static u_int8_t prog_buf[128];
static u_int16_t prog_addr;
static int prog_len;
@ -702,6 +736,103 @@ static int cmd_gdb(char **arg)
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[] = {
{"=", cmd_eval,
"= <expression>\n"
@ -737,6 +868,9 @@ static const struct command all_commands[] = {
"prog <filename>\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"},
{"read", cmd_read,
"read <filename>\n"
" Read commands from a file and evaluate them.\n"},
{"regs", cmd_regs,
"regs\n"
" Read and display the current register contents.\n"},
@ -756,120 +890,9 @@ static const struct command all_commands[] = {
{"syms", cmd_syms,
"syms <filename>\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)
{
fprintf(stderr,
@ -898,6 +921,29 @@ static void usage(const char *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_UIF 0x02
#define MODE_UIF_BSL 0x04

View File

@ -145,6 +145,11 @@ from the file into the symbol table (discarding any existing symbols),
if they are present.
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"
Show the current value of all CPU registers in the device under test.
.IP "reset"