From be7a2ddc9cccf2f5365019bb05438ae5f17e919e Mon Sep 17 00:00:00 2001 From: Nathan Schulte <8540239+nmschulte@users.noreply.github.com> Date: Mon, 5 Aug 2024 13:43:07 -0500 Subject: [PATCH] simulator: more arguments (#432) * simulator: improve READMEs * simulator: use argp for argument parsing * simulator: plumb SocketCAN device argument * simulator: change verbosity argument use a --quiet instead, as --verbose is a "set-only" option without arguments and cannot be "unset" if default * simulator: timeout is an option, not an argument * simulator: github workflow uses --timeout option --- .github/workflows/build-simulator.yaml | 2 +- simulator/{readme.md => README.md} | 3 +- simulator/libc_argp.h | 65 ++++++++++++++++++++ simulator/main.cpp | 19 ++++-- simulator/simulator/README.md | 1 + simulator/simulator/readme.md | 1 - simulator/simulator/rusEfiFunctionalTest.cpp | 6 +- simulator/simulator/rusEfiFunctionalTest.h | 2 +- 8 files changed, 85 insertions(+), 14 deletions(-) rename simulator/{readme.md => README.md} (67%) create mode 100644 simulator/libc_argp.h create mode 100644 simulator/simulator/README.md delete mode 100644 simulator/simulator/readme.md diff --git a/.github/workflows/build-simulator.yaml b/.github/workflows/build-simulator.yaml index b0cbff5878..395fa00f45 100644 --- a/.github/workflows/build-simulator.yaml +++ b/.github/workflows/build-simulator.yaml @@ -40,7 +40,7 @@ jobs: - name: Run Linux Simulator for 10 seconds working-directory: ./simulator/ - run: ./build/fome_simulator 10 + run: ./build/fome_simulator --timeout 10 - name: Upload Linux built simulator uses: actions/upload-artifact@v4 diff --git a/simulator/readme.md b/simulator/README.md similarity index 67% rename from simulator/readme.md rename to simulator/README.md index b3b8045632..85e208c487 100644 --- a/simulator/readme.md +++ b/simulator/README.md @@ -1,4 +1,4 @@ -Win32 or posix version of firmware allows to explore rusEFI on a PC without any embedded hardware! +Win32 or POSIX version of firmware allows to explore FOME on a PC without any embedded hardware! Simulator runs a subset of ECU on your pc, easier to debug some things, tighter dev loop. @@ -6,4 +6,3 @@ Simulator runs a subset of ECU on your pc, easier to debug some things, tighter * mocked analog sensors * mocked outputs * SocketCAN integration on Linux - diff --git a/simulator/libc_argp.h b/simulator/libc_argp.h new file mode 100644 index 0000000000..218ad1142a --- /dev/null +++ b/simulator/libc_argp.h @@ -0,0 +1,65 @@ +#include +#include + +/* Program documentation. */ +static char doc[] = + "FOME Simulator -- https://wiki.fome.tech/"; + +/* A description of the arguments we accept. */ +static char args_doc[] = ""; + +/* The options we understand. */ +static struct argp_option options[] = { + {"quiet", 'q', 0, 0, "Don't produce verbose output", 0 }, + {"socketcan-device", + 'd', "DEVICE", 0, "SocketCAN DEVICE (default: can0) to use", 0 }, + {"timeout", 't', "SECONDS", 0, "Run for SECONDS and then exit (negative values ignored)", 0 }, + { 0, 0, 0, 0, 0, 0 } +}; + +/* Used by main to communicate with parse_opt. */ +struct arguments +{ + int quiet; + char * socketcanDevice; + int timeout; +}; + +/* Parse a single option. */ +static error_t +parse_opt(int key, char * arg, struct argp_state * state) +{ + /* Get the input argument from argp_parse, which we + know is a pointer to our arguments structure. */ + struct arguments * arguments = (struct arguments *)state->input; + + switch (key) { + case 'd': + arguments->socketcanDevice = arg; + break; + case 'q': + arguments->quiet = 1; + break; + case 't': + arguments->timeout = atoi(arg); + break; + + case ARGP_KEY_ARG: + /* if (state->arg_num >= 0) */ { + /* Too many arguments. */ + argp_usage(state); + } + break; + + case ARGP_KEY_END: + case ARGP_KEY_NO_ARGS: + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +/* Our argp parser. */ +static struct argp argp = { options, parse_opt, args_doc, doc, 0, 0, 0 }; diff --git a/simulator/main.cpp b/simulator/main.cpp index 71a57fc26e..2be07b2793 100644 --- a/simulator/main.cpp +++ b/simulator/main.cpp @@ -18,6 +18,7 @@ #include "chprintf.h" #include "rusEfiFunctionalTest.h" #include "flash_int.h" +#include "libc_argp.h" #include #include @@ -143,6 +144,14 @@ static virtual_timer_t exitTimer; int main(int argc, char** argv) { setbuf(stdout, NULL); + struct arguments arguments; + arguments.quiet = 0; + arguments.socketcanDevice = (char *)"can0"; + arguments.timeout = -1; + argp_parse(&argp, argc, argv, 0, 0, &arguments); + + verboseMode = arguments.quiet == 0; + /* * System initializations. * - HAL initialization, this also initializes the configured device drivers @@ -153,12 +162,10 @@ int main(int argc, char** argv) { halInit(); chSysInit(); - if (argc == 2) { - int timeoutSeconds = atoi(argv[1]); - printf("Running rusEFI simulator for %d seconds, then exiting.\n\n", timeoutSeconds); - + if (arguments.timeout >= 0) { + printf("Running rusEFI simulator for %d seconds, then exiting.\n\n", arguments.timeout); chSysLock(); - chVTSetI(&exitTimer, MY_US2ST(timeoutSeconds * 1e6), [](void*) { exit(0); }, nullptr); + chVTSetI(&exitTimer, MY_US2ST(arguments.timeout * 1e6), [](void *) { exit(0); }, nullptr); chSysUnlock(); } @@ -178,7 +185,7 @@ int main(int argc, char** argv) { cputs(" - Listening for connections on SD2"); chEvtRegister(chnGetEventSource(&SD2), &sd2fel, 2); - rusEfiFunctionalTest(); + rusEfiFunctionalTest(arguments.socketcanDevice); /* * Events servicing loop. diff --git a/simulator/simulator/README.md b/simulator/simulator/README.md new file mode 100644 index 0000000000..f588f29677 --- /dev/null +++ b/simulator/simulator/README.md @@ -0,0 +1 @@ +Here we have FOME PC version ("simulator"). Same Makefile would build Win32 or \*nix/POSIX. diff --git a/simulator/simulator/readme.md b/simulator/simulator/readme.md deleted file mode 100644 index 4e2b498114..0000000000 --- a/simulator/simulator/readme.md +++ /dev/null @@ -1 +0,0 @@ -Here we have rusEfi PC version. Same Makefile would build win32 or unux posix. diff --git a/simulator/simulator/rusEfiFunctionalTest.cpp b/simulator/simulator/rusEfiFunctionalTest.cpp index 4d6ae5f809..2ed5605c63 100644 --- a/simulator/simulator/rusEfiFunctionalTest.cpp +++ b/simulator/simulator/rusEfiFunctionalTest.cpp @@ -84,7 +84,7 @@ static void runChprintfTest() { } -void rusEfiFunctionalTest(void) { +void rusEfiFunctionalTest(char const * const socketcanDevice) { printToConsole("Running rusEfi simulator version:"); static char versionBuffer[20]; itoa10(versionBuffer, (int)getRusEfiVersion()); @@ -128,8 +128,8 @@ void rusEfiFunctionalTest(void) { #if HAL_USE_CAN // Set CAN device name - CAND1.deviceName = "can0"; - + CAND1.deviceName = socketcanDevice; + printf("Using SocketCAN device: %s\n", CAND1.deviceName); initCan(); #endif // HAL_USE_CAN diff --git a/simulator/simulator/rusEfiFunctionalTest.h b/simulator/simulator/rusEfiFunctionalTest.h index 1597175652..b5205806e5 100644 --- a/simulator/simulator/rusEfiFunctionalTest.h +++ b/simulator/simulator/rusEfiFunctionalTest.h @@ -7,6 +7,6 @@ #pragma once -void rusEfiFunctionalTest(void); +void rusEfiFunctionalTest(char const * const socketcanDevice); void printPendingMessages(void); void logMsg(const char *fmt, ...);