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}