diff --git a/.vscode/launch.json b/.vscode/launch.json index 2b75f26..f51cf18 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,7 @@ "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/app/bs", - "args": ["-l"], + "args": [], "stopAtEntry": false, "cwd": "${fileDirname}", "environment": [], @@ -28,56 +28,6 @@ } ], "preLaunchTask": "build", - }, - { - "name": "bs scan", - "type": "cppdbg", - "request": "launch", - "program": "${workspaceFolder}/build/app/bs", - "args": ["-n", "2", "scan"], - "stopAtEntry": false, - "cwd": "${fileDirname}", - "environment": [], - "externalConsole": false, - "MIMode": "gdb", - "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - }, - { - "description": "Set Disassembly Flavor to Intel", - "text": "-gdb-set disassembly-flavor intel", - "ignoreFailures": true - } - ], - "preLaunchTask": "build", - }, - { - "name": "bs devid", - "type": "cppdbg", - "request": "launch", - "program": "${workspaceFolder}/build/app/bs", - "args": ["-n", "2", "-b", "/data/frd/xcku15p_ffve1517.bsd", "-d", "0x14a56093"], - "stopAtEntry": false, - "cwd": "${fileDirname}", - "environment": [], - "externalConsole": false, - "MIMode": "gdb", - "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - }, - { - "description": "Set Disassembly Flavor to Intel", - "text": "-gdb-set disassembly-flavor intel", - "ignoreFailures": true - } - ], - "preLaunchTask": "build", - }, + } ] } \ No newline at end of file diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 9aa596d..d28296e 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -7,6 +7,8 @@ add_executable( ${ALL_SOURCES} ) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src) + # linking configuration target_link_libraries( bs PRIVATE jtag_core diff --git a/app/src/args.c b/app/src/args.c index ac356ff..b9f001e 100644 --- a/app/src/args.c +++ b/app/src/args.c @@ -4,75 +4,88 @@ #include #include +#include "common.h" #include "args.h" -char * COMMAND_STRINGS[COMMANDS_NUMBER-1] = { - "scan" -}; +// void global_help() { +// printf("Usage: bs [[-l] [--list]] [[-n] [--nprobe]] [[-b] [--bsdl]] [[-d] [--device_id]] PROBE_NUM] [] []\n"); +// } -void usage() { - printf("Usage: bs [[-l] [--list]] [[-n] [--nprobe]] [[-b] [--bsdl]] [[-d] [--device_id]] PROBE_NUM] [scan]\n"); -} +// int parse_args(struct args *a, int argc, char *argv[]) { +// int opt = 0; +// int i = 0; +// unsigned int devid = 0; +// int command = 0; +// __uint8_t option_arg[MAX_PATH] = {0}; -int parse_args(struct args *a, int argc, char *argv[]) { - int opt = 0; - int i = 0; - unsigned int devid = 0; - int command = 0; - __uint8_t option_arg[MAX_PATH] = {0}; +// // Définir les options longues +// static struct option long_options[] = { +// {"list", no_argument, 0, 'l'}, +// {"nprobe", required_argument, 0, 'n'}, +// {"bsdl", required_argument, 0, 'b'}, +// {"device_id", required_argument, 0, 'd'}, +// {0, 0, 0, 0} +// }; - // Définir les options longues - static struct option long_options[] = { - {"list", no_argument, 0, 'l'}, - {"nprobe", required_argument, 0, 'n'}, - {"bsdl", required_argument, 0, 'b'}, - {"device_id", required_argument, 0, 'd'}, - {0, 0, 0, 0} - }; +// // Utilisation de getopt_long pour parser les options +// while ((opt = getopt_long(argc, argv, "ln:b:d:", long_options, NULL)) != -1) { +// switch (opt) { +// case 'h': +// a->list = 1; +// break; +// case 'n': +// snprintf(option_arg, sizeof(option_arg)-2, "%s", optarg); +// a->probe = atoi(option_arg); +// break; +// case 'b': +// snprintf(a->bsdl, MAX_PATH-2, "%s", optarg); +// break; +// case 'd': +// i = sscanf(optarg, "0x%x", &devid); +// if (i == 0) { +// printf("Device ID must be an hex value like '0xABCD'"); +// return EXIT_FAILURE; +// } +// break; +// default: +// usage(); +// return EXIT_FAILURE; +// } +// } - // Utilisation de getopt_long pour parser les options - while ((opt = getopt_long(argc, argv, "ln:b:d:", long_options, NULL)) != -1) { - switch (opt) { - case 'l': - a->list = 1; - break; - case 'n': - snprintf(option_arg, sizeof(option_arg)-2, "%s", optarg); - a->probe = atoi(option_arg); - break; - case 'b': - snprintf(a->bsdl, MAX_PATH-2, "%s", optarg); - break; - case 'd': - i = sscanf(optarg, "0x%x", &devid); - if (i == 0) { - printf("Device ID must be an hex value like '0xABCD'"); - return EXIT_FAILURE; - } - break; - default: - usage(); - return EXIT_FAILURE; +// // Positional arguments +// if (optind < argc) { +// /* Positional arguments */ +// while (optind < argc) { +// for (i=0;icmds[command] = (enum commands)i+1; +// } +// } +// optind++; +// } +// } + +// // Si aucune option n'est fournie, afficher l'aide +// if (optind == 1) { +// usage(); +// } + +// return EXIT_SUCCESS; +// } + +void parse_command(char *line, int *argc, char **argv) { + *argc = 0; + while (*line != '\0') { + while (*line == ' ' || *line == '\t' || *line == '\n') { + *line++ = '\0'; + } + if (*argc >= MAX_ARGS) break; + (*argc)++; + *argv++ = line; + while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n') { + line++; } } - - // Positional arguments - if (optind < argc) { - /* Positional arguments */ - while (optind < argc) { - for (i=0;icmds[command] = (enum commands)i+1; - } - } - optind++; - } - } - - // Si aucune option n'est fournie, afficher l'aide - if (optind == 1) { - usage(); - } - - return EXIT_SUCCESS; + *argv = '\0'; } diff --git a/app/src/args.h b/app/src/args.h index 5c83340..25377a5 100644 --- a/app/src/args.h +++ b/app/src/args.h @@ -1,23 +1,20 @@ #ifndef _ARGS_H #define _ARGS_H -#define MAX_COMMANDS 16 -#define MAX_PATH 1024 +// #define MAX_LINE 1024 +// #define MAX_ARGS 16 +// #define MAX_COMMANDS 16 +// #define MAX_PATH 1024 -enum commands { - NO_COMMAND=0, - COMMAND_SCAN, - COMMANDS_NUMBER, /* The number of enums +1*/ -}; +// struct args { +// int list; +// int probe; +// char bsdl[MAX_PATH]; +// int devid; +// enum commands cmds[MAX_COMMANDS]; +// }; -struct args { - int list; - int probe; - char bsdl[MAX_PATH]; - int devid; - enum commands cmds[MAX_COMMANDS]; -}; - -int parse_args(struct args *a, int argc, char *argv[]); +// int parse_args(struct args *a, int argc, char *argv[]); +void parse_command(char *line, int *argc, char **argv); #endif diff --git a/app/src/cmds/exit.c b/app/src/cmds/exit.c new file mode 100644 index 0000000..7a0c561 --- /dev/null +++ b/app/src/cmds/exit.c @@ -0,0 +1,11 @@ +#include +#include + +#include "exit.h" + +const char cmd_exit_help[] = "Bla bla."; + +int cmd_exit(jtag_core *jc, int argc, char **argv) { + jtagcore_deinit(jc); + exit(0); +} \ No newline at end of file diff --git a/app/src/cmds/exit.h b/app/src/cmds/exit.h new file mode 100644 index 0000000..216bef8 --- /dev/null +++ b/app/src/cmds/exit.h @@ -0,0 +1,10 @@ +#ifndef _CMD_EXIT_H +#define _CMD_EXIT_H + +#include "jtag_core.h" + +extern const char cmd_exit_help[]; + +int cmd_exit(jtag_core *jc, int argc, char *argv[]); + +#endif /* _CMD_EXIT_H */ \ No newline at end of file diff --git a/app/src/cmds/help.c b/app/src/cmds/help.c new file mode 100644 index 0000000..4c55d7c --- /dev/null +++ b/app/src/cmds/help.c @@ -0,0 +1,8 @@ +#include +#include + +#include "help.h" + +int cmd_help(jtag_core *jc, int argc, char **argv) { + +} \ No newline at end of file diff --git a/app/src/cmds/help.h b/app/src/cmds/help.h new file mode 100644 index 0000000..f18113b --- /dev/null +++ b/app/src/cmds/help.h @@ -0,0 +1,8 @@ +#ifndef _CMD_HELP_H +#define _CMD_HELP_H + +#include "jtag_core.h" + +int cmd_help(jtag_core *jc, int argc, char *argv[]); + +#endif /* _CMD_help_H */ \ No newline at end of file diff --git a/app/src/cmds/list_probes.c b/app/src/cmds/list_probes.c new file mode 100644 index 0000000..e471322 --- /dev/null +++ b/app/src/cmds/list_probes.c @@ -0,0 +1,69 @@ +#include +#include + +#include "list_probes.h" +#include "common.h" + +const char cmd_list_probes_help[] = "Bla bla."; + +struct probe { + int drv; + int probe; + int probe_id; + char name[PROBE_NAME_SIZE]; +}; + +int list_probes(jtag_core *jc, struct probe probes[], int show) { + int i = 0; + int j = 0; + int n = 0; + + char probe_name[PROBE_NAME_SIZE] = {0}; + int n_probe_drv = 0; + int n_probes = 0; + + /* Drivers and probes */ + n_probe_drv = jtagcore_get_number_of_probes_drv(jc); + if (n_probe_drv > 0) { + if (0 != show) printf("Found a debug probe driver:\n"); + } else { + if (0 != show) printf("No probes driver found\n"); + return n; + } + + for (i=0;i 0) { + + if (0 != show) printf("Found a debug probe:\n"); + + } else { + + if (0 != show) printf("No probe found.\n"); + continue; + } + for (j=0;j + +#include "scan.h" +#include "common.h" + +const char cmd_scan_help[] = "Bla bla."; + +int scan(jtag_core *jc, int probe_id, int *ndevs, unsigned long ids[], int show) { + int err = JTAG_CORE_NO_ERROR; + int n = 0; + int i = 0; + + if (0 != show) printf("Devices scan in progress...\n"); + + err = jtagcore_scan_and_init_chain(jc); + if (err < 0) { + if (0 != show) printf("Impossible to scan the JTAG chain"); + return err; + } + + n = jtagcore_get_number_of_devices(jc); + if (n < 0) { + if (0 != show) printf("Error while getting the number of devices on the chain.\n"); + return err; + } + *ndevs = n; + for (i=0;i < MIN(n, DEVICES_SCAN_MAX);i++) { + ids[i] = jtagcore_get_dev_id(jc, i); + if (0 != show) printf(" device %d : 0x%08x\n", i, ids[i]); + } + + if (0 != show) printf("Done.\n"); + return err; +} + +int cmd_scan(jtag_core *jc, int argc, char *argv[]) { + +} \ No newline at end of file diff --git a/app/src/cmds/scan.h b/app/src/cmds/scan.h new file mode 100644 index 0000000..7639f2b --- /dev/null +++ b/app/src/cmds/scan.h @@ -0,0 +1,11 @@ +#ifndef _CMDS_SCAN_H +#define _CMDS_SCAN_H + +#include "jtag_core.h" + +extern const char cmd_scan_help[]; + +int cmd_scan(jtag_core *jc, int argc, char *argv[]); + + +#endif diff --git a/app/src/cmds/select_probe.c b/app/src/cmds/select_probe.c new file mode 100644 index 0000000..d84a328 --- /dev/null +++ b/app/src/cmds/select_probe.c @@ -0,0 +1,16 @@ +#include + +#include "select_probe.h" + +const char cmd_select_probe_help[] = "Bla bla."; + +int cmd_select_probe(jtag_core *jc, int argc, char *argv[]) { + int error = 0; + + error = jtagcore_select_and_open_probe(jc, probe_id); + if (error < 0) { + printf("Impossible to open the selected probe.\n"); + return error; + } + +} \ No newline at end of file diff --git a/app/src/cmds/select_probe.h b/app/src/cmds/select_probe.h new file mode 100644 index 0000000..1b88393 --- /dev/null +++ b/app/src/cmds/select_probe.h @@ -0,0 +1,10 @@ +#ifndef _SELECT_PROBE_H +#define _SELECT_PROBE_H + +#include "jtag_core.h" + +extern const char cmd_select_probe_help[]; + +int cmd_select_probe(jtag_core *jc, int argc, char *argv[]); + +#endif \ No newline at end of file diff --git a/app/src/common.c b/app/src/common.c new file mode 100644 index 0000000..d4ac0dc --- /dev/null +++ b/app/src/common.c @@ -0,0 +1,41 @@ +#include +#include + +#include "common.h" +#include "cmds/help.h" +#include "cmds/scan.h" +#include "cmds/list_probes.h" +#include "cmds/exit.h" +#include "cmds/select_probe.h" + +// Table des commandes internes +Command commands[] = { + {"help", cmd_help, NULL}, + {"list_probes", cmd_list_probes, cmd_list_probes_help}, + {"scan", cmd_scan, cmd_scan_help}, + {"select_probe", cmd_select_probe, cmd_select_probe_help}, + {"exit", cmd_exit, cmd_exit_help}, + {NULL, NULL} +}; + + +void jprint(jtag_core *jc, const char *msg) { + printf(msg); +} + +jtag_core * bsexp_init(void) { + + jtag_core *ret = NULL; + + /* initialize the JTAG library */ + ret = jtagcore_init(); + if (NULL != ret) { + /* Log printing callback */ + if (jtagcore_set_logs_callback(ret, jprint) < 0) { + printf("Impossible to define the logs callback!\n"); + } else { + jtagcore_set_logs_level(ret, MSG_DEBUG); + } + } + return ret; +} \ No newline at end of file diff --git a/app/src/common.h b/app/src/common.h new file mode 100644 index 0000000..8d09d62 --- /dev/null +++ b/app/src/common.h @@ -0,0 +1,26 @@ +#ifndef _UTILS_H +#define _UTILS_H + +#include "jtag_core.h" + +#define MAX_LINE 1024 +#define MAX_ARGS 16 +#define PROBES_MAX_NUM 16 +#define PROBE_NAME_SIZE 64 +#define DEVICES_SCAN_MAX 32 + +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + +typedef int (*command_call)(jtag_core *jc, int argc, char *argv[]); + +typedef struct { + char *name; + command_call cmd_call; +} Command; + +extern Command commands[]; + +jtag_core *bsexp_init(void); + +#endif \ No newline at end of file diff --git a/app/src/main.c b/app/src/main.c index c1a7917..1978f13 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -2,162 +2,116 @@ #include #include #include +#include +#include #include "jtag_core.h" +#include "common.h" #include "args.h" -#include "utils.h" + +// int main(int argc, char *argv[]) { +// int success = 0; +// int n_probes = 0; +// int i = 0; +// int error = 0; +// jtag_core *jc = NULL; + +// struct args a = {0}; +// struct probe probes[PROBES_MAX_NUM] = {0}; +// unsigned long dev_ids[DEVICES_SCAN_MAX] = {0}; +// int ndevs = 0; + +// success = parse_args(&a, argc, argv); +// if (EXIT_FAILURE == success) exit(EXIT_FAILURE); + +// jc = bsexp_init(); +// if (NULL == jc) { +// error = JTAG_CORE_MEM_ERROR; +// goto err; +// } + +// /* List the probes (and display if asked) */ +// n_probes = list_probes(jc, probes, a.list); + +// i = 0; +// while ((i= a.probe) || (a.probe > MIN(n_probes, PROBES_MAX_NUM))) goto err; +// error = scan(jc, probes[a.probe-1].probe_id, &ndevs, dev_ids, 1); +// break; +// default: +// printf("Unknown command."); +// goto err; +// } +// i++; +// } + +// goto end; + +// err: +// printf("Exited with error (%d).\n", error); + +// end: +// jtagcore_deinit(jc); +// return error; +// } -#define PROBES_MAX_NUM 16 -#define PROBE_NAME_SIZE 64 -#define DEVICES_SCAN_MAX 32 - - -struct probe { - int drv; - int probe; - int probe_id; - char name[PROBE_NAME_SIZE]; -}; - - -void jprint(jtag_core *jc, const char *msg) { - printf(msg); -} - - -int list_probes(jtag_core *jc, struct probe probes[], int show) { - int i = 0; - int j = 0; - int n = 0; - - char probe_name[PROBE_NAME_SIZE] = {0}; - int n_probe_drv = 0; - int n_probes = 0; - - /* Drivers and probes */ - n_probe_drv = jtagcore_get_number_of_probes_drv(jc); - if (n_probe_drv > 0) { - if (0 != show) printf("Found a debug probe driver:\n"); - } else { - if (0 != show) printf("No probes driver found\n"); - return n; - } - - for (i=0;i 0) { - - if (0 != show) printf("Found a debug probe:\n"); - - } else { - - if (0 != show) printf("No probe found.\n"); - continue; - } - for (j=0;j= a.probe) || (a.probe > MIN(n_probes, PROBES_MAX_NUM))) goto err; - error = scan(jc, probes[a.probe-1].probe_id, &ndevs, dev_ids, 1); - break; - default: - printf("Unknown command."); - goto err; - } - i++; + jc = bsexp_init(); + if (NULL == jc) { + error = JTAG_CORE_MEM_ERROR; + printf("JTAG Core execution failed"); + goto err; } - goto end; + while (1) { + line = readline("bs_explorer> "); + if (line == NULL) { + break; + } + if (*line) { + add_history(line); + } + parse_command(line, &cmd_argc, cmd_argv); + if (cmd_argv[0] == NULL) { + continue; + } + if (strcmp(cmd_argv[0], "exit") == 0) { + break; + } + error = execute_command(jc, cmd_argc, cmd_argv); + printf("\n"); + if (0 == error) { + } else { + printf("Command failed with code: %d", error); + } + } + return 0; err: - printf("Exited with error (%d).\n", error); - -end: - jtagcore_deinit(jc); return error; } \ No newline at end of file diff --git a/app/src/utils.h b/app/src/utils.h deleted file mode 100644 index b9ac895..0000000 --- a/app/src/utils.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _UTILS_H -#define _UTILS_H - -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - -#endif \ No newline at end of file diff --git a/lib_jtag_core/src/jtag_core.h b/lib_jtag_core/src/jtag_core.h index a61bd69..f02e48b 100644 --- a/lib_jtag_core/src/jtag_core.h +++ b/lib_jtag_core/src/jtag_core.h @@ -1,3 +1,6 @@ +#ifndef _JTAG_CORE_H +#define _JTAG_CORE_H + /* * JTAG Core library * Copyright (c) 2008 - 2024 Viveris Technologies @@ -340,3 +343,5 @@ int jtagemu_get_regbit_state(jtag_emu * je, int regid, int bit); int jtagemu_loadbsdlfile(jtag_emu * je, char * path, int device); void jtagemu_deinit(jtag_emu * je); + +#endif \ No newline at end of file