#include <stdio.h>
#include <unistd.h>
#include <string.h>
+#include <string>
+#include <regex>
#include "sim/sim.h"
#include "simavr/simavr.h"
void printHelp () {
- printf("simuc V0.0.2 (%s,%s)\n", __DATE__, __TIME__);
- printf("usage: simuc [options] elf-file\n\n");
- printf(" available options:\n");
+ printf("simuc V0.0.3 (%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(" --board ... set board (arduino, sure, evws1)\n");
- printf(" --sync sync elapsed µC-time with real time\n\n");
+ printf(" --nosync do not sync elapsed µC-time with real time\n\n");
printf(" --mmcu ... set target device type\n");
printf(" --frequency ... set target frequency in Hz\n");
printf(" --pc ... set start program counter (default is 0)\n");
printf(" simuc --board arduino a.out\n\n");
}
+struct SimUcInit {
+ int argc;
+ char *argv[];
+};
+
+
int main (int argc, char **argv) {
struct StartParameters params;
memset((void *)¶ms, 0, sizeof(params));
- params.filename = NULL;
+ params.filenames = NULL;
params.gdbPort = -1;
params.frequency = -1;
params.mmcu = NULL;
params.vcc = -1;
params.avcc = -1;
params.aref = -1;
-
+ params.nosync = 0;
+ struct SimUcInit *simUcInit = NULL;
if (argc <= 1) {
- printHelp();
- return 1;
+ const char *fileName = ".simucinit";
+ FILE *fp = fopen(fileName, "r");
+ if (fp == NULL) {
+ printHelp();
+ return 1;
+ }
+ char * line = NULL;
+ size_t len = 0;
+ ssize_t read;
+ simUcInit = (struct SimUcInit *)malloc(sizeof(struct SimUcInit));
+ if (!simUcInit) {
+ fprintf(stderr, "ERROR: out of memory?");
+ return 1;
+ }
+
+ simUcInit->argc = 0;
+ simUcInit->argv[simUcInit->argc] = (char *)malloc(strlen(fileName) + 1);
+ strcpy(simUcInit->argv[simUcInit->argc], ".simucinit");
+ simUcInit->argc++;
+
+ while ((read = getline(&line, &len, fp)) != -1) {
+ std::string sLine = std::string(line);
+ std::string sTrimmed = std::regex_replace(sLine, std::regex("(^[ \\t]+)|([ \\t]*\\n$)"), "");
+ if (sTrimmed.length() == 0 || sTrimmed.at(0) == '#') {
+ continue;
+ }
+ std::regex e("\\s+");
+ std::regex_token_iterator<std::string::iterator> i(sTrimmed.begin(), sTrimmed.end(), e, -1);
+ std::regex_token_iterator<std::string::iterator> end;
+ while (i != end) {
+ std::string s = (*i++).str();
+ simUcInit = (struct SimUcInit *)realloc(simUcInit, sizeof(struct SimUcInit) + sizeof(char *) * (simUcInit->argc + 1));
+ simUcInit->argv[simUcInit->argc] = (char *)malloc(s.length() + 1);
+ strcpy(simUcInit->argv[simUcInit->argc], s.c_str());
+ simUcInit->argc++;
+ }
+ }
+ fclose(fp);
}
+ if (simUcInit != NULL && simUcInit->argc > 0) {
+ argc = simUcInit->argc;
+ argv = simUcInit->argv;
+ }
+
+ int filenameIndex = -1;
for (int i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
if (strcmp(argv[i], "--help") == 0) {
fprintf(stderr, "ERROR: invalid board %s, use --help to show usage\n\n", argv[i]);
return 1;
}
+ }
+ }
+ }
+ for (int i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ if (strcmp(argv[i], "--board") == 0 && argc >= (i + 1)) {
+ i++;
+ continue;
} else if (strcmp(argv[i], "--mmcu") == 0) {
params.mmcu = argv[++i];
} else if (strcmp(argv[i], "--port") == 0) {
sscanf(argv[++i], "%d", ¶ms.avcc);
} else if (strcmp(argv[i], "--aref") == 0) {
sscanf(argv[++i], "%d", ¶ms.aref);
+ } else if (strcmp(argv[i], "--nosync") == 0) {
+ params.nosync = 1;
} else {
fprintf(stderr, "ERROR: invalid option %s, use --help to show usage\n\n", argv[i]);
return 1;
}
continue;
}
- params.filename = argv[i];
- break;
+ params.filenames = (const char **)realloc(params.filenames, sizeof(params.filenames[0]) * (++filenameIndex + 2));
+ params.filenames[filenameIndex] = argv[i];
+ params.filenames[filenameIndex + 1] = NULL;
}
- if (params.filename == NULL) {
+ if (params.filenames == NULL || params.filenames[0] == NULL) {
printf("ERROR: missing target elf file, use --help to show usage\n\n");
return 1;
}
+ printf("--------------------------------------------------------------------\n");
init(¶ms);
if (errno == 1) {
return 1;
}
- printf("available commands: i (interrupt), c (continue), s (stack)\n");
- printf("----------------------------------------------------------\n");
+ printf("--------------------------------------------------------------------\n");
+ printf("available commands: i (interrupt), c (continue), s (stack), q (quit)\n");
+ printf("--------------------------------------------------------------------\n");
printf("init done - press key to start\n");
getchar();
- printf("----------------------------------------------------------\n");
+ printf("--------------------------------------------------------------------\n");
start();
// int cnt = 0;
char *line = NULL;
size_t size = 0;
- while (1) {
+ int quit = 0;
+
+ while (!quit) {
// struct SimAvrEvent ev = waitForEvent();
// printf("%10.03lf: event %s (%d) received \r", ev.cycle / 20E6, eventText((EnumSimEvent)ev.event), ev.event);
// fflush(stdout);
// }
if (getline(&line, &size, stdin) > 0) {
- const char *commands[] = { "interrupt", "continue", "stack" };
+ const char *commands[] = { "quit", "interrupt", "continue", "stack" };
try {
int foundIndex = -1;
int foundCnt = 0;
}
// printf("foundCnt=%d foundIndex=%d command=%s\n", foundCnt, foundIndex, foundIndex >= 0 ? commands[foundIndex] : "");
if (foundCnt == 1 || length == 0) {
- setCommand((EnumSimAvrCommand)(foundCnt > 0 ? foundIndex + 2 : 1), NULL);
+ EnumSimAvrCommand cmd = (EnumSimAvrCommand)(foundCnt > 0 ? foundIndex + 2 : 1);
+ setCommand(cmd, NULL);
while (1) {
struct SimAvrEvent ev = waitForEvent();
+ if (ev.event == EventShutdown || (cmd == CommandQuit && ev.event == EventCommandExecuted)) {
+ quit = 1;
+ break;
+ }
if (ev.event == EventCommandExecuted) {
break;
}
}
}
- while (1) {
- struct SimAvrEvent ev = waitForEvent();
- printf("event %s (%d) received\n", eventText((EnumSimEvent)ev.event), ev.event);
- if (ev.event == EventShutdown) {
- break;
+ // while (1) {
+ // struct SimAvrEvent ev = waitForEvent();
+ // printf("event %s (%d) received\n", eventText((EnumSimEvent)ev.event), ev.event);
+ // if (ev.event == EventShutdown) {
+ // break;
+ // }
+ // }
+
+ if (simUcInit != NULL) {
+ for (int i = 0; i < simUcInit->argc; i++) {
+ free(simUcInit->argv[i]);
}
+ free(simUcInit);
+ simUcInit = NULL;
}
usleep(10000);
throw std::logic_error(error(AT, "firmware already loaded"));
}
- startParameters = params;
firmware = (elf_firmware_t *) malloc(sizeof(elf_firmware_t));
- std::string filename = std::string(params->filename);
if (params->mmcu != NULL) {
// elf_read_firmware needs mmcu to malloc proper flash size
strncpy(firmware->mmcu, params->mmcu, sizeof(firmware->mmcu));
}
- 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()));
+ startParameters = params;
+
+ 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()));
+ }
}
if (params->mmcu != NULL) {
strncpy(firmware->mmcu, params->mmcu, sizeof(firmware->mmcu));
} else {
avr->gdb_port = 1234;
}
- printf("init with port=%d, mmcu=%s, f=%u, vcc=%d, avcc=%d, aref=%d, pc=0x%04x\n",
+ 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 (cancelThread) {
cnt = -1;
cancelThread = false;
- } else {
+ } else if (!startParameters->nosync) {
if (syncTime[0] != syncTime[1]) {
syncTime[0] = syncTime[1];
if (syncTime[0]) {