| /* |
| * Copyright (c) 2017 Oticon A/S |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| #include <stdbool.h> |
| #include <stdlib.h> |
| #include <limits.h> |
| #include "soc.h" |
| #include "bs_tracing.h" |
| #include "bs_oswrap.h" |
| #include "bs_dump_files.h" |
| #include "argparse.h" |
| #include "bstests.h" |
| #include "NRF_hw_args.h" |
| #include "bs_cmd_line.h" |
| #include "bs_dynargs.h" |
| #include "bs_cmd_line_typical.h" |
| #include "NRF_HWLowL.h" |
| |
| static bs_args_struct_t *args_struct; |
| char executable_name[] = "bs_nrf52_bsim_.."; |
| |
| void component_print_post_help(void) |
| { |
| fprintf(stdout, "\nZephyr and a given app compiled with models of the " |
| "NRF52 HW\n\n"); |
| } |
| |
| static struct NRF_bsim_args_t arg; |
| static char *testid; |
| const char *bogus_sim_id = "bogus"; |
| |
| static void cmd_trace_lvl_found(char *argv, int offset) |
| { |
| bs_trace_set_level(arg.verb); |
| } |
| |
| static void cmd_gdev_nbr_found(char *argv, int offset) |
| { |
| bs_trace_set_prefix_dev(arg.global_device_nbr); |
| } |
| |
| static void cmd_testid_found(char *argv, int offset) |
| { |
| bst_set_testapp_mode(testid); |
| } |
| |
| static void cmd_testlist_found(char *argv, int offset) |
| { |
| bst_print_testslist(); |
| exit(0); |
| } |
| |
| static bool nosim; |
| static void cmd_nosim_found(char *argv, int offset) |
| { |
| hwll_set_nosim(true); |
| } |
| |
| static void save_test_arg(struct NRF_bsim_args_t *args, char *argv) |
| { |
| if (args->test_case_argc >= MAXPARAMS_TESTCASES) { |
| bs_trace_error_line("Too many testcase arguments (at '%s'), " |
| "maximum is %i\n", argv, |
| MAXPARAMS_TESTCASES); |
| } else { |
| bs_trace_raw(9, "cmdarg: adding '%s' to testcase args[%i]\n", |
| argv, args->test_case_argc); |
| args->test_case_argv[args->test_case_argc++] = argv; |
| } |
| } |
| |
| static void print_no_sim_warning(void) |
| { |
| bs_trace_warning("Neither simulation id or the device number " |
| "have been set. I assume you want to run " |
| "without a BabbleSim phy (-nosim)\n"); |
| bs_trace_warning("If this is not what you wanted, check with " |
| "--help how to set them\n"); |
| bs_trace_raw(3, "setting sim_id to 'bogus', device number to 0 " |
| "and nosim\n"); |
| } |
| |
| void nrfbsim_register_args(void) |
| { |
| #define args (&arg) |
| /* This define is quite ugly, but allows reusing the definitions |
| * provided by the utils library |
| */ |
| static bs_args_struct_t args_struct_toadd[] = { |
| ARG_TABLE_S_ID, |
| ARG_TABLE_P_ID_2G4, |
| ARG_TABLE_DEV_NBR, |
| ARG_TABLE_GDEV_NBR, |
| ARG_TABLE_VERB, |
| ARG_TABLE_SEED, |
| ARG_TABLE_COLOR, |
| ARG_TABLE_NOCOLOR, |
| ARG_TABLE_FORCECOLOR, |
| _NRF_HW_SUB_CMD_ARG_STRUCT, |
| /* |
| * Fields: |
| * manual, mandatory, switch, |
| * option_name, var_name, type, |
| * destination, callback, |
| * description |
| */ |
| {false, false, true, |
| "nosim", "", 'b', |
| (void *)&nosim, cmd_nosim_found, |
| "(debug feature) Do not connect to the phy"}, |
| BS_DUMP_FILES_ARGS, |
| {false, false, false, |
| "testid", "testid", 's', |
| (void *)&testid, cmd_testid_found, |
| "Which of the tests shall be run. Run -testslist for more info" |
| }, |
| {false, false, true, |
| "testslist", "", 'b', |
| NULL, cmd_testlist_found, |
| "Print information about the available FW application tests"}, |
| {true, false, false, |
| "argstest", "arg", 'l', |
| NULL, NULL, |
| "The arguments that follow will be passed straight to the " |
| "testcase init function"}, |
| {true, false, false, |
| "argsmain", "arg", 'l', |
| NULL, NULL, |
| "The arguments that follow will be passed to main (default)"}, |
| ARG_TABLE_ENDMARKER |
| }; |
| #undef args |
| |
| bs_add_dynargs(&args_struct, args_struct_toadd); |
| } |
| |
| |
| void bs_add_extra_dynargs(bs_args_struct_t *args_struct_toadd) |
| { |
| bs_add_dynargs(&args_struct, args_struct_toadd); |
| } |
| |
| /** |
| * Check the arguments provided in the command line: set args based on it or |
| * defaults, and check they are correct |
| */ |
| struct NRF_bsim_args_t *nrfbsim_argsparse(int argc, char *argv[]) |
| { |
| bs_args_set_defaults(args_struct); |
| arg.verb = 2; |
| bs_trace_set_level(arg.verb); |
| arg.test_case_argv[0] = 0; |
| arg.test_case_argc = 0; |
| nrf_hw_sub_cmline_set_defaults(&arg.nrf_hw); |
| static const char default_phy[] = "2G4"; |
| |
| enum {Main = 0, Test = 1} parsing = Main; |
| |
| for (int i = 1; i < argc; i++) { |
| if (bs_is_option(argv[i], "argstest", 0)) { |
| parsing = Test; |
| continue; |
| } else if (bs_is_option(argv[i], "argsmain", 0)) { |
| parsing = Main; |
| continue; |
| } |
| |
| if (parsing == Main) { |
| if (!bs_args_parse_one_arg(argv[i], args_struct)) { |
| bs_args_print_switches_help(args_struct); |
| bs_trace_error_line("Incorrect option %s\n", |
| argv[i]); |
| } |
| } else if (parsing == Test) { |
| save_test_arg(&arg, argv[i]); |
| } else { |
| bs_trace_error_line("Bad error\n"); |
| } |
| } |
| /** |
| * If the user did not set the simulation id or device number |
| * we assume he wanted to run with nosim (but warn him) |
| */ |
| if ((!nosim) && (arg.s_id == NULL) && (arg.device_nbr == UINT_MAX)) { |
| print_no_sim_warning(); |
| nosim = true; |
| hwll_set_nosim(true); |
| } |
| if (nosim) { |
| if (arg.s_id == NULL) { |
| arg.s_id = (char *)bogus_sim_id; |
| } |
| if (arg.device_nbr == UINT_MAX) { |
| arg.device_nbr = 0; |
| } |
| } |
| |
| if (arg.device_nbr == UINT_MAX) { |
| bs_args_print_switches_help(args_struct); |
| bs_trace_error_line("The command line option <device number> " |
| "needs to be set\n"); |
| } |
| if (arg.global_device_nbr == UINT_MAX) { |
| arg.global_device_nbr = arg.device_nbr; |
| bs_trace_set_prefix_dev(arg.global_device_nbr); |
| } |
| if (!arg.s_id) { |
| bs_args_print_switches_help(args_struct); |
| bs_trace_error_line("The command line option <simulation ID> " |
| "needs to be set\n"); |
| } |
| if (!arg.p_id) { |
| arg.p_id = (char *)default_phy; |
| } |
| |
| if (arg.rseed == UINT_MAX) { |
| arg.rseed = 0x1000 + arg.device_nbr; |
| } |
| return &arg; |
| } |
| |
| void nrfbsim_cleanup_args(void) |
| { |
| bs_cleanup_dynargs(&args_struct); |
| } |
| |
| NATIVE_TASK(nrfbsim_register_args, PRE_BOOT_1, 0); |
| NATIVE_TASK(nrfbsim_cleanup_args, ON_EXIT, 10); |