4 Copyright 2008, 2010 Michel Pollet <buserror@gmail.com>
6 This file is part of simavr.
8 simavr is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 simavr is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with simavr. If not, see <http://www.gnu.org/licenses/>.
33 #include "sim_core_decl.h"
35 void display_usage(char * app)
37 printf("Usage: %s [-t] [-g] [-v] [-m <device>] [-f <frequency>] firmware\n", app);
38 printf(" -t: Run full scale decoder trace\n"
39 " -g: Listen for gdb connection on port 1234\n"
40 " -ff: Load next .hex file as flash\n"
41 " -ee: Load next .hex file as eeprom\n"
42 " -v: Raise verbosity level (can be passed more than once)\n"
43 " Supported AVR cores:\n");
44 for (int i = 0; avr_kind[i]; i++) {
46 for (int ti = 0; ti < 4 && avr_kind[i]->names[ti]; ti++)
47 printf("%s ", avr_kind[i]->names[ti]);
59 printf("signal caught, simavr terminating\n");
65 int main(int argc, char *argv[])
67 elf_firmware_t f = {{0}};
73 uint32_t loadBase = AVR_SEGMENT_OFFSET_FLASH;
74 int trace_vectors[8] = {0};
75 int trace_vectors_count = 0;
78 display_usage(basename(argv[0]));
80 for (int pi = 1; pi < argc; pi++) {
81 if (!strcmp(argv[pi], "-h") || !strcmp(argv[pi], "-help")) {
82 display_usage(basename(argv[0]));
83 } else if (!strcmp(argv[pi], "-m") || !strcmp(argv[pi], "-mcu")) {
85 strcpy(name, argv[++pi]);
87 display_usage(basename(argv[0]));
88 } else if (!strcmp(argv[pi], "-f") || !strcmp(argv[pi], "-freq")) {
90 f_cpu = atoi(argv[++pi]);
92 display_usage(basename(argv[0]));
93 } else if (!strcmp(argv[pi], "-t") || !strcmp(argv[pi], "-trace")) {
95 } else if (!strcmp(argv[pi], "-ti")) {
97 trace_vectors[trace_vectors_count++] = atoi(argv[++pi]);
98 } else if (!strcmp(argv[pi], "-g") || !strcmp(argv[pi], "-gdb")) {
100 } else if (!strcmp(argv[pi], "-v")) {
102 } else if (!strcmp(argv[pi], "-ee")) {
103 loadBase = AVR_SEGMENT_OFFSET_EEPROM;
104 } else if (!strcmp(argv[pi], "-ff")) {
105 loadBase = AVR_SEGMENT_OFFSET_FLASH;
106 } else if (argv[pi][0] != '-') {
107 char * filename = argv[pi];
108 char * suffix = strrchr(filename, '.');
109 if (suffix && !strcasecmp(suffix, ".hex")) {
110 if (!name[0] || !f_cpu) {
111 fprintf(stderr, "%s: -mcu and -freq are mandatory to load .hex files\n", argv[0]);
114 ihex_chunk_p chunk = NULL;
115 int cnt = read_ihex_chunks(filename, &chunk);
117 fprintf(stderr, "%s: Unable to load IHEX file %s\n",
121 printf("Loaded %d section of ihex\n", cnt);
122 for (int ci = 0; ci < cnt; ci++) {
123 if (chunk[ci].baseaddr < (1*1024*1024)) {
124 f.flash = chunk[ci].data;
125 f.flashsize = chunk[ci].size;
126 f.flashbase = chunk[ci].baseaddr;
127 printf("Load HEX flash %08x, %d\n", f.flashbase, f.flashsize);
128 } else if (chunk[ci].baseaddr >= AVR_SEGMENT_OFFSET_EEPROM ||
129 chunk[ci].baseaddr + loadBase >= AVR_SEGMENT_OFFSET_EEPROM) {
131 f.eeprom = chunk[ci].data;
132 f.eesize = chunk[ci].size;
133 printf("Load HEX eeprom %08x, %d\n", chunk[ci].baseaddr, f.eesize);
137 if (elf_read_firmware(filename, &f) == -1) {
138 fprintf(stderr, "%s: Unable to load firmware from file %s\n",
147 strcpy(f.mmcu, name);
151 avr = avr_make_mcu_by_name(f.mmcu);
153 fprintf(stderr, "%s: AVR '%s' not known\n", argv[0], f.mmcu);
157 avr_load_firmware(avr, &f);
159 printf("Attempted to load a bootloader at %04x\n", f.flashbase);
160 avr->pc = f.flashbase;
162 avr->log = (log > LOG_TRACE ? LOG_TRACE : log);
164 for (int ti = 0; ti < trace_vectors_count; ti++)
165 if (avr->interrupts.vector[trace_vectors[ti]])
166 avr->interrupts.vector[trace_vectors[ti]]->trace = 1;
168 // even if not setup at startup, activate gdb if crashing
169 avr->gdb_port = 1234;
171 avr->state = cpu_Stopped;
175 signal(SIGINT, sig_int);
176 signal(SIGTERM, sig_int);
179 int state = avr_run(avr);
180 if ( state == cpu_Done || state == cpu_Crashed)