1srec_examples(1) i srec_examples(1)
2
3
4
6 srec_examples - examples of how to use SRecord
7
9 The srec_cat command is very powerful, due to the ability to combine
10 the the input filters in almost unlimited ways. This manual page
11 describes a few of them.
12
13 This manual page describes how to use the various input files, input
14 filters and input generators. But these are only examples, for more
15 complete details, see the srec_input(1) manual page.
16
17 The Commands Lines Are Too Long
18 If you are marooned on an operating system with absurdly short command
19 line length limits, some of the commands which follow may be too long.
20 You can get around this handicap by placing your command line in a
21 file, say fred.txt, and then tell srec_cat(1) to read this file for the
22 rest of its command line, like this
23
24 srec_cat @fred.txt
25
26 This also has the advantage of allowing comments, allowing you to write
27 your command line options over several lines, and even indenting to
28 make the command more clear. Comments start at a “#” and extend to the
29 end of the line. Blank lines are ignored.
30
31 Of course, you could always upgrade to Linux, which has been sucking
32 less for over 27 years now.
33
34 Your Examples Wanted
35 If you have a clever way of using SRecord, or have solved a difficult
36 problem with SRecord, you could contribute to this manual page, making
37 it more useful for everyone. Send your example in an email to the
38 email address at the end of this manual page.
39
41 The simplest of the things srec_cat(1) can do is convert from one EPROM
42 file format to another. Please keep in mind, as you read this section,
43 that you can do many of these things simultaneously in one command.
44 They are only broken out separately to make them easier to understand.
45
46 Intel to Motorola
47 One of the simplest examples is converting files from Intel hex format
48 to Motorola S‐Record format:
49
50 srec_cat intel‐file -intel -o srec‐file
51
52 Note that the format specifier immediately follows the name of the file
53 it is describing. Pick any two formats that SRecord understands, and
54 it can convert between all of them. (Except the assembler, BASIC, C
55 and FPGA outputs which are write only.)
56
57 Motorola to Intel
58 Converting the other way is just as simple:
59
60 srec_cat srec‐file -o intel‐file -intel
61
62 The default format is Motorola S‐Record format, so it does not need to
63 be specified after the file name.
64
65 Different Shapes of the Same Format
66 It is regrettably common that some addle‐pated EPROM programmers only
67 implement a portion of the specification used to represent their hex
68 files. For example, some compilers produce “s19” Motorola data (that
69 is, S1 data records with S9 start records, 16 bit address fields) which
70 would be OK except that some blockhead EPROM programmers insist on
71 “s37” Motorola data (that is, S3 data records with S7 start records, 32
72 bit address fields).
73
74 It is possible to convert from one Motorola shape to another using the
75 -Address‐Length option:
76
77 srec_cat short.srec -o long.srec -address‐length=4
78
79 This command says to use four byte (32‐bit) addresses on output.
80
81 This section also applies to Intel hex files, as they, too, have the
82 ability to select from a variety of address widths. To convert from
83 one Intel shape to another using the same -Address‐Length option:
84
85 srec_cat i32.hex -o i16.hex -address‐length=3
86
87 This command says to use “i16hex” 20‐bit segmented addresses on output.
88 An address length of 4 is the default (“i32hex” 32‐bit linear address‐
89 ing), and an address length of 2 would request “i8hex” 16‐bit address‐
90 ing.
91
92 Line Lengths
93 From time to time you will come across a feeble‐minded EPROM programmer
94 that can't cope with long text lines, they assume that there will only
95 ever be 46 characters per line and barf when they see the default line
96 lengths that srec_cat(1) writes (or worse, get a stack scribble and
97 crash).
98
99 The Motorola S‐record format definition permits up to 255 bytes of pay‐
100 load, or lines of 514 characters, plus the line termination. All EPROM
101 programmers should have sufficiently large line buffers to cope with
102 records this big. Few do.
103
104 The -line‐length option may be used to specify the maximum line length
105 (not including the newline) to be used on output. For example, 16 byte
106 payloads for Motorola hex
107
108 srec_cat long.srec -o short.s19 -line‐length=46
109
110 The line length option interacts with the address length option, so
111 some tinkering to optimize for your particular situation many be neces‐
112 sary.
113
114 Output Block Size
115 Every once in a while you will come across an ancient daft EPROM pro‐
116 grammer that can't cope with long data records, they assume that there
117 will only ever be at most 16 bytes of data per record, and barf when
118 they see the default 32 byte payloads that srec_cat(1) writes (or
119 worse, the buffer over‐run causes a tall grass walk that scribbles on
120 your EPROM).
121
122 The Intel hex format definition permits up to 255 bytes of payload data
123 per record. All EPROM programmers should have sufficiently large data
124 buffers to cope with records this big. Good luck with that.
125
126 The -Output‐Block‐Size option may be used to specify the record data
127 size to be used on output. For example, Intel hex with 16 byte pay‐
128 loads:
129
130 srec_cat long.srec -o short.hex -intel -obs=16
131
132 Be careful not to put the -obs option between the output file name and
133 the format specifier.
134
135 Just the Data, Please
136 There are some bonehead EPROM programmers which can only cope with data
137 records, and are unable to cope with header records or execution start
138 address records. If you have this problem, the -data‐only option can
139 be used to suppress just about everything except the data. The actual
140 effect depends on the format, of course, because some don't have these
141 features anyway.
142
143 The -data‐only option is short hand. There are four properties which
144 may be -disabled or -enabled separately. See the srec_cat(1) man page
145 for a description of the -disabled and -enabled options.
146
147 For example, your neanderthal EPROM programmer requires Motorola hex
148 with header records (S0), but without data count (S5) records. Not
149 using the -data‐only option has it barf on the data count record, but
150 using the -data‐only option has it barf on the missing header record.
151 Using the -disable=data‐count option would leave the header record
152 intact while suppressing the data count record.
153
154 Data Headers
155 The srec_cat(1) command always tries to pass through header records
156 unchanged, whenever they are present. It even tries preserve them
157 across file format changes, to the limit the file formats are capable
158 of.
159
160 If there is no file header record and you would like to add one, or you
161 wish to override an existing file header record, use the -header=string
162 option. You will need to quote the string (to insulate it from the
163 shell) if it contains spaces or shell meta‐characters.
164
165 Execution Start Addresses
166 The srec_cat(1) command always tries to pass through execution start
167 addresses (typically occurring at the end of the file), whenever they
168 are present. They are adjusted along with the data records by the
169 -offset filter. It even tries preserve them across file format
170 changes, to the limit the file formats are capable of.
171
172 If there is no execution start address record and you would like to add
173 one, or you wish to override an existing execution start address
174 record, use the -execution‐start‐address=number option.
175
176 Please note: the execution start address is a different concept than
177 the first address in memory of your data. Think of it as a “goto”
178 address to be jumped to by the monitor when the hex load is complete.
179 If you want to change where your data starts in memory, use the -offset
180 filter.
181
182 Fixing Checksums
183 Some embedded firmware developers are saddled with featherbrained tools
184 which produce incorrect checksums, which the more vigilant models of
185 EPROM programmer will not accept.
186
187 To fix the checksums on a file, use the -ignore‐checksums option. For
188 example:
189
190 srec_cat broken.srec -ignore‐checksums -o fixed.srec
191
192 The checksums in broken.srec are parsed (it is still and error if they
193 are absent) but are not checked. The resulting fixed.srec file has
194 correct checksums. The -ignore‐checksums option only applies to input.
195
196 This option may be used on any file format which has checksums, includ‐
197 ing Intel hex.
198
199 Discovering Mystery Formats
200 See the What Format Is This? section, below, for how to discover and
201 convert mystery EPROM load file formats.
202
204 It is possible to convert to and from binary files. You can even mix
205 binary files and other formats together in the same srec_cat(1) com‐
206 mand.
207
208 Writing Binary Files
209 The simplest way of reading a hex file and converting it to a binary
210 file looks like this:
211
212 srec_cat fred.hex -o fred.bin -binary
213
214 This reads the Motorola hex file fred.srec and writes it out to the
215 fred.bin as raw binary.
216
217 Note that the data is placed into the binary file at the byte offset
218 specified by the addresses in the hex file. If there are holes in the
219 data they are filled with zero. This is, of course, common with linker
220 output where the code is placed starting at a particular place in mem‐
221 ory. For example, when you have an image that starts at 0x100000, the
222 first 1MB of the output binary file will be zero.
223
224 You can automatically cancel this offset using a command like
225
226 srec_cat fred.hex -offset − -minimum‐addr fred.hex -o fred.bin
227
228 The above command works by offsetting the fred.hex file lower in memory
229 by the least address in the fred.hex file's data.
230
231 See also the srec_binary(5) man page for additional detail.
232
233 Reading Binary Files
234 The simplest way of reading a binary file and converting it looks like
235 this
236
237 srec_cat fred.bin -binary -o fred.srec
238
239 This reads the binary file fred.bin and writes all of its data back out
240 again as a Motorola S‐Record file.
241
242 Often, this binary isn't exactly where you want it in the address
243 space, because it is assumed to reside at address zero. If you need to
244 move it around use the -offset filter.
245
246 srec_cat fred.bin -binary -offset 0x10000 -o fred.srec
247
248 You also need to avoid file “holes” which are filled with zero. You
249 can use the -crop filter, of you could use the -unfill filter if you
250 don't know exactly where the data is.
251
252 srec_cat fred.bin -binary -unfill 0x00 512 -o fred.srec
253
254 The above command removes runs of zero bytes that are 512 bytes long or
255 longer. If your file contains 1GB of leading zero bytes, this is going
256 to be slow, it may be better to use the dd(1) command to slice and dice
257 first.
258
260 The srec_cat command takes its name from the UNIX cat(1) command, which
261 is short for “catenate” or “to join”. The srec_cat command joins EPROM
262 load files together.
263
264 All In One
265 Joining EPROM load files together into a single file is simple, just
266 name as many files on the command line as you need:
267
268 srec_cat infile1 infile2 -o outfile
269
270 This example is all Motorola S‐Record files, because that's the default
271 format. You can have multiple formats in the one command, and
272 srec_cat(1) will still work. You don't even have to output the same
273 format:
274
275 srec_cat infile1 -spectrum infile2 -needham \
276 -o outfile -signetics
277
278 These are all ancient formats, however it isn't uncommon to have to mix
279 and match Intel and Motorola formats in the one project.
280
281 Overlaying two data files
282 It is common to want to “join” two hex files together, without any
283 changes of address. on the assumption neither file intersects with the
284 other. This is a simple “layers”, it is quite common for linkers to
285 output the main code, and then a whole bunch of relocation and jump
286 destination, by writing a two layered files.
287 srec_cat one.he two.hex -o three.hex
288 Almost always you see an error
289 srec_cat: two.srec: 49282: contradictory 0x00000000 value (pre‐
290 vious = 0x00, this one = 0x80)
291
292 This means that the files actually intersect, they try to set the same
293 location. You can turn the error into a warning, using the -contradic‐
294 tory‐bytes=warning command line option. But this will probably gener‐
295 ate a bazillion warnings.
296
297 The necessary step is to crop the first file, to avoid the regions the
298 second file is going o be overwriting.
299 srec_cat \
300 one.srec -exclude -within two.srec \
301 two.srec -exclude -within one.srec \
302 -o three.hex
303
304 Depending on your linker this will have no errors (but if it wants
305 another layer, more jiggery‐pokery is required).
306
307 Filtering After Joining
308 There are times when you want to join two sets of data together, and
309 then apply a filter to the joined result. To do this you use parenthe‐
310 ses.
311 srec_cat \
312 '(' \
313 infile -exclude 0xFFF0 0x10000 \
314 -generate 0xFFF0 0xFFF8 -repeat‐string 'Bananas ' \
315 ')' \
316 -length‐b‐e 0xFFF8 4 \
317 -checksum‐neg‐b‐e 0xFFFC 4 4 \
318 -o outfile
319
320 The above example command catenate an input file (with the generated
321 data area excluded) with a constant string. This catenated input is
322 then filtered to add a 4‐byte length, and a 4‐byte checksum.
323
324 Joining End‐to‐End
325 All too often the address ranges in the EPROM load files will overlap.
326 You will get an error if they do. If both files start from address
327 zero, because each goes into a separate EPROM, you may need to use the
328 offset filter:
329
330 srec_cat infile1 \
331 infile2 -offset 0x80000 \
332 -o outfile
333
334 Sometimes you want the two files to follow each other exactly, but you
335 don't know the offset in advance:
336
337 srec_cat infile1 \
338 infile2 -offset -maximum‐addr infile1 \
339 -o outfile
340
341 Notice that where the was a number (0x80000) before, there is now a
342 calculation (-maximum‐addr infile1). This is possible most places a
343 number may be used (also -minimum‐addr and -range).
344
346 It is possible to copy an EPROM load file, selecting addresses to keep
347 and addresses to discard.
348
349 What To Keep
350 A common activity is to crop your data to match your EPROM location.
351 Your linker may add other junk that you are not interested in, e.g. at
352 the RAM location. In this example, there is a 1MB EPROM at the 2MB
353 boundary:
354
355 srec_cat infile -crop 0x200000 0x300000 \
356 -o outfile
357
358 The lower bound for all address ranges is inclusive, the upper bound is
359 exclusive. If you subtract them, you get the number of bytes.
360
361 Address Offset
362 Just possibly, you have a moronic EPROM programmer, and it barfs if the
363 EPROM image doesn't start at zero. To find out just where is does
364 start in memory, use the srec_info(1) command:
365
366 $ srec_info example.srec
367 Format: Motorola S‐Record
368 Header: extra‐whizz tool chain linker
369 Execution Start Address: 0x00200000
370 Data: 0x200000 - 0x32AAEF
371 $
372
373 Rather than butcher the linker command file, just offset the addresses:
374
375 srec_cat infile -crop 0x200000 0x300000 -offset −0x200000 \
376 -o outfile
377
378 Note that the offset given is negative, it has the effect of subtract‐
379 ing that value from all addresses in the input records, to form the
380 output record addresses. In this case, shifting the image back to
381 zero.
382
383 This example also demonstrates how the input filters may be chained
384 together: first the crop and then the offset, all in one command, with‐
385 out the need for temporary files.
386
387 If all you want to do is offset the data to start from address zero,
388 this can be automated, so you don't have to know the minimum address in
389 advance, by using srec_cat's ability to calculate some things on the
390 command line:
391
392 srec_cat infile -offset − -minimum‐addr infile \
393 -o outfile
394
395 Note the spaces either side of the minus sign, they are mandatory.
396
397 What To Throw Away
398 There are times when you need to exclude an small address range from an
399 EPROM load file, rather than wanting to keep a small address range.
400 The -exclude filter may be used for this purpose.
401
402 For example, if you wish to exclude the address range where the serial
403 number of an embedded device is kept, say 0x20 bytes at 0x100, you
404 would use a command like this:
405
406 srec_cat input.srec -exclude 0x100 0x120 -o output.srec
407
408 The output.srec file will have a hole in the data at the necessary
409 locations.
410
411 Note that you can have both -crop and -exclude on the same command
412 line, whichever works more naturally for your situation.
413
414 Discontinuous Address Ranges
415 Address ranges don't have to be a single range, you can build up an
416 address range using more than a single pair.
417
418 srec_cat infile -crop 0x100 0x200 0x1000 0x1200 \
419 -o outfile
420
421 This filter results in data from 0x100..0x1FF and data from
422 0x1000..0x1200 to pass through, the rest is dropped. This is is more
423 efficient than chaining a -crop and an -exclude filter together.
424
426 It is also possible to change the address of data records, both for‐
427 wards and backwards. It is also possible rearrange where data records
428 are placed in memory.
429
430 Offset Filter
431 The -offset=number filter operates on the addresses of records. If the
432 number is positive the addresses move that many bytes higher in memory,
433 negative values move lower.
434
435 srec_cat infile -crop 0x200000 0x300000 -offset −0x200000 \
436 -o outfile
437
438 The above example moves the 1MB block of data at 0x200000 down to zero
439 (the offset is negative) and discards the rest of the data.
440
441 Byte Swapping
442 There are times when the bytes in the data need to be swapped, convert‐
443 ing between big‐endian and little‐endian data usually.
444
445 srec_cat infile -byte‐swap 4 -o outfile
446
447 This reverses bytes in 32 bit values (4 bytes). The default, if you
448 don't supply a width, is to reverse bytes in 16 bit values (2 bytes).
449 You can actually use any weird value you like, it doesn't even have to
450 be a power of 2. Perhaps 64 bits (8 bytes) may be useful one day.
451
452 Binary Output
453 You need to watch out for binary files on output, because the holes are
454 filled with zeros. Your 100kB program at the top of 32‐bit addressed
455 memory will make a 4GB file. See srec_binary(5) for how understand and
456 avoid this problem, usually with the -offset filter.
457
458 Splitting an Image
459 If you have a 16‐bit data bus, but you are using two 8‐bit EPROMs to
460 hold your firmware, you can generate the even and odd images by using
461 the -SPlit filter. Assuming your firmware is in the firmware.hex file,
462 use the following:
463
464 srec_cat firmware.hex -split 2 0 -o firmware.even.hex
465 srec_cat firmware.hex -split 2 1 -o firmware.odd.hex
466
467 This will result in the two necessary EPROM images. Note that the out‐
468 put addresses are divided by the split multiple, so if your EPROM
469 images are at a particular offset (say 0x10000, in the following exam‐
470 ple), you need to remove the offset, and then replace it...
471
472 srec_cat firmware.hex \
473 -offset −0x10000 -split 2 0 \
474 -offset 0x10000 -o firmware.even.hex
475 srec_cat firmware.hex \
476 -offset −0x10000 -split 2 1 \
477 -offset 0x10000 -o firmware.odd.hex
478
479 Note how the ability to apply multiple filters simplifies what would
480 otherwise be a much longer script.
481
482 Striping
483 A second use for the -SPlit filter is memory striping.
484
485 You don't have to split into byte‐wide parts, you can choose other
486 sizes. It is common to want to convert 32‐bit wide data into two set
487 of 16‐bit wide data.
488
489 srec_cat firmware.hex -split 4 0 2 -o firmware.01.hex
490 srec_cat firmware.hex -split 4 2 2 -o firmware.23.hex
491
492 This is relatively simple to understand, but you can use even wider
493 stripes.
494
495 In this next example, the hardware requires that 512‐byte blocks alter‐
496 nate between 4 EPROMs. Generating the 4 images would be done as fol‐
497 lows:
498
499 srec_cat firmware.hex -split 0x800 0x000 0x200 -o firmware.0.hex
500 srec_cat firmware.hex -split 0x800 0x200 0x200 -o firmware.1.hex
501 srec_cat firmware.hex -split 0x800 0x400 0x200 -o firmware.2.hex
502 srec_cat firmware.hex -split 0x800 0x600 0x200 -o firmware.3.hex
503
504 Asymmetric Striping
505 A more peculiar example of striping is the Microchip dsPIC33F microcon‐
506 troller, that has a weird memory storage pattern and they are able to
507 store 3 bytes in an address that should only contain 2 bytes. The
508 result is a hex file that has zero‐filled the top byte (little‐endian),
509 and all addresses are doubled from what they are in the chip. Here is
510 an example:
511
512 S1130000000102000405060008090A000C0D0E0098
513 S1130010101112001415160018191A001C1D1E00C8
514 S1130020202122002425260028292A002C2D2E00F8
515 S1130030303132003435360038393A003C3D3E0028
516
517 To get rid of the 00 padding bytes, leaving only the 3/4 significant
518 bytes, you also use the split filter, with its additional width argu‐
519 ment, like this:
520
521 srec_cat example.srec -split 4 0 3 -o no_dross.srec
522
523 This results in a file with the 00 padding bytes removed. It looks
524 like this:
525
526 S113000000010204050608090A0C0D0E1011121451
527 S1130010151618191A1C1D1E2021222425262829EC
528 S11300202A2C2D2E30313234353638393A3C3D3E87
529
530 Notice how the addresses are 3/4 the size, as well. You can reverse
531 this using the -unsplit and -fill=0 filters.
532
533 Unsplit ING Images
534 The unsplit filter may be used to reverse the effects of the split fil‐
535 ter. Note that the address range is expanded leaving holes between the
536 stripes. By using all the stripes, the complete input is reassembled,
537 without any holes.
538
539 srec_cat -o firmware.hex \
540 firmware.even.hex -unsplit 2 0 \
541 firmware.odd.hex -unsplit 2 1
542
543 The above example reverses the previous 16‐bit data bus example. In
544 general, you unsplit with the same parameters that you split with.
545
547 Often EPROM load files will have “holes” in them, places where the com‐
548 piler and linker did not put anything. For some purposes this is OK,
549 and for other purposes something has to be done about the holes.
550
551 The Fill Filter
552 It is possible to fill the blanks where your data does not lie. The
553 simplest example of this fills the entire EPROM:
554
555 srec_cat infile -fill 0x00 0x200000 0x300000 -o outfile
556
557 This example fills the holes, if any, with zeros. You must specify a
558 range - with a 32‐bit address space, filling everything generates huge
559 load files.
560
561 If you only want to fill the gaps in your data, and don't want to fill
562 the entire EPROM, try:
563
564 srec_cat infile -fill 0x00 -over infile -o outfile
565
566 This example demonstrates the fact that wherever an address range may
567 be specified, the -over and -within options may be used.
568
569 Unfilling the Blanks
570 It is common to need to “unfill” an EPROM image after you read it out
571 of a chip. Usually, it will have had all the holes filled with 0xFF
572 (areas of the EPROM you don't program show as 0xFF when you read them
573 back).
574
575 To get rid of all the 0xFF bytes in the data, use this filter:
576
577 srec_cat infile -unfill 0xFF -o outfile
578
579 This will get rid of all the 0xFF bytes, including the ones you actu‐
580 ally wanted in there. There are two ways to deal with this. First,
581 you can specify a minimum run length to the un‐fill:
582
583 srec_cat infile -unfill 0xFF 5 -o outfile
584
585 This says that runs of 1 to 4 bytes of 0xFF are OK, and that a hole
586 should only be created for runs of 5 or more 0xFF bytes in a row. The
587 second method is to re‐fill over the intermediate gaps:
588
589 srec_cat outfile -fill 0xFF -over outfile \
590 -o outfile2
591
592 Which method you choose depends on your needs, and the shape of the
593 data in your EPROM. You may need to combine both techniques.
594
595 Address Range Padding
596 Some data formats are 16 bits wide, and automatically fill with 0xFF
597 bytes if it is necessary to fill out the other half of a word which is
598 not in the data. If you need to fill with a different value, you can
599 use a command like this:
600
601 srec_cat infile -fill 0x0A \
602 -within infile -range‐padding 2 \
603 -o outfile
604
605 This gives the fill filter an address range calculated from details of
606 the input file. The address range is all the address ranges covered by
607 data in the infile, extended downwards (if necessary) at the start of
608 each sub‐range to a 2 byte multiple and extended upwards (if necessary)
609 at the end of each sub‐range to a 2 byte multiple. This also works for
610 larger multiples, like 1kB page boundaries of flash chips. This
611 address range padding works anywhere an address range is required.
612
613 Fill with Copyright
614 It is possible to fill unused portions of your EPROM with a repeating
615 copyright message. Anyone trying to reverse engineer your EPROMs is
616 going to see the copyright notice in their hex editor.
617
618 This is accomplished with two input sources, one from a data file, and
619 one which is generated on‐the‐fly.
620
621 srec_cat infile \
622 -generate '(' 0 0x100000 -minus -within infile ')' \
623 -repeat‐string 'Copyright (C) 1812 Tchaikovsky. ' \
624 -o outfile
625
626 Notice the address range for the data generation: it takes the address
627 range of your EPROM, in this case 1MB starting from 0, and subtracts
628 from it the address ranges used by the input file.
629
630 If you want to script this with the current year (because 1812 is a bit
631 out of date) use the shell's output substitution (back ticks) ability:
632
633 srec_cat infile \
634 -generate '(' 0 0x100000 -minus -within infile ')' \
635 -repeat‐string "Copyright (C) `date +%Y` Tchaikovsky. " \
636 -o outfile
637
638 The string specified is repeated over and over again, until it has
639 filled all the holes.
640
641 Obfuscating with Noise
642 Sometimes you want to fill your EPROM images with noise, to conceal
643 where the real data stops and starts. You can do this with the -ran‐
644 dom‐fill filter.
645
646 srec_cat infile -random‐fill 0x200000 0x300000 \
647 -o outfile
648
649 It works just like the -fill filter, but uses random numbers instead of
650 a constant byte value.
651
652 Fill With 16‐bit Words
653 When filling the image with a constant byte value doesn't work, and you
654 need a constant 16‐bit word value instead, use the -repeat‐data genera‐
655 tor, which takes an arbitrarily long sequence of bytes to use as the
656 fill pattern:
657
658 srec_cat infile \
659 -generator '(' 0x200000 0x300000 -minus -within infile ')' \
660 -repeat‐data 0x1B 0x08 \
661 -o outfile
662
663 Notice how the generator's address range once again avoids the address
664 ranges occupied by the infile's data. You have to get the endian‐ness
665 right yourself.
666
668 From time to time you will want to insert constant data, or data not
669 produced by your compiler or assembler, into your EPROM load images.
670
671 Binary Means Literal
672 One simple way is to have the desired information in a file. To insert
673 the file's contents literally, with no format interpretation, use the
674 binary input format:
675
676 srec_cat infile -binary -o outfile
677
678 It will probably be necessary to use an offset filter to move the data
679 to where you actually want it within the image:
680
681 srec_cat infile -binary -offset 0x1234 -o outfile
682
683 It is also possible to use the standard input as a data source, which
684 lends itself to being scripted. For example, to insert the current
685 date and time into an EPROM load file, you could use a pipe:
686
687 date | srec_cat - -bin -offset 0xFFE3 -o outfile
688
689 The special file name “-” means to read from the standard input. The
690 output of the date command is always 29 characters long, and the offset
691 shown will place it at the top of a 64KB EPROM image.
692
693 Repeating Once
694 The Fill with Copyright section, above, shows how to repeat a string
695 over and over. We can use a single repeat to insert a string just
696 once.
697
698 srec_cat -generate 0xFFE3 0x10000 -repeat‐string "`date`" \
699 -o outfile
700
701 Notice how the address range for the data generation exactly matches
702 the length of the date(1) output size. You can, of course, add your
703 input file to the above srec_cat(1) command to catenate your EPROM
704 image together with the date and time.
705
706 Inserting A Long
707 Another possibility is to add the Subversion commit number to your
708 EPROM image. In this example, we are inserting it a a 4‐byte little‐
709 endian value at address 0x0008. The Subversion commit number is in the
710 $version shell variable in this example:
711
712 srec_cat -generate 0x0008 0x000C -constant‐l‐e $version 4 \
713 infile -exclude 0x0008 0x000C \
714 -o outfile
715
716 Note that we use a filter to ensure there is a hole in the input where
717 the version number goes, just in case the linker put something there.
718
720 It is possible to add a variety of data about the data to the output.
721
722 Checksums
723 The -checksum‐negative‐big‐endian filter may be used to sum the data,
724 and then insert the negative of the sum into the data. This has the
725 effect of summing to zero when the checksum itself is summed across,
726 provided the sum width matches the inserted value width.
727
728 srec_cat infile \
729 -crop 0 0xFFFFFC \
730 -random‐fill 0 0xFFFFFC \
731 -checksum‐neg‐b‐e 0xFFFFFC 4 4 \
732 -o outfile
733
734 In this example, we have an EPROM in the lowest megabyte of memory.
735 The -crop filter ensures we are only summing the data within the EPROM,
736 and not anywhere else. The -random‐fill filter fills any holes left in
737 the data with random values. Finally, the -checksum‐neg‐b‐e filter
738 inserts a 32 bit (4 byte) checksum in big‐endian format in the last 4
739 bytes of the EPROM image. Naturally, there is a little‐endian version
740 of this filter as well.
741
742 Your embedded code can check the EPROM using C code similar to the fol‐
743 lowing:
744
745 unsigned long *begin = (unsigned long *)0;
746 unsigned long *end = (unsigned long *)0x100000;
747 unsigned long sum = 0;
748 while (begin < end)
749 sum += *begin++;
750 if (sum != 0)
751 {
752 Oops
753 }
754
755 The -checksum‐bitnot‐big‐endian filter is similar, except that summing
756 over the checksum should yield a value of all‐one‐bits (−1). For exam‐
757 ple, using shorts rather than longs:
758
759 srec_cat infile \
760 -crop 0 0xFFFFFE \
761 -fill 0xCC 0x00000 0xFFFFFE \
762 -checksum‐neg‐b‐e 0xFFFFFE 2 2 \
763 -o outfile
764
765 Assuming you chose the correct endian‐ness filter, your embedded code
766 can check the EPROM using C code similar to the following:
767
768 unsigned short *begin = (unsigned short *)0;
769 unsigned short *end = (unsigned short *)0x100000;
770 unsigned short sum = 0;
771 while (begin < end)
772 sum += *begin++;
773 if (sum != 0xFFFF)
774 {
775 Oops
776 }
777
778 There is also a -checksum‐positive‐b‐e filter, and a matching little‐
779 endian filter, which inserts the simple sum, and which would be checked
780 in C using an equality test.
781
782 srec_cat infile \
783 -crop 0 0xFFFFFF \
784 -fill 0x00 0x00000 0xFFFFFF \
785 -checksum‐neg‐b‐e 0xFFFFFF 1 1 \
786 -o outfile
787
788 Assuming you chose the correct endian‐ness filter, your embedded code
789 can check the EPROM using C code similar to the following:
790
791 unsigned char *begin = (unsigned char *)0;
792 unsigned char *end = (unsigned char *)0xFFFFF;
793 unsigned char sum = 0;
794 while (begin < end)
795 sum += *begin++;
796 if (sum != *end)
797 {
798 Oops
799 }
800
801 In the 8‐bit case, it doesn't matter whether you use the big‐endian or
802 little‐endian filter.
803
804 Quick Hex‐Dump
805 You can look at the checksum of your data, by using the “hex‐dump” out‐
806 put format. This is useful for looking at calculated values, or for
807 debugging an srec_cat(1) command before immortalizing it in a script.
808
809 srec_cat infile \
810 -crop 0 0x10000 \
811 -fill 0xFF 0x0000 0x10000 \
812 -checksum‐neg‐b‐e 0x10000 4 \
813 -crop 0x10000 0x10004 \
814 -o - -hex‐dump
815
816 This command reads in the file, checksums the data and places the
817 checksum at 0x10000, crops the result to contain only the checksum, and
818 then prints the checksum on the standard output in a classical hexadec‐
819 imal dump format. The special file name “-” means “the standard out‐
820 put” in this context.
821
822 Cyclic Redundancy Checks
823 The simple additive checksums have a number of theoretical limitations,
824 to do with errors they can and can't detect. The CRC methods have
825 fewer problems.
826
827 srec_cat infile \
828 -crop 0 0xFFFFFC \
829 -fill 0x00 0x00000 0xFFFFFC \
830 -crc32‐b‐e 0xFFFFFC \
831 -o outfile
832
833 In the above example, we have an EPROM in the lowest megabyte of mem‐
834 ory. The -crop filter ensures we are only summing the data within the
835 EPROM, and not anywhere else. The -fill filter fills any holes left in
836 the data. Finally, the -checksum‐neg‐b‐e filter inserts a 32 bit (4
837 byte) checksum in big‐endian format in the last 4 bytes of the EPROM
838 image. Naturally, there is a little‐endian version of this filter as
839 well.
840
841 The checksum is calculated using the industry standard 32‐bit CRC.
842 Because SRecord is open source, you can always read the source code to
843 see how it works. There are many non‐GPL versions of this code avail‐
844 able on the Internet, and suitable for embedding in proprietary
845 firmware.
846
847 There is also a 16‐bit CRC available.
848
849 srec_cat infile \
850 -crop 0 0xFFFFFE \
851 -fill 0x00 0x00000 0xFFFFFE \
852 -crc16‐b‐e 0xFFFFFE \
853 -o outfile
854
855 The checksum is calculated using the CCITT formula. Because SRecord is
856 open source, you can always read the source code to see how it works.
857 There are many non‐GPL version of this code available on the Internet,
858 and suitable for embedding in proprietary firmware.
859
860 You can look at the CRC of your data, by using the “hex‐dump” output
861 format.
862
863 srec_cat infile \
864 -crop 0 0x10000 \
865 -fill 0xFF 0x0000 0x10000 \
866 -crc16‐b‐e 0x10000 \
867 -crop 0x10000 0x10002 \
868 -o - -hex‐dump
869
870 This command reads in the file, calculates the CRC of the data and
871 places the CRC at 0x10000, crops the result to contain only the CRC,
872 and then prints the checksum on the standard output in a classical
873 hexadecimal dump format.
874
875 Where Is My Data?
876 There are several properties of your EPROM image that you may wish to
877 insert into the data.
878
879 srec_cat infile -minimum‐b‐e 0xFFFE 2 -o outfile
880
881 The above example inserts the minimum address of the data (low water)
882 into the data, as two bytes in big‐endian order at address 0xFFFE.
883 This includes the minimum itself. If the data already contains bytes
884 at the given address, you need to use an exclude filter. The number of
885 bytes defaults to 4.
886
887 There is also a -minimum‐l‐e filter for inserting little‐endian values,
888 and two more filters called -exclusive‐minimum‐b‐e and -exclusive‐mini‐
889 mum‐l‐e that do not include the minimum itself in the calculation of
890 the minimum data address.
891
892 srec_cat infile -maximum‐b‐e 0xFFFFFC 4 -o outfile
893
894 The above example inserts the maximum address of the data (high water +
895 1, just like address ranges) into the data, as four bytes in big‐endian
896 order at address 0xFFFFFC. This includes the maximum itself. If the
897 data already contains bytes at the given address, you need to use an
898 -exclude filter. The number of bytes defaults to 4.
899
900 There is also a -maximum‐l‐e filter for inserting little‐endian values,
901 and two more filters called -exclusive‐maximum‐b‐e and -exclusive‐maxi‐
902 mum‐l‐e that do not include the maximum itself in the calculation of
903 the maximum data address.
904
905 srec_cat infile -length‐b‐e 0xFFFFFC 4 -o outfile
906
907 The above example inserts the length of the data (high water + 1 − low
908 water) into the data, as four bytes in big‐endian order at address
909 0xFFFFFC. This includes the length itself. If the data already con‐
910 tains bytes at the length location, you need to use an -exclude filter.
911 The number of bytes defaults to 4.
912
913 There is also a -length‐l‐e filter for inserting a little‐endian
914 length, and the -exclusive‐length‐b‐e and -exclusive‐length‐l‐e filters
915 that do not include the length itself in the calculation.
916
917 What Format Is This?
918 You can obtain a variety of information about an EPROM load file by
919 using the srec_info(1) command. For example:
920
921 $ srec_info example.srec
922 Format: Motorola S‐Record
923 Header: "http://srecord.sourceforge.net/"
924 Execution Start Address: 00000000
925 Data: 0000 - 0122
926 0456 - 0FFF
927 $
928
929 This example shows that the file is a Motorola S‐Record. The text in
930 the file header is printed, along with the execution start address.
931 The final section shows the address ranges containing data (the upper
932 bound of each subrange is inclusive, rather than the exclusive form
933 used on the command line.
934
935 $ srec_info some‐weird‐file.hex -guess
936 Format: Signetics
937 Data: 0000 - 0122
938 0456 - 0FFF
939 $
940
941 The above example guesses the EPROM load file format. It isn't infal‐
942 lible but it usually gets it right. You can use -guess anywhere you
943 would give an explicit format, but it tends to be slower and for that
944 reason is not recommended. Also, for automated build systems, you want
945 hard errors as early as possible; if a file isn't in the expected for‐
946 mat, you want it to barf.
947
949 It is possible to change the values of the data bytes in several ways.
950
951 srec_cat infile -and 0xF0 -o outfile
952
953 The above example performs a bit‐wise AND of the data bytes with the
954 0xF0 mask. The addresses of records are unchanged. I can't actually
955 think of a use for this filter.
956
957 srec_cat infile -or 0x0F -o outfile
958
959 The above example performs a bit‐wise OR of the data bytes with the
960 0x0F bits. The addresses of records are unchanged. I can't actually
961 think of a use for this filter.
962
963 srec_cat infile -xor 0xA5 -o outfile
964
965 The above example performs a bit‐wise exclusive OR of the data bytes
966 with the 0xA5 bits. The addresses of records are unchanged. You could
967 use this to obfuscate the contents of your EPROM.
968
969 srec_cat infile -not -o outfile
970
971 The above example performs a bit‐wise NOT of the data bytes. The
972 addresses of records are unchanged. Security by obscurity?
973
975 srec_cat version 1.64
976 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
977 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Peter Miller
978
979 The srec_cat program comes with ABSOLUTELY NO WARRANTY; for details use
980 the 'srec_cat -VERSion License' command. This is free software and you
981 are welcome to redistribute it under certain conditions; for details
982 use the 'srec_cat -VERSion License' command.
983
985 Scott Finneran E‐Mail: scottfinneran@yahoo.com.au
986 Peter Miller E‐Mail: pmiller@opensource.org.au
987
988
989
990Reference Manual SRecord srec_examples(1)