Add code generation for indexing files in flash

Fix
This commit is contained in:
logicog
2025-07-31 19:31:29 +02:00
parent 99344a2d99
commit 42c8f05afe
+124 -40
View File
@@ -17,10 +17,16 @@
// Use a 4MB buffer, the same as the flash rom size
#define BUFFER_SIZE 0x400000
unsigned char buffer[BUFFER_SIZE];
FILE *inptr, *dataptr;
FILE *inptr, *dataptr, *ofile;
int outptr;
#define PATH_SIZE 1024
#define INDEX_SIZE 1024
#define DEF_SIZE 1024
char pathbuffer[PATH_SIZE];
char ibuf[INDEX_SIZE];
char dbuf[DEF_SIZE];
int defbuf_p;
int ibuf_p;
const char *argp_program_version = "fileadder 0.1";
const char *argp_program_bug_address = "<git@logicog.de>";
@@ -31,7 +37,8 @@ static struct argp_option options[] = {
{ "output", 'o', "FILE", 0, "Output image file name instead of overwriting input image"},
{ "data", 'd', "FILE", 0, "File or directory to add to image"},
{ "address", 'a', 0, OPTION_ARG_OPTIONAL, "Address where data is placed, default is 0x1000000 if option is used, otherwise 0x1fd000"},
{ "header", 'h', 0, OPTION_ARG_OPTIONAL, "Creates a header file."},
{ "prefix", 'p', "FILE", 0, "Prefix for header and index file generation"},
{ "bank", 'b', "BANKNAME", 0, "Generate #pragma with given bank-name"},
{ 0 }
};
@@ -40,6 +47,8 @@ struct arguments {
int size, address;
char *output_file;
char *data_file;
char *prefix;
char *bank;
bool overwrite;
bool add_zero;
};
@@ -62,9 +71,15 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
case 'd':
arguments->data_file = arg;
break;
case 'p':
arguments->prefix = arg;
break;
case 'n':
arguments->add_zero = false;
break;
case 'b':
arguments->bank = arg? arg : "BANK1";
break;
default:
return ARGP_ERR_UNKNOWN;
}
@@ -97,6 +112,24 @@ int addfile(const char *name, int addr)
}
int addidx(const char *name, int addr, int len)
{
char s[256];
int i = 0;
while (name[i]) {
s[i] = name[i] == '.'? '_' : name[i];
i++;
}
s[i] = '\0';
defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "#define FDATA_START_%s 0x%x\n", s, addr);
defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "#define FDATA_SIZE_%s %d\n", s, len);
ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, " {\"%s\", FDATA_START_%s, FDATA_SIZE_%s},\n", name, s, s);
return 0;
}
int main(int argc, char **argv)
{
char * line = NULL;
@@ -110,38 +143,59 @@ int main(int argc, char **argv)
arguments.address = 0x1fd000;
arguments.size = 0;
arguments.overwrite = true;
arguments.prefix = 0;
arguments.bank = NULL;
argp_parse(&argp, argc, argv, 0, &arg_index, &arguments);
if (!arg_index)
argp_usage (0);
memset(buffer, BUFFER_SIZE, 1);
inptr = fopen(argv[arg_index], "rb");
if (inptr == NULL) {
printf("Cannot open %s\n", argv[1]);
return 5;
memset(buffer, 0, BUFFER_SIZE);
size_t filesize = 0;
if (argv[arg_index]) {
inptr = fopen(argv[arg_index], "rb");
if (inptr == NULL) {
printf("Cannot open input file %s\n", argv[arg_index]);
return 5;
}
fseek(inptr, 0L, SEEK_END);
filesize = ftell(inptr);
rewind(inptr);
printf("Input file size: %ld\n", filesize);
if (filesize > BUFFER_SIZE) {
printf("File too large.\n");
return 5;
}
size_t bytes_read = fread(buffer, 1, sizeof(buffer), inptr);
printf("Bytes read: %ld\n", bytes_read);
if (bytes_read != filesize) {
printf("Error reading input file.\n");
return 5;
}
fclose(inptr);
}
fseek(inptr, 0L, SEEK_END);
size_t filesize = ftell(inptr);
rewind(inptr);
printf("Input file size: %ld\n", filesize);
if (filesize > BUFFER_SIZE) {
printf("File too large.\n");
return 5;
}
size_t bytes_read = fread(buffer, 1, sizeof(buffer), inptr);
// Add preambles to index and header file
defbuf_p = ibuf_p = 0;
defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "#ifndef FDATA_DEFS_H\n\n");
defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "#define FDATA_DEFS_H\n\n");
defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "#include <stdint.h>\n\n");
defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "struct f_data {\n char *file;\n uint32_t start;\n uint16_t end;\n};\n\n");
printf("Bytes read: %ld\n", bytes_read);
if (bytes_read != filesize) {
printf("Error reading input file.\n");
return 5;
}
fclose(inptr);
ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, "// This file is automatically generated, do not edit!\n\n");
if (arguments.prefix)
ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, "#include \"%s.h\"\n\n", arguments.prefix);
if (arguments.bank)
ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, "#pragma codeseg %s\n", arguments.bank);
ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, "struct f_data f_data[] = {\n");
// Now that the beginning of the buffer is filled with out image, optionally resize the image
filesize = arguments.size? arguments.size : filesize;
if (filesize)
filesize = arguments.size? arguments.size : filesize;
if (stat(arguments.data_file, &s) == 0 && s.st_mode & S_IFDIR) {
printf("Adding entries in directory %s\n", arguments.data_file);
@@ -169,6 +223,7 @@ int main(int argc, char **argv)
buffer[arguments.address + data_read++ + 1] = '0';
printf("Data inserted from %s at 0x%x, size: %ld\n", pathbuffer, addr, data_read);
}
addidx(in_file->d_name, addr, data_read);
addr += data_read;
}
} else {
@@ -181,25 +236,54 @@ int main(int argc, char **argv)
}
}
if (!arguments.overwrite)
outptr = creat(arguments.output_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
else
outptr = mkstemp(tmpfilename);
ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, "};\n");
defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "#endif\n");
if (!outptr) {
printf("Cannot open %s\n", arguments.output_file);
return 5;
if (filesize) {
if (!arguments.overwrite)
outptr = creat(arguments.output_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
else
outptr = mkstemp(tmpfilename);
if (!outptr) {
printf("Cannot open %s\n", arguments.output_file);
return 5;
}
size_t written = write(outptr, buffer, filesize);
if (written != filesize) {
printf("Error writing output file.\n");
return 5;
}
close(outptr);
if (arguments.overwrite)
rename(tmpfilename, argv[arg_index]);
}
size_t written = write(outptr, buffer, filesize);
if (written != filesize) {
printf("Error writing output file.\n");
return 5;
if (arguments.prefix) {
snprintf(pathbuffer, PATH_SIZE, "%s.%s", arguments.prefix, "h");
ofile = fopen(pathbuffer, "w");
if (!ofile) {
fprintf(stderr, "%s: ", pathbuffer);
perror("Open failed");
return 5;
}
fputs(dbuf, ofile);
fclose(ofile);
snprintf(pathbuffer, PATH_SIZE, "%s.%s", arguments.prefix, "c");
ofile = fopen(pathbuffer, "w");
if (!ofile) {
fprintf(stderr, "%s: ", pathbuffer);
perror("Open failed");
return 5;
}
fputs(ibuf, ofile);
fclose(ofile);
} else {
puts(dbuf);
puts(ibuf);
}
close(outptr);
if (arguments.overwrite)
rename(tmpfilename, argv[arg_index]);
return 0;
}