Program Source “gen-flash-gdbinit.c”

  1#include <ctype.h>
  2#include <inttypes.h>
  3#include <stdint.h>
  4#include <stdio.h>
  5
  6static FILE *f_out_gdb;
  7
  8static uint8_t page_buf[256];
  9static int page_buf_ptr = 0;
 10static uint32_t page_start = 0;
 11
 12static inline void flush_gdb_script()
 13{
 14  if (page_start % 0x10000 == 0) {
 15    fprintf(f_out_gdb, "echo Erase block 0x%06x\\n\n", page_start);
 16    fprintf(f_out_gdb, "call flash_erase_64k(0x%06x)\n", page_start);
 17  }
 18  fprintf(f_out_gdb, "set flash_test_write_buf = {");
 19  for (int i = 0; i < page_buf_ptr; i++) {
 20    if (i != 0) fprintf(f_out_gdb, ", ");
 21    fprintf(f_out_gdb, "%d", page_buf[i]);
 22  }
 23  fprintf(f_out_gdb, "}\n");
 24  fprintf(f_out_gdb, "call flash_test_write(0x%06x, %d)\n", page_start, page_buf_ptr);
 25  fprintf(f_out_gdb, "echo Written page 0x%06x\\n\n", page_start);
 26
 27  page_buf_ptr = 0;
 28  page_start += 256;
 29}
 30
 31static inline void add_data(uint8_t data)
 32{
 33  page_buf[page_buf_ptr++] = data;
 34  if (page_buf_ptr == 256) flush_gdb_script();
 35}
 36
 37int main(int argc, char *argv[])
 38{
 39  if (argc <= 2) {
 40    printf("Usage: %s <input> [<input> ...] <output-gdbinit>\n", argv[0]);
 41    return 0;
 42  }
 43
 44  const char *path_out_gdb = argv[argc - 1];
 45  f_out_gdb = fopen(path_out_gdb, "w");
 46  fprintf(stderr, "Writing GDB script to %s\n", path_out_gdb);
 47  if (f_out_gdb == NULL) {
 48    fprintf(stderr, "Cannot open %s for writing\n", path_out_gdb);
 49    return 1;
 50  }
 51
 52  fprintf(f_out_gdb, "b flash_test_write_breakpoint\n");
 53  fprintf(f_out_gdb, "commands\n");
 54
 55  int in_count = argc - 2;
 56  for (int i = 0; i < in_count; i++) {
 57    const char *path_in = argv[1 + i];
 58    FILE *f_in = fopen(path_in, "rb");
 59    // fprintf(stderr, "Reading file (%d/%d) %s\n", i + 1, in_count, path_in);
 60    if (f_in == NULL) {
 61      fprintf(stderr, "Cannot open %s for reading\n", path_in);
 62      return 1;
 63    }
 64
 65    const char *name = path_in;
 66    for (const char *p = path_in; *p != '\0'; p++)
 67      if (*p == '/' || *p == '\\') name = p;
 68    uint32_t addr_start = page_start + page_buf_ptr;
 69
 70    fprintf(f_out_gdb, "echo ======== File (%d/%d) %s ========\\n\n", i + 1, in_count, name);
 71
 72    int b;
 73    while ((b = fgetc(f_in)) != EOF) add_data(b);
 74
 75    uint32_t len = page_start + page_buf_ptr - addr_start;
 76
 77#define print_name() do { \
 78    int spaces = 16; \
 79    for (const char *p = name; *p != '\0'; p++) { \
 80      putchar(isalnum(*p) ? *p : '_'); \
 81      spaces--; \
 82    } \
 83    for (int i = 0; i < spaces; i++) putchar(' '); \
 84  } while (0)
 85
 86    printf("#define FILE_ADDR_");
 87    print_name();
 88    printf(" %" PRId32 "\n", addr_start);
 89    printf("#define FILE_SIZE_");
 90    print_name();
 91    printf(" %" PRId32 "\n", len);
 92  }
 93  flush_gdb_script();
 94
 95  fprintf(f_out_gdb, "end\n");
 96  fprintf(f_out_gdb, "r\n");
 97
 98  fclose(f_out_gdb);
 99
100  return 0;
101}
Raw file (2.7 KiB)