#include "simavr/simavr.h"
void printHelp () {
- printf("simuc V0.0.3 (%s,%s)\n", __DATE__, __TIME__);
+ printf("simuc V0.0.4 (%s,%s)\n", __DATE__, __TIME__);
printf("usage: simuc [options] elf-file [elf-file ...]\n\n");
printf(" available options (you can use file .simucinit instead):\n");
printf(" --port ... listining port for gdb (default 1234)\n");
printf(" --vcc ... set voltage VCC in Volt\n");
printf(" --avcc ... set voltage AVCC in Volt\n");
printf(" --aref ... set voltage AREF in Volt\n\n");
+ printf(" --log ... set simavr log level\n");
+ printf(" (none, output, error, warning, trace or debug)\n");
printf(" example:\n");
printf(" simuc --mmcu atmega328p --frequency 16000000 --pc 0x7000 a.out\n");
printf(" simuc --board arduino a.out\n\n");
int main (int argc, char **argv) {
+ struct SimUcInit *simUcInit = NULL;
struct StartParameters params;
memset((void *)¶ms, 0, sizeof(params));
params.filenames = NULL;
params.frequency = -1;
params.mmcu = NULL;
params.board = BoardUnknown;
+ params.pc = -1;
params.vcc = -1;
params.avcc = -1;
params.aref = -1;
params.nosync = 0;
- struct SimUcInit *simUcInit = NULL;
+ params.log = LOG_NONE;
if (argc <= 1) {
const char *fileName = ".simucinit";
if (strcmp(argv[i], "--board") == 0 && argc >= (i + 1)) {
i++;
continue;
- } else if (strcmp(argv[i], "--mmcu") == 0) {
+ } else if (strcmp(argv[i], "--mmcu") == 0 && argc >= (i + 1)) {
params.mmcu = argv[++i];
- } else if (strcmp(argv[i], "--port") == 0) {
+ } else if (strcmp(argv[i], "--port") == 0 && argc >= (i + 1)) {
sscanf(argv[++i], "%d", ¶ms.gdbPort);
- } else if (strcmp(argv[i], "--frequency") == 0) {
+ } else if (strcmp(argv[i], "--frequency") == 0 && argc >= (i + 1)) {
sscanf(argv[++i], "%" PRIu64, ¶ms.frequency);
- } else if (strcmp(argv[i], "--pc") == 0) {
+ } else if (strcmp(argv[i], "--pc") == 0 && argc >= (i + 1)) {
i++;
if (argv[i][0] == '0' && argv[i][1] == 'x') {
sscanf(&argv[i][2], "%x", ¶ms.pc);
} else {
sscanf(argv[++i], "%d", ¶ms.pc);
}
- } else if (strcmp(argv[i], "--vcc") == 0) {
+ } else if (strcmp(argv[i], "--vcc") == 0 && argc >= (i + 1)) {
sscanf(argv[++i], "%d", ¶ms.vcc);
- } else if (strcmp(argv[i], "--avcc") == 0) {
+ } else if (strcmp(argv[i], "--avcc") == 0 && argc >= (i + 1)) {
sscanf(argv[++i], "%d", ¶ms.avcc);
- } else if (strcmp(argv[i], "--aref") == 0) {
+ } else if (strcmp(argv[i], "--aref") == 0 && argc >= (i + 1)) {
sscanf(argv[++i], "%d", ¶ms.aref);
- } else if (strcmp(argv[i], "--nosync") == 0) {
+ } else if (strcmp(argv[i], "--nosync") == 0 && argc >= (i + 1)) {
params.nosync = 1;
+ } else if (strcmp(argv[i], "--log") == 0 && argc >= (i + 1)) {
+ params.nosync = 1;
+ i++;
+ if (strcmp("none", argv[i]) == 0) {
+ params.log = LOG_NONE;
+ } else if (strcmp("output", argv[i]) == 0) {
+ params.log = LOG_OUTPUT;
+ } else if (strcmp("error", argv[i]) == 0) {
+ params.log = LOG_ERROR;
+ } else if (strcmp("warning", argv[i]) == 0) {
+ params.log = LOG_WARNING;
+ } else if (strcmp("trace", argv[i]) == 0) {
+ params.log = LOG_TRACE;
+ } else if (strcmp("debug", argv[i]) == 0) {
+ params.log = LOG_DEBUG;
+ } else {
+ fprintf(stderr, "ERROR: invalid option %s, use --help to show usage\n\n", argv[i - 1]);
+ return 1;
+ }
+
} else {
fprintf(stderr, "ERROR: invalid option %s, use --help to show usage\n\n", argv[i]);
return 1;
for (int i = 0; params->filenames[i] != NULL; i++) {
std::string filename = std::string(params->filenames[i]);
printf("firmware file \"%s\"\n", params->filenames[i]);
-
if (firmware == NULL || elf_read_firmware(filename.c_str(), firmware) != 0) {
throw std::logic_error(error(AT, "elf_read_firmware() from %s fails", filename.c_str()));
}
+ printf("--------------------------------------------------------------------\n");
}
if (params->mmcu != NULL) {
strncpy(firmware->mmcu, params->mmcu, sizeof(firmware->mmcu));
} else {
avr->gdb_port = 1234;
}
- printf("init with gdb-port=%d, mmcu=%s, f=%u, vcc=%d, avcc=%d, aref=%d, pc=0x%04x\n",
- avr->gdb_port, firmware->mmcu, firmware->frequency, firmware->vcc, firmware->avcc, firmware->aref, params->pc < 0 ? 0 : params->pc);
+ if (params->log >= LOG_TRACE) {
+ printf("init with gdb-port=%d, mmcu=%s, f=%u, vcc=%d, avcc=%d, aref=%d, pc=0x%04x\n",
+ avr->gdb_port, firmware->mmcu, firmware->frequency, firmware->vcc, firmware->avcc, firmware->aref, params->pc < 0 ? 0 : params->pc);
+ }
status.freqHz = firmware->frequency;
- if (avr_init(avr) != 0) {
- throw std::logic_error(error(AT, "avr_init() fails"));
+ // firmware->eeprom = (uint8_t *)malloc(1024);
+ // for (int i = 0; i < 1024; i++) {
+ // firmware->eeprom[i] = 0xff;
+ // }
+ // firmware->eeprom[0] = 0x01;
+ // firmware->eesize = 1024;
+
+ // fuse values set in section .fuse (ORIGIN = 0x820000)
+ // lock bit values set in section .lock (ORIGIN = 0x830000)
+ printf("Fuse- and Lockbits:");
+ if (firmware->fusesize == 0 && firmware->lockbits == NULL) {
+ printf(" not defined (neither section .eeprom nor section .lock found");
+ } else {
+ if (firmware->fusesize >= 0) {
+ for (uint32_t i = 0; i < firmware->fusesize; i++) {
+ switch (i) {
+ case 0: printf(" LFUSE"); break;
+ case 1: printf(" HFUSE"); break;
+ case 2: printf(" EFUSE"); break;
+ default: printf(" ?="); break;
+ }
+ printf("=0x%02x", firmware->fuse[i]);
+ }
+ }
+ if (firmware->lockbits != NULL) {
+ printf(" LOCK=0x%02x", *firmware->lockbits);
+ }
+ printf("\n");
+ if (firmware->fusesize >= 2) {
+ if (strcmp("atmega324p", firmware->mmcu) == 0 ||
+ strcmp("atmega328p", firmware->mmcu) == 0 ||
+ strcmp("atmega16", firmware->mmcu) == 0) {
+
+ uint8_t bootsz = ~(firmware->fuse[1] >> 1) & 0x03;
+ uint8_t bootrst = ~(firmware->fuse[1]) & 0x01;
+ if (bootrst && startParameters->pc < 0) {
+ switch (bootsz) {
+ case 0: avr->reset_pc = 0x7000; break;
+ case 1: avr->reset_pc = 0x7800; break;
+ case 2: avr->reset_pc = 0x7c00; break;
+ case 3: avr->reset_pc = 0x7e00; break;
+ }
+ printf("reset on 0x%04x (HFUSE-> BOOTRST=%d, BOOTSZ=%d%d)\n", avr->reset_pc, bootrst, bootsz & 0x02, bootsz & 0x01);
+ }
+ } else {
+ printf("WARNING: cannot decode FUSE (%s not supported)", firmware->mmcu);
+ }
+ }
+ }
+
+ printf("EEPROM: ");
+ if (firmware->eesize == 0) {
+ printf("not defined (no section .eeprom found)");
+ } else {
+ printf("%d bytes defined (", firmware->eesize);
+ for (uint32_t i = 0; i < firmware->eesize; i++) {
+ if (i > 6) {
+ printf(" ...");
+ break;
+ } else if (i > 0) {
+ printf(" ");
+ }
+ printf("0x%02x", firmware->eeprom[i]);
+ }
+ printf(")\n");
+ }
+
+ if (params->pc >= 0) {
+ avr->reset_pc = params->pc;
+ printf("reset on 0x%04x (option --pc)\n", avr->reset_pc);
}
-
- firmware->eeprom = (uint8_t *)malloc(1024);
- for (int i = 0; i < 1024; i++) {
- firmware->eeprom[i] = 0xff;
+ avr->log = params->log;
+ printf("simavr log level: ");
+ switch (avr->log) {
+ case LOG_NONE: printf("NONE\n"); break;
+ case LOG_OUTPUT: printf("OUTPUT\n"); break;
+ case LOG_ERROR: printf("ERROR\n"); break;
+ case LOG_WARNING: printf("WARNING\n"); break;
+ case LOG_TRACE: printf("TRACE\n"); break;
+ case LOG_DEBUG: printf("DEBUG\n"); break;
+ default: printf(" ? (=%d)\n", avr->log); break;
+ }
+
+ if (avr_init(avr) != 0) {
+ throw std::logic_error(error(AT, "avr_init() fails"));
}
- firmware->eeprom[0] = 0xf0;
- firmware->eesize = 1024;
avr_load_firmware(avr, firmware);
status.state = StateLoaded;
- avr->fuse[AVR_FUSE_LOW] = 0xe7;
- avr->fuse[AVR_FUSE_HIGH] = 0xd8;
- avr->fuse[AVR_FUSE_EXT] = 0xff;
- avr->lockbits = 0xff;
-
- avr->gdb_port = 1234;
+ avr->gdb_port = params->gdbPort > 0 ? params->gdbPort : 1234;
avr_gdb_init(avr);
- if (params->pc >= 0) {
- avr->pc = params->pc;
- }
pthread_mutex_unlock(&lock);