00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include <config.h>
00027
00028
#include <stdio.h>
00029
#include <stdlib.h>
00030
#include <string.h>
00031
#include <errno.h>
00032
00033
#include "avrerror.h"
00034
#include "avrmalloc.h"
00035
#include "avrclass.h"
00036
#include "utils.h"
00037
#include "callback.h"
00038
#include "op_names.h"
00039
00040
#include "storage.h"
00041
#include "flash.h"
00042
00043
#include "vdevs.h"
00044
#include "memory.h"
00045
#include "stack.h"
00046
#include "register.h"
00047
#include "sram.h"
00048
#include "eeprom.h"
00049
#include "timers.h"
00050
#include "ports.h"
00051
00052
#include "avrcore.h"
00053
00054
#include "devsupp.h"
00055
#include "display.h"
00056
00057
#include "gdb.h"
00058
#include "gnu_getopt.h"
00059
00060
00061
00062
00063
00064
00065
00066
static char *global_device_type = NULL;
00067
00068
static int global_eeprom_image_type = FFMT_BIN;
00069
static char *global_eeprom_image_file = NULL;
00070
00071
static int global_flash_image_type = FFMT_BIN;
00072
static char *global_flash_image_file = NULL;
00073
00074
static int global_gdbserver_mode = 0;
00075
static int global_gdbserver_port = 1212;
00076
static int global_gdb_debug = 0;
00077
00078
static char *global_disp_prog = NULL;
00079
static int global_disp_without_xterm = 0;
00080
00081
static int global_dump_core = 0;
00082
00083
static int global_clock_freq = 8000000;
00084
00085
00086
00087
00088
#define LEN_BREAK_LIST 50
00089
static int global_break_count = 0;
00090
static int global_break_list[LEN_BREAK_LIST];
00091
00092
static AvrCore *global_core = NULL;
00093
00094
00095
static GdbComm_T global_gdb_comm[1] = {{
00096 .user_data = NULL,
00097
00098 .read_reg = (CommFuncReadReg) avr_core_gpwr_get,
00099 .write_reg = (CommFuncWriteReg) avr_core_gpwr_set,
00100
00101 .read_sreg = (CommFuncReadSREG) avr_core_sreg_get,
00102 .write_sreg = (CommFuncWriteSREG) avr_core_sreg_set,
00103
00104 .read_pc = (CommFuncReadPC) avr_core_PC_get,
00105 .write_pc = (CommFuncWritePC) avr_core_PC_set,
00106 .max_pc = (CommFuncMaxPC) avr_core_PC_max,
00107
00108 .read_sram = (CommFuncReadSRAM) avr_core_mem_read,
00109 .write_sram = (CommFuncWriteSRAM) avr_core_mem_write,
00110
00111 .read_flash = (CommFuncReadFlash) avr_core_flash_read,
00112 .write_flash = (CommFuncWriteFlash) avr_core_flash_write,
00113 .write_flash_lo8 = (CommFuncWriteFlashLo8) avr_core_flash_write_lo8,
00114 .write_flash_hi8 = (CommFuncWriteFlashHi8) avr_core_flash_write_hi8,
00115
00116 .insert_break = (CommFuncInsertBreak)
avr_core_insert_breakpoint,
00117 .remove_break = (CommFuncRemoveBreak)
avr_core_remove_breakpoint,
00118 .enable_breakpts = (CommFuncEnableBrkpts)
avr_core_enable_breakpoints,
00119 .disable_breakpts = (CommFuncDisableBrkpts)
avr_core_disable_breakpoints,
00120
00121 .step = (CommFuncStep)
avr_core_step,
00122 .reset = (CommFuncReset)
avr_core_reset,
00123
00124 .io_fetch = (CommFuncIORegFetch) avr_core_io_fetch,
00125
00126 .irq_raise = (CommFuncIrqRaise)
avr_core_irq_raise,
00127 }};
00128
00129
static char *usage_fmt_str =
00130
"\nUsage: %s [OPTIONS]... [flash_image]\n" "\n"
00131
"Simulate an avr device. The optional flash_image file is loaded\n"
00132
"into the flash program memory space of the device.\n" "\n" "Options:\n"
00133
" -h, --help : Show this message\n"
00134
" -D, --debug : Debug instruction output\n"
00135
" -v, --version : Print out the version number and exit\n"
00136
" -g, --gdbserver : Run as a gdbserver process\n"
00137
" -G, --gdb-debug : Print out debug messages for gdbserver\n"
00138
" -p, --port <port> : Listen for gdb connection on TCP port\n"
00139
" -d, --device <dev> : Specify device type\n"
00140
" -e, --eeprom-image <img> : Specify an eeprom image file\n"
00141
" -E, --eeprom-type <type> : Specify the type of the eeprom image file\n"
00142
" -F, --flash-type <type> : Specify the type of the flash image file\n"
00143
" -L, --list-devices : Print supported devices to stdout and exit\n"
00144
" -P, --disp-prog <prog> : Display register and memory info with prog\n"
00145
" -X, --without-xterm : Don't start disp prog in an xterm\n"
00146
" -C, --core-dump : Dump a core memory image to file on exit\n"
00147
" -c, --clock-freq <freq> : Set the simulated mcu clock freqency (in Hz)\n"
00148
" -B, --breakpoint <addr> : Set a breakpoint (address is a byte address)\n"
00149
"\n" "If the image file types for eeprom or flash images are not given,\n"
00150
"the default file type is binary.\n" "\n"
00151
"If you wish to run the simulator in gdbserver mode, you do not\n"
00152
"have to specify a flash-image file since the program can be loaded\n"
00153
"from gdb via the `load` command.\n" "\n"
00154
"If '--port' option is given, and '--gdbserver' is not, port is ignored\n"
00155
"\n" "If running in gdbserver mode and port is not specified, a default\n"
00156
"port of 1212 is used.\n" "\n"
00157
"If using the '--breakpoint' option, note the simulator will terminate when\n"
00158
"the address is hit if you are not running in gdbserver mode. This feature\n"
00159
"not intended for use in gdbserver mode. It is really intended for testing\n"
00160
"the simulator itself, but may be useful for testing avr programs too.\n"
00161
"\n" "Currently available device types:\n";
00162
00163
00164
00165
00166
00167
00168
static void
00169 usage (
char *prog)
00170 {
00171 fprintf (stdout, usage_fmt_str, prog);
00172
dev_supp_list_devices (stdout);
00173 fprintf (stdout,
"\n");
00174
00175 exit (1);
00176 }
00177
00178
00179
static struct option long_opts[] = {
00180
00181 {
"help", 0, 0,
'h' },
00182 {
"debug", 0, 0,
'D' },
00183 {
"version", 0, 0,
'v' },
00184 {
"gdbserver", 0, 0,
'g' },
00185 {
"gdb-debug", 0, 0,
'G' },
00186 {
"port", 1, 0,
'p' },
00187 {
"device", 1, 0,
'd' },
00188 {
"eeprom-type", 1, 0,
'E' },
00189 {
"eeprom-image", 1, 0,
'e' },
00190 {
"flash-type", 1, 0,
'F' },
00191 {
"list-devices", 0, 0,
'L' },
00192 {
"disp-prog", 1, 0,
'P' },
00193 {
"without-xterm", 1, 0,
'X' },
00194 {
"core-dump", 0, 0,
'C' },
00195 {
"clock-freq", 1, 0,
'c' },
00196 {
"breakpoint", 1, 0,
'B' },
00197 { NULL, 0, 0, 0 }
00198 };
00199
00200
00201
00202
00203
00204
static void
00205 parse_cmd_line (
int argc,
char **argv)
00206 {
00207
int c;
00208
char *prog = argv[0];
00209
char *basename;
00210
int option_index;
00211
char dummy_char;
00212
int break_addr;
00213
00214 opterr = 0;
00215
00216
while (1)
00217 {
00218 c = getopt_long (argc, argv,
"hgGvDLd:e:E:F:p:P:XCc:B:", long_opts,
00219 &option_index);
00220
if (c == -1)
00221
break;
00222
00223
switch (c)
00224 {
00225
case 'h':
00226
case '?':
00227 usage (prog);
00228
case 'g':
00229 global_gdbserver_mode = 1;
00230
break;
00231
case 'G':
00232 global_gdb_debug = 1;
00233
break;
00234
case 'p':
00235 global_gdbserver_port = atoi (optarg);
00236
break;
00237
case 'v':
00238 printf (
"\n%s version %s\n", PACKAGE, VERSION);
00239 printf (
"Copyright 2001, 2002, 2003 Theodore A. Roth.\n");
00240 printf (
"\n%s is free software, covered by the GNU General "
00241
"Public License,\n", PACKAGE);
00242 printf (
"and you are welcome to change it and/or distribute "
00243
"copies of it under\n");
00244 printf (
"the conditions of the GNU General Public License."
00245
"\n\n");
00246 exit (0);
00247
case 'D':
00248
global_debug_inst_output = 1;
00249
break;
00250
case 'd':
00251 global_device_type = optarg;
00252
break;
00253
case 'e':
00254 global_eeprom_image_file =
avr_strdup (optarg);
00255
break;
00256
case 'E':
00257
break;
00258 global_eeprom_image_type =
str2ffmt (optarg);
00259
case 'F':
00260 global_flash_image_type =
str2ffmt (optarg);
00261
break;
00262
case 'L':
00263
dev_supp_list_devices (stdout);
00264 exit (0);
00265
case 'P':
00266 global_disp_prog =
avr_strdup (optarg);
00267
break;
00268
case 'X':
00269 global_disp_without_xterm = 1;
00270
break;
00271
case 'C':
00272 global_dump_core = 1;
00273
break;
00274
case 'c':
00275
if (sscanf (optarg,
"%d%c", &global_clock_freq, &dummy_char)
00276 != 1)
00277 {
00278
avr_error (
"Invalid clock value: %s", optarg);
00279 }
00280
avr_warning (
"Clock frequency option is not yet "
00281
"implemented.\n");
00282
break;
00283
case 'B':
00284
if (sscanf (optarg,
"%i%c", &break_addr, &dummy_char) != 1)
00285 {
00286
avr_error (
"Ignoring invalid break addres: %s", optarg);
00287 }
00288
00289
if (global_break_count < LEN_BREAK_LIST)
00290 {
00291 global_break_list[global_break_count] = break_addr;
00292 global_break_count++;
00293 }
00294
else
00295 {
00296
avr_warning (
"Too many break points: igoring %s\n",
00297 optarg);
00298 }
00299
00300
break;
00301
default:
00302
avr_error (
"getop() did something screwey");
00303 }
00304 }
00305
00306
if ((optind + 1) == argc)
00307 global_flash_image_file = argv[optind];
00308
else if (optind != argc)
00309 usage (prog);
00310
00311
00312
00313
00314
if ((global_eeprom_image_type != FFMT_BIN)
00315 || (global_flash_image_type != FFMT_BIN))
00316 {
00317 fprintf (stderr,
00318
"Only the bin file format is currently "
00319
"implemented. Sorry.\n");
00320 exit (1);
00321 }
00322
00323
00324
00325
00326
if (global_device_type == NULL)
00327 {
00328
00329 basename = strrchr (prog,
'/');
00330
if (basename == NULL)
00331
00332 global_device_type = prog;
00333
else
00334 global_device_type = ++basename;
00335 }
00336 }
00337
00338 uint8_t
00339 ext_port_rd (
int addr)
00340 {
00341
int data;
00342
char line[80];
00343
00344
while (1)
00345 {
00346 fprintf (stderr,
"\nEnter a byte of data to read into 0x%04x: ",
00347 addr);
00348
00349
00350
if (fgets (line,
sizeof (line), stdin) == NULL)
00351
continue;
00352
00353
00354
if (sscanf (line,
"%i\n", &data) != 1)
00355
continue;
00356
00357
break;
00358 }
00359
return (uint8_t) (data & 0xff);
00360 }
00361
00362
void
00363 ext_port_wr (
int addr, uint8_t val)
00364 {
00365 fprintf (stderr,
"writing 0x%02x to 0x%04x\n", val, addr);
00366 }
00367
00368
00369
00370
void
00371 atexit_cleanup (
void)
00372 {
00373 FILE *dump;
00374
00375
if (global_dump_core)
00376 {
00377
if ((dump = fopen (
"core_avr_dump.core",
"w")) == NULL)
00378 {
00379
00380 fprintf (stderr,
"fopen failed: core_avr_dump.core: %s\n",
00381 strerror (errno));
00382 }
00383
else
00384 {
00385
avr_core_dump_core (global_core, dump);
00386 fclose (dump);
00387 }
00388 }
00389
00390
class_unref ((AvrClass *)global_core);
00391 }
00392
00393
00394
00395
00396
00397
int
00398 main (
int argc,
char **argv)
00399 {
00400
int i;
00401
int flash_sz = 0, sram_sz = 0, eeprom_sz = 0;
00402
int sram_start = 0;
00403
00404 parse_cmd_line (argc, argv);
00405
00406 global_core =
dev_supp_create_core (global_device_type);
00407
if (global_core == NULL)
00408 {
00409
avr_warning (
"Device not supported: %s\n", global_device_type);
00410 exit (1);
00411 }
00412
00413
avr_message (
"Simulating clock frequency of %d Hz\n", global_clock_freq);
00414
00415
avr_core_get_sizes (global_core, &flash_sz, &sram_sz, &sram_start,
00416 &eeprom_sz);
00417
display_open (global_disp_prog, global_disp_without_xterm, flash_sz,
00418 sram_sz, sram_start, eeprom_sz);
00419
avr_core_io_display_names (global_core);
00420
00421
00422
if (atexit (atexit_cleanup))
00423
avr_error (
"Failed to install exit handler");
00424
00425
00426
avr_core_add_ext_rd_wr (global_core, PORT_B, ext_port_rd, ext_port_wr);
00427
avr_core_add_ext_rd_wr (global_core, PORT_C, ext_port_rd, ext_port_wr);
00428
avr_core_add_ext_rd_wr (global_core, PORT_D, ext_port_rd, ext_port_wr);
00429
00430
00431
if (global_flash_image_file)
00432
avr_core_load_program (global_core, global_flash_image_file,
00433 global_flash_image_type);
00434
00435
00436
if (global_eeprom_image_file)
00437
avr_core_load_eeprom (global_core, global_eeprom_image_file,
00438 global_eeprom_image_type);
00439
00440
for (i = 0; i < global_break_count; i++)
00441 {
00442
00443
00444
00445
00446
avr_message (
"Setting breakpoint at 0x%x.\n", global_break_list[i]);
00447
avr_core_insert_breakpoint (global_core, global_break_list[i] / 2);
00448 }
00449
00450
if (global_gdbserver_mode == 1)
00451 {
00452 global_gdb_comm->user_data = global_core;
00453
gdb_interact (global_gdb_comm, global_gdbserver_port,
00454 global_gdb_debug);
00455 }
00456
else
00457 {
00458
if (global_flash_image_file)
00459
00460
avr_core_run (global_core);
00461
else
00462 fprintf (stderr,
"No program was specified to be run.\n");
00463 }
00464
00465
display_close ();
00466
00467 exit (0);
00468
return 0;
00469 }