#include #include #include #include #include /* Jedna z možností jak dostat data do externí flash. Sice to poněkud * nabobtná (na začátku je zbytečně celá struktura SayedTexts + padding), * ale funguje to. * 1. zdroják melofy.c se přeloží a pomocí linker skriptu se vytvoří elf * 2. z elf se udělá binárka, příp. hex soubor standardním binutils * 3. binárka se tímto přečte a do extdata.c se extrahují potřebné informace. * extdata.c pak obsahuje adresy meloddií potřebné pro čtení. * Nezávisí to na tom, zda se binárka vytváří na 64. nebo 32. bit stroji. */ class Reader { unsigned char * file_data; int file_size; public: explicit Reader() : file_data(nullptr), file_size(0) {} ~Reader() { if (file_data) delete [] file_data; } int process (const char * filename); protected: void check (); void generate(); }; int Reader::process(const char * filename) { struct stat statbuf; int r = ::stat(filename, &statbuf); if (r < 0) return -1; if (file_data) delete [] file_data; file_data = new unsigned char [statbuf.st_size]; FILE * in_file = fopen(filename, "r"); r = fread (file_data, 1, statbuf.st_size, in_file); file_size = r; printf("readen %d bytes (%g 0x1000 blocks)\n", file_size, double(file_size)/4096.0); if (!in_file) return -1; fclose(in_file); check(); // kontrola - mělo by sedět to co je v data.bin a přeložené melody.c generate(); // generuje C-soubor s adresami a počty rámců return 0; } void Reader::check() { if (!file_size) return; } // Jen toto je podstatné - vytvoření extdata.c static const char * prefix = R"---(/* GENERATED FILE DO NOT EDIT */ const unsigned scores [] = {)---"; void Reader::generate() { FILE * out = fopen("extdata.c","w"); fprintf(out, "%s", prefix); uint32_t * ptr = reinterpret_cast(file_data); for (unsigned n=0; ; n++) { if ((n%8) == 0) fprintf(out, "\n"); const size_t e = ptr[n]; fprintf(out, " 0x%06lXu,", e); if (e == 0lu) break; } fprintf(out, "\n};\n"); fclose(out); } /// main () int main (int argc, char *argv[]) { Reader read; return read.process("data.bin"); }