forked from contiki-os/contiki
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmakefsdata
executable file
·375 lines (355 loc) · 14.1 KB
/
makefsdata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
#!/usr/bin/perl
#Generate a .c source that preinitializes a file system
#David Kopf <[email protected]> July 2009
#Extended from the existing non-coffee tool
#The simplest format is used with httpd-fs.c. It contains a linked
#list pointing to file names and file contents.
#An extension uses the same linked list that points to a the file names
#and contents within a coffee file system having fixed file sizes.
#This allows the content to be rewritten by coffee while still being
#readable by httpd-fs.c New files or sector extension of existing files
#is not possible, but a larger initial sector allocation could be given
#to some files to allow a limited size increase. Since this would leave the
#wrong file size in the linked list, httpd-fs would have to terminate on
#a reverse zero scan like coffee does. Rewriting the linked list would
#probably be OK if in eeprom, but not if in program flash. Suggestions
#for a workaround would be welcome!
#Lastly a full coffee file system can be preinitialized. File reads must
#then be done using coffee.
#Assumes the coffee file_header structure is
#struct file_header {
# coffee_page_t log_page;
# uint16_t log_records;
# uint16_t log_record_size;
# coffee_page_t max_pages;
# uint8_t deprecated_eof_hint;
# uint8_t flags=3 for the initial value;
# char name[COFFEE_NAME_LENGTH];
# } __attribute__((packed));
goto DEFAULTS;
START:$version="1.1";
#Process options
for($n=0;$n<=$#ARGV;$n++) {
$arg=$ARGV[$n];
if ($arg eq "-v") {
print "makefsdata Version $version\n";
} elsif ($arg eq "-A") {
$n++;$attribute=$ARGV[$n];
} elsif ($arg eq "-C") {
$coffee=1;
} elsif ($arg eq "-c") {
$complement=1;
} elsif ($arg eq "-i") {
$n++;$includefile=$ARGV[$n];
# } elsif ($arg eq "-p") {
# $n++;$coffee_page_length=$ARGV[$n];
} elsif ($arg eq "-s") {
$n++;$coffee_sector_size=$ARGV[$n];
} elsif ($arg eq "-t") {
$n++;$coffee_page_t =$ARGV[$n];
} elsif ($arg eq "-f") {
$n++;$coffee_name_length=$ARGV[$n];
} elsif ($arg eq "-S") {
$n++;$sectionname=$ARGV[$n];
} elsif ($arg eq "-l") {
$linkedlist=1;
} elsif ($arg eq "-d") {
$n++;$directory=$ARGV[$n];
} elsif ($arg eq "-o") {
$n++;$outputfile=$ARGV[$n];
$coffeefile=$outputfile;
} else {
DEFAULTS:
#Set up defaults
$coffee=0;
#$coffee_page_length=256;
$coffee_sector_size=256;
$coffee_page_t=1;
$coffee_name_length=16;
$complement=0;
$directory="";
$outputfile="httpd-fsdata.c";
$coffeefile="httpd-coffeedata.c";
$includefile="makefsdata.h";
$linkedlist=0;
$attribute="";
$sectionname=".coffeefiles";
if (!$version) {goto START;}
print "\n";
print "Usage: makefsdata <option(s)> <-d input_directory> <-o output_file>\n\n";
print " Generates c source file to pre-initialize a contiki file system.\n";
print " The default output is a simple linked list readable by httpd-fs.c\n";
print " and written to $outputfile.\n\n";
print " The -C option makes a coffee file system to default output $coffeefile.\n";
print " A linked list can be still be generated for use with httpd-fs.c so long\n";
print " as coffee does not extend, delete, or add any files.\n\n";
print " The input directory structure is copied. If input_directory is specified\n";
print " it becomes the root \"/\". If no input_directory is specified the first\n";
print " subdirectory found in the current directory is used as the root.\n\n";
print " WARNING : If the output file exists it will be overwritten without confirmation!\n\n";
print " Options are:\n";
print " -v Display the version number\n";
print " -A attribute Append \"attribute\" to the declaration, e.g. PROGMEM to put data in AVR program flash memory\n";
print " -C Use coffee file system format\n";
print " -c Complement the data, useful for obscurity or fast page erases for coffee\n";
print " -i filename Treat any input files with name \"filename\" as include files.\n";
print " Useful for giving a server a name and ip address associated with the web content.\n";
print " The default is $includefile.\n\n";
print " The following apply only to coffee file system\n";
# print " -p pagesize Page size in bytes (default $coffee_page_length)\n";
print " -s sectorsize Sector size in bytes (default $coffee_sector_size)\n";
print " -t page_t Number of bytes in coffee_page_t (1,2,or 4, default $coffee_page_t)\n";
print " -f namesize File name field size in bytes (default $coffee_name_length)\n";
print " -S section Section name for data (default $sectionname)\n";
print " -l Append a linked list for use with httpd-fs\n";
exit;
}
}
#--------------------Configure parameters-----------------------
if ($coffee) {
$outputfile=$coffeefile;
$coffee_header_length=2*$coffee_page_t+$coffee_name_length+6;
if ($coffee_page_t==1) {
$coffeemax=0xff;
} elsif ($coffee_page_t==2) {
$coffeemax=0xffff;
} elsif ($coffee_page_t==4) {
$coffeemax=0xffffffff;
} else {
die "Unsupported coffee_page_t $coffee_page_t\n";
}
} else {
# $coffee_page_length=1;
$coffee_sector_size=1;
$linkedlist=1;
$coffee_name_length=256;
$coffee_max=0xffffffff;
$coffee_header_length=0;
}
$null="0x00";if ($complement) {$null="0xff";}
$tab=" "; #optional tabs or spaces at beginning of line, e.g. "\t\t"
#--------------------Create output file-------------------------
#awkward but could not figure out how to compare paths later unless the file exists -- dak
if (!open(OUTPUT, "> $outputfile")) {die "Aborted: Could not create output file $outputfile";}
print(OUTPUT "\n");
close($outputfile);
use Cwd qw(abs_path);
if (!open(OUTPUT, "> $outputfile")) {die "Aborted: Could not create output file $outputfile";}
$outputfile=abs_path($outputfile);
#--------------------Get a list of input files------------------
if ($directory eq "") {
opendir(DIR, ".");
@files = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);
closedir(DIR);
foreach $file (@files) {
if(-d $file && $file !~ /^\./) {
$directory=$file;
break;
}
}
}
if ($directory eq "") {die "Aborted: No subdirectory in current directory";}
if (!chdir("$directory")) {die "Aborted: Directory \"$directory\" does not exist!";}
if ($coffee) {
print "Processing directory $directory as root of coffee file system\n";
} else {
print "Processing directory $directory as root of packed httpd-fs file system\n";
}
opendir(DIR, ".");
@files = grep { !/^\./ && !/(CVS|~)/ && !/(makefsdata.ignore)/ } readdir(DIR);
closedir(DIR);
foreach $file (@files) {
if(-d $file && $file !~ /^\./) {
print "Adding subdirectory $file\n";
opendir(DIR, $file);
@newfiles = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);
closedir(DIR);
# printf "Adding files @newfiles\n";
@files = (@files, map { $_ = "$file/$_" } @newfiles);
next;
}
}
#--------------------Write the output file-------------------
print "Writing to $outputfile\n";
($DAY, $MONTH, $YEAR) = (localtime)[3,4,5];
printf(OUTPUT "/*********Generated by contiki/tools/makefsdata on %04d-%02d-%02d*********/\n", $YEAR+1900, $MONTH+1, $DAY);
if ($coffee) {
print(OUTPUT "/*For coffee filesystem of sector size $coffee_sector_size and header length $coffee_header_length bytes*/\n");
}
print(OUTPUT "\n");
#--------------------Process include file-------------------
foreach $file (@files) {if ($file eq $includefile) {
open(FILE, $file) || die "Aborted: Could not open include file $file\n";
print "Including text from $file\n";
$file_length= -s FILE;
read(FILE, $data, $file_length);
print OUTPUT ($data);
close(FILE);
next; #include all include file matches
# break; #include only first include file match
}}
#--------------------Process data files-------------------
$n=0;$coffeesize=0;$coffeesectors=0;
foreach $file (@files) {if(-f $file) {
if (length($file)>=($coffee_name_length-1)) {die "Aborted: File name $file is too long";}
if (abs_path("$file") eq abs_path("$outputfile")) {
print "Skipping output file $outputfile - recursive input NOT allowed\n";
next;
}
if ($file eq $includefile) {next;}
open(FILE, $file) || die "Aborted: Could not open file $file\n";
print "Adding /$file\n";
if (grep /.png/||/.jpg/||/jpeg/||/.pdf/||/.gif/||/.bin/||/.zip/,$file) {binmode FILE;}
$file_length= -s FILE;
$file =~ s-^-/-;
$fvar = $file;
$fvar =~ s-/-_-g;
$fvar =~ s-\.-_-g;
if ($coffee) {
$coffee_sectors=int(($coffee_header_length+$file_length+$coffee_sector_size-1)/$coffee_sector_size);
# $coffee_sectors=sprintf("%.0f",($coffee_header_length+$file_length+$coffee_sector_size-1)/$coffee_sector_size)-1;
$coffee_length=$coffee_sectors*$coffee_sector_size;
} else {
$coffee_length=$file_length+length($file)+1;
}
$flen[$n]=$file_length;
$clen[$n]=$coffee_length;
$n++;$coffeesectors+=$coffee_sectors;$coffeesize+=$coffee_length;
if ($coffee) {
if ($coffeesectors>$coffeemax) {
print "Warning: sector number $coffeesectors overflows allocated sector size in coffee header\n";
}
print(OUTPUT "\n__attribute__ ((section (\"$sectionname\")))\n");
print(OUTPUT "volatile const char data".$fvar."[$coffee_length] = {\n");
} else {
print(OUTPUT "\nconst char data".$fvar."[$coffee_length] $attribute = {\n");
}
print(OUTPUT "$tab/* $file */\n$tab");
#--------------------Header-----------------------------
#log_page
if ($coffee) {
print (OUTPUT " ");
for($j=0;$j<$coffee_page_t;$j++) {print (OUTPUT "$ null ,");}
#log_records, log_record_size
for($j=0;$j<4;$j++) {print (OUTPUT "$null, ");}
#max_pages
if ($complement) {$coffee_sectors=$coffee_sectors^0xffffffff;}
if ($coffee_page_t==1) {
printf(OUTPUT "0x%2.2x, ",($coffee_sectors )&0xff);
} elsif ($coffee_page_t==2) {
printf(OUTPUT "0x%2.2x, ",($coffee_sectors>> 8)&0xff);
printf(OUTPUT "0x%2.2x, ",($coffee_sectors )&0xff);
} elsif ($coffee_page_t==4) {
printf(OUTPUT "0x%2.2x, ",($coffee_sectors>>24)&0xff);
printf(OUTPUT "0x%2.2x, ",($coffee_sectors>>16)&0xff);
printf(OUTPUT "0x%2.2x, ",($coffee_sectors>> 8)&0xff);
printf(OUTPUT "0x%2.2x, ",($coffee_sectors )&0xff);
}
if ($complement) {$coffee_sectors=$coffee_sectors^0xffffffff;}
#eof hint and flags
if ($complement) {
print(OUTPUT "0xff, 0xfc,\n$tab");
} else {
print(OUTPUT "0x00, 0x03,\n$tab");
}
}
#-------------------File name--------------------------
for($j = 0; $j < length($file); $j++) {
$temp=unpack("C", substr($file, $j, 1));
if ($complement) {$temp=$temp^0xff;}
printf(OUTPUT " %#02.2x,", $temp);
}
if ($coffee) {
for(; $j < $coffee_name_length-1; $j++) {printf(OUTPUT " $null,");}
{print(OUTPUT " $null");}
} else {
{printf(OUTPUT " $null");}
}
#------------------File Data---------------------------
$coffee_length-=$coffee_header_length;
$i = 10;
while(read(FILE, $data, 1)) {
$temp=unpack("C", $data);
if ($complement) {$temp=$temp^0xff;}
if($i == 10) {
printf(OUTPUT ",\n$tab 0x%2.2x", $temp);
$i = 0;
} else {
printf(OUTPUT ", 0x%2.2x", $temp)
}
$i++;$coffee_length--;
}
if ($coffee) {
print (OUTPUT ",");
while (--$coffee_length) {
if($i==9) {
print(OUTPUT " $null,\n$tab");
$i = 0;
} else {
print (OUTPUT " $null,");
$i++;
}
}
print (OUTPUT " $null");
}
print (OUTPUT "};\n");
close(FILE);
push(@fvars, $fvar);
push(@pfiles, $file);
}}
if ($linkedlist) {
#-------------------httpd_fsdata_file links-------------------
#The non-coffee PROGMEM flash file system for the Raven webserver uses a linked flash list as follows:
print(OUTPUT "\n\n/* Structure of linked list (all offsets relative to start of section):\n");
print(OUTPUT "struct httpd_fsdata_file {\n");
print(OUTPUT "$tab const struct httpd_fsdata_file *next; //actual flash address of next link\n");
print(OUTPUT "$tab const char *name; //offset to coffee file name\n");
print(OUTPUT "$tab const char *data; //offset to coffee file data\n");
print(OUTPUT "$tab const int len; //length of file data\n");
print(OUTPUT "#if HTTPD_FS_STATISTICS == 1 //not enabled since list is in PROGMEM\n");
print(OUTPUT "$tab uint16_t count; //storage for file statistics\n");
print(OUTPUT "#endif\n");
print(OUTPUT "}\n*/\n");
# For the static httpd-fs.c file system the file name and data addresses in the linked list
# point to the actual memory locations.
# For the coffee file system the addresses start from zero. The starting address must be added
# in the coffee read routine.
for($i = 0; $i < @fvars; $i++) {
$file = $pfiles[$i];
$fvar = $fvars[$i];
if($i == 0) {
$prevfile = "NULL";
$data_offset=0;
} else {
$data_offset=$data_offset+$clen[$i-1];
$prevfile = "file" . $fvars[$i - 1];
}
$filename_offset=$data_offset+6+2*$coffee_page_t;
$coffee_offset=$data_offset+$coffee_header_length;
if ($coffee_offset>0xffff) {print "Warning : Linked list offset field overflow\n";}
print(OUTPUT "const struct httpd_fsdata_file");
for ($t=length($file);$t<16;$t++) {print(OUTPUT " ")};
print(OUTPUT " file".$fvar."[] ");
if ($attribute) {print(OUTPUT "$attribute ");}
print(OUTPUT "={{");
for ($t=length($prevfile);$t<20;$t++) {print(OUTPUT " ")};
print(OUTPUT "$prevfile, ");
if ($coffee) {
printf(OUTPUT "(const char *)0x%4.4x, ",$filename_offset);
printf(OUTPUT "(const char *)0x%4.4x, ",$coffee_offset);
printf(OUTPUT "%5u}};\n",$flen[$i]);
} else {
print(OUTPUT "data$fvar");
for ($t=length($file);$t<15;$t++) {print(OUTPUT " ")};
print(OUTPUT ", data$fvar");
for ($t=length($file);$t<15;$t++) {print(OUTPUT " ")};
print(OUTPUT " +".(length($file)+1).", sizeof(data$fvar)");
for ($t=length($file);$t<16;$t++) {print(OUTPUT " ")};
print(OUTPUT " -".(length($file)+1)."}};\n");
}
}
print(OUTPUT "\n#define HTTPD_FS_ROOT file$fvars[$n-1]\n");
print(OUTPUT "#define HTTPD_FS_NUMFILES $n\n");
print(OUTPUT "#define HTTPD_FS_SIZE $coffeesize\n");
}
print "All done, files occupy $coffeesize bytes\n";