Provided by: srecord_1.64-4.1build1_amd64 bug

NAME

       srec_examples - examples of how to use SRecord

DESCRIPTION

       The srec_cat command is very powerful, due to the ability to combine the the input filters
       in almost unlimited ways.  This manual page describes a few of them.

       This manual page describes how to use the various input files,  input  filters  and  input
       generators.  But these are only examples, for more complete details, see the srec_input(1)
       manual page.

   The Commands Lines Are Too Long
       If you are marooned on an operating system with absurdly short command line length limits,
       some  of  the  commands which follow may be too long.  You can get around this handicap by
       placing your command line in a file, say fred.txt, and then tell srec_cat(1) to read  this
       file for the rest of its command line, like this

              srec_cat @fred.txt

       This  also has the advantage of allowing comments, allowing you to write your command line
       options over several lines, and even indenting to make the command more  clear.   Comments
       start at a “#” and extend to the end of the line.  Blank lines are ignored.

       Of  course,  you  could  always  upgrade to Linux, which has been sucking less for over 32
       years now.

   Your Examples Wanted
       If you have a clever way of using  SRecord,  or  have  solved  a  difficult  problem  with
       SRecord,  you  could  contribute  to this manual page, making it more useful for everyone.
       Send your example in an email to the email address at the end of this manual page.

CONVERTING FILE FORMATS

       The simplest of the things srec_cat(1) can do is convert from one  EPROM  file  format  to
       another.   Please  keep  in  mind, as you read this section, that you can do many of these
       things simultaneously in one command.  They are only broken out separately  to  make  them
       easier to understand.

   Intel to Motorola
       One  of  the  simplest  examples  is converting files from Intel hex format to Motorola S‐
       Record format:

              srec_cat intel‐file -intel -o srec‐file

       Note that the format specifier immediately follows the name of the file it is  describing.
       Pick  any  two  formats  that SRecord understands, and it can convert between all of them.
       (Except the assembler, BASIC, C and FPGA outputs which are write only.)

   Motorola to Intel
       Converting the other way is just as simple:

              srec_cat srec‐file -o intel‐file -intel

       The default format is Motorola S‐Record format, so it does not need to be specified  after
       the file name.

   Different Shapes of the Same Format
       It  is regrettably common that some addle‐pated EPROM programmers only implement a portion
       of the specification used to represent their  hex  files.   For  example,  some  compilers
       produce  “s19”  Motorola  data  (that  is,  S1  data records with S9 start records, 16 bit
       address fields) which would be OK except that some blockhead EPROM programmers  insist  on
       “s37”  Motorola  data  (that  is,  S3  data  records with S7 start records, 32 bit address
       fields).

       It is possible to convert from one Motorola shape to  another  using  the  -Address‐Length
       option:

              srec_cat short.srec -o long.srec -address‐length=4

       This command says to use four byte (32‐bit) addresses on output.

       This  section  also  applies  to Intel hex files, as they, too, have the ability to select
       from a variety of address widths.  To convert from one Intel shape to  another  using  the
       same -Address‐Length option:

              srec_cat i32.hex -o i16.hex -address‐length=3

       This command says to use “i16hex” 20‐bit segmented addresses on output.  An address length
       of 4 is the default (“i32hex” 32‐bit linear addressing), and an address length of 2  would
       request “i8hex” 16‐bit addressing.

   Line Lengths
       From  time  to  time you will come across a feeble‐minded EPROM programmer that can't cope
       with long text lines, they assume that there will only ever be 46 characters per line  and
       barf when they see the default line lengths that srec_cat(1) writes (or worse, get a stack
       scribble and crash).

       The Motorola S‐record format definition permits up to 255 bytes of payload,  or  lines  of
       514 characters, plus the line termination.  All EPROM programmers should have sufficiently
       large line buffers to cope with records this big.  Few do.

       The -line‐length option may be used to specify the maximum line length (not including  the
       newline) to be used on output.  For example, 16 byte payloads for Motorola hex

              srec_cat long.srec -o short.s19 -line‐length=46

       The  line  length  option  interacts  with the address length option, so some tinkering to
       optimize for your particular situation many be necessary.

   Output Block Size
       Every once in a while you will come across an ancient daft  EPROM  programmer  that  can't
       cope  with long data records, they assume that there will only ever be at most 16 bytes of
       data per record, and barf when they see the default  32  byte  payloads  that  srec_cat(1)
       writes  (or  worse,  the  buffer  over‐run causes a tall grass walk that scribbles on your
       EPROM).

       The Intel hex format definition permits up to 255 bytes of payload data per  record.   All
       EPROM  programmers  should  have sufficiently large data buffers to cope with records this
       big.  Good luck with that.

       The -Output‐Block‐Size option may be used to specify the record data size to  be  used  on
       output.  For example, Intel hex with 16 byte payloads:

              srec_cat long.srec -o short.hex -intel -obs=16

       Be  careful  not  to  put  the  -obs  option  between  the output file name and the format
       specifier.

   Just the Data, Please
       There are some bonehead EPROM programmers which can only cope with data records,  and  are
       unable  to  cope with header records or execution start address records.  If you have this
       problem, the -data‐only option can be used to suppress just about  everything  except  the
       data.   The  actual effect depends on the format, of course, because some don't have these
       features anyway.

       The -data‐only option is short hand.  There are four properties which may be -disabled  or
       -enabled  separately.  See the srec_cat(1) man page for a description of the -disabled and
       -enabled options.

       For example, your neanderthal EPROM programmer requires Motorola hex with  header  records
       (S0), but without data count (S5) records.  Not using the -data‐only option has it barf on
       the data count record, but using the -data‐only option has it barf on the  missing  header
       record.   Using  the -disable=data‐count option would leave the header record intact while
       suppressing the data count record.

   Data Headers
       The srec_cat(1) command always tries to pass through header  records  unchanged,  whenever
       they  are  present.   It even tries preserve them across file format changes, to the limit
       the file formats are capable of.

       If there is no file header record and you would like to add one, or you wish  to  override
       an existing file header record, use the -header=string option.  You will need to quote the
       string (to insulate it from the shell) if it contains spaces or shell meta‐characters.

   Execution Start Addresses
       The srec_cat(1) command always tries to pass through execution start addresses  (typically
       occurring  at  the  end  of the file), whenever they are present.  They are adjusted along
       with the data records by the -offset filter.  It even  tries  preserve  them  across  file
       format changes, to the limit the file formats are capable of.

       If  there  is no execution start address record and you would like to add one, or you wish
       to override  an  existing  execution  start  address  record,  use  the  -execution‐start‐
       address=number option.

       Please  note: the execution start address is a different concept than the first address in
       memory of your data.  Think of it as a “goto” address to be jumped to by the monitor  when
       the hex load is complete.  If you want to change where your data starts in memory, use the
       -offset filter.

   Fixing Checksums
       Some embedded firmware developers are saddled  with  featherbrained  tools  which  produce
       incorrect checksums, which the more vigilant models of EPROM programmer will not accept.

       To fix the checksums on a file, use the -ignore‐checksums option.  For example:

              srec_cat broken.srec -ignore‐checksums -o fixed.srec

       The checksums in broken.srec are parsed (it is still and error if they are absent) but are
       not checked.  The resulting fixed.srec file has correct checksums.  The  -ignore‐checksums
       option only applies to input.

       This option may be used on any file format which has checksums, including Intel hex.

   Discovering Mystery Formats
       See the What Format Is This? section, below, for how to discover and convert mystery EPROM
       load file formats.

BINARY FILES

       It is possible to convert to and from binary files.  You can even  mix  binary  files  and
       other formats together in the same srec_cat(1) command.

   Writing Binary Files
       The simplest way of reading a hex file and converting it to a binary file looks like this:

              srec_cat fred.hex -o fred.bin -binary

       This  reads  the  Motorola  hex  file  fred.srec  and writes it out to the fred.bin as raw
       binary.

       Note that the data is placed into the binary file at the  byte  offset  specified  by  the
       addresses  in  the  hex  file.   If there are holes in the data they are filled with zero.
       This is, of course, common with linker output where the  code  is  placed  starting  at  a
       particular  place in memory.  For example, when you have an image that starts at 0x100000,
       the first 1MB of the output binary file will be zero.

       You can automatically cancel this offset using a command like

              srec_cat fred.hex -offset − -minimum‐addr fred.hex -o fred.bin

       The above command works by offsetting the fred.hex file  lower  in  memory  by  the  least
       address in the fred.hex file's data.

       See also the srec_binary(5) man page for additional detail.

   Reading Binary Files
       The simplest way of reading a binary file and converting it looks like this

              srec_cat fred.bin -binary -o fred.srec

       This  reads  the  binary  file  fred.bin  and  writes  all of its data back out again as a
       Motorola S‐Record file.

       Often, this binary isn't exactly where you want it in the address  space,  because  it  is
       assumed to reside at address zero.  If you need to move it around use the -offset filter.

              srec_cat fred.bin -binary -offset 0x10000 -o fred.srec

       You  also  need  to  avoid file “holes” which are filled with zero.  You can use the -crop
       filter, of you could use the -unfill filter if you don't know exactly where the data is.

              srec_cat fred.bin -binary -unfill 0x00 512 -o fred.srec

       The above command removes runs of zero bytes that are 512 bytes long or longer.   If  your
       file contains 1GB of leading zero bytes, this is going to be slow, it may be better to use
       the dd(1) command to slice and dice first.

JOINING FILES TOGETHER

       The srec_cat command takes its name from the UNIX  cat(1)  command,  which  is  short  for
       “catenate” or “to join”.  The srec_cat command joins EPROM load files together.

   All In One
       Joining EPROM load files together into a single file is simple, just name as many files on
       the command line as you need:

              srec_cat infile1 infile2 -o outfile

       This example is all Motorola S‐Record files, because that's the default format.   You  can
       have multiple formats in the one command, and srec_cat(1) will still work.  You don't even
       have to output the same format:

              srec_cat infile1 -spectrum infile2 -needham \
                  -o outfile -signetics

       These are all ancient formats, however it isn't uncommon to have to mix  and  match  Intel
       and Motorola formats in the one project.

   Overlaying two data files
       It  is common to want to “join” two hex files together, without any changes of address. on
       the assumption neither file intersects with the other.  This is a simple “layers”,  it  is
       quite common for linkers to output the main code, and then a whole bunch of relocation and
       jump destination, by writing a two layered files.
              srec_cat one.he two.hex -o three.hex
       Almost always you see an error
              srec_cat: two.srec: 49282: contradictory 0x00000000 value (previous  =  0x00,  this
              one = 0x80)

       This  means that the files actually intersect, they try to set the same location.  You can
       turn the error into a warning, using the -contradictory‐bytes=warning command line option.
       But this will probably generate a bazillion warnings.

       The  necessary  step  is  to  crop the first file, to avoid the regions the second file is
       going o be overwriting.
              srec_cat                               \
                  one.srec -exclude -within two.srec \
                  two.srec -exclude -within one.srec \
                  -o three.hex

       Depending on your linker this will have no errors (but if it  wants  another  layer,  more
       jiggery‐pokery is required).

   Filtering After Joining
       There  are  times when you want to join two sets of data together, and then apply a filter
       to the joined result.  To do this you use parentheses.
              srec_cat                                                  \
                  '('                                                   \
                      infile -exclude 0xFFF0 0x10000                      \
                      -generate 0xFFF0 0xFFF8 -repeat‐string 'Bananas ' \
                  ')'                                                   \
                  -length‐b‐e 0xFFF8 4                                  \
                  -checksum‐neg‐b‐e 0xFFFC 4 4                          \
                  -o outfile

       The above example command catenate an input file (with the generated data  area  excluded)
       with a constant string.  This catenated input is then filtered to add a 4‐byte length, and
       a 4‐byte checksum.

   Joining End‐to‐End
       All too often the address ranges in the EPROM load files will overlap.  You  will  get  an
       error  if  they  do.   If  both  files  start  from address zero, because each goes into a
       separate EPROM, you may need to use the offset filter:

              srec_cat infile1 \
                  infile2 -offset 0x80000 \
                  -o outfile

       Sometimes you want the two files to follow each other exactly,  but  you  don't  know  the
       offset in advance:

              srec_cat infile1 \
                  infile2 -offset -maximum‐addr infile1 \
                  -o outfile

       Notice that where the was a number (0x80000) before, there is now a calculation (-maximum‐
       addr infile1).  This is possible most places a number may be used (also -minimum‐addr  and
       -range).

CROPPING THE DATA

       It  is  possible  to copy an EPROM load file, selecting addresses to keep and addresses to
       discard.

   What To Keep
       A common activity is to crop your data to match your EPROM location.  Your linker may  add
       other  junk  that  you are not interested in, e.g.  at the RAM location.  In this example,
       there is a 1MB EPROM at the 2MB boundary:

              srec_cat infile -crop 0x200000 0x300000 \
                  -o outfile

       The lower bound for all address ranges is inclusive, the upper bound is exclusive.  If you
       subtract them, you get the number of bytes.

   Address Offset
       Just  possibly,  you  have  a  moronic  EPROM  programmer, and it barfs if the EPROM image
       doesn't start at zero.  To  find  out  just  where  is  does  start  in  memory,  use  the
       srec_info(1) command:

              $ srec_info example.srec
              Format: Motorola S‐Record
              Header: extra‐whizz tool chain linker
              Execution Start Address: 0x00200000
              Data:   0x200000 - 0x32AAEF
              $

       Rather than butcher the linker command file, just offset the addresses:

              srec_cat infile -crop 0x200000 0x300000 -offset −0x200000 \
                  -o outfile

       Note  that  the offset given is negative, it has the effect of subtracting that value from
       all addresses in the input records, to form the output record addresses.   In  this  case,
       shifting the image back to zero.

       This  example  also  demonstrates how the input filters may be chained together: first the
       crop and then the offset, all in one command, without the need for temporary files.

       If all you want to do is offset  the  data  to  start  from  address  zero,  this  can  be
       automated,  so  you don't have to know the minimum address in advance, by using srec_cat's
       ability to calculate some things on the command line:

              srec_cat infile -offset − -minimum‐addr infile \
                  -o outfile

       Note the spaces either side of the minus sign, they are mandatory.

   What To Throw Away
       There are times when you need to exclude an small address range from an EPROM  load  file,
       rather  than  wanting  to keep a small address range.  The -exclude filter may be used for
       this purpose.

       For example, if you wish to exclude the address  range  where  the  serial  number  of  an
       embedded device is kept, say 0x20 bytes at 0x100, you would use a command like this:

              srec_cat input.srec -exclude 0x100 0x120 -o output.srec

       The output.srec file will have a hole in the data at the necessary locations.

       Note  that  you can have both -crop and -exclude on the same command line, whichever works
       more naturally for your situation.

   Discontinuous Address Ranges
       Address ranges don't have to be a single range, you can build up an  address  range  using
       more than a single pair.

              srec_cat infile -crop 0x100 0x200 0x1000 0x1200 \
                  -o outfile

       This  filter  results  in  data  from  0x100..0x1FF  and  data from 0x1000..0x1200 to pass
       through, the rest is dropped.  This is is more efficient than  chaining  a  -crop  and  an
       -exclude filter together.

MOVING THINGS AROUND

       It  is  also  possible to change the address of data records, both forwards and backwards.
       It is also possible rearrange where data records are placed in memory.

   Offset Filter
       The -offset=number filter operates on the addresses of records.  If the number is positive
       the addresses move that many bytes higher in memory, negative values move lower.

              srec_cat infile -crop 0x200000 0x300000 -offset −0x200000 \
                  -o outfile

       The  above  example  moves  the  1MB block of data at 0x200000 down to zero (the offset is
       negative) and discards the rest of the data.

   Byte Swapping
       There are times when the bytes in the data need to be  swapped,  converting  between  big‐
       endian and little‐endian data usually.

              srec_cat infile -byte‐swap 4 -o outfile

       This reverses bytes in 32 bit values (4 bytes).  The default, if you don't supply a width,
       is to reverse bytes in 16 bit values (2 bytes).  You can actually use any weird value  you
       like,  it  doesn't  even have to be a power of 2.  Perhaps 64 bits (8 bytes) may be useful
       one day.

   Binary Output
       You need to watch out for binary files on output, because the holes are filled with zeros.
       Your  100kB  program  at  the  top  of  32‐bit addressed memory will make a 4GB file.  See
       srec_binary(5) for how understand and avoid this problem, usually with the -offset filter.

   Splitting an Image
       If you have a 16‐bit data bus, but you are using two 8‐bit EPROMs to hold  your  firmware,
       you  can  generate  the  even  and  odd  images by using the -SPlit filter.  Assuming your
       firmware is in the firmware.hex file, use the following:

              srec_cat firmware.hex -split 2 0 -o firmware.even.hex
              srec_cat firmware.hex -split 2 1 -o firmware.odd.hex

       This will result in the two necessary EPROM images.  Note that the  output  addresses  are
       divided  by  the  split  multiple, so if your EPROM images are at a particular offset (say
       0x10000, in the following example), you need to remove the offset, and then replace it...

              srec_cat firmware.hex \
                  -offset −0x10000 -split 2 0 \
                  -offset 0x10000 -o firmware.even.hex
              srec_cat firmware.hex \
                  -offset −0x10000 -split 2 1 \
                  -offset 0x10000 -o firmware.odd.hex

       Note how the ability to apply multiple filters simplifies what would otherwise be  a  much
       longer script.

   Striping
       A second use for the -SPlit filter is memory striping.

       You don't have to split into byte‐wide parts, you can choose other sizes.  It is common to
       want to convert 32‐bit wide data into two set of 16‐bit wide data.

              srec_cat firmware.hex -split 4 0 2 -o firmware.01.hex
              srec_cat firmware.hex -split 4 2 2 -o firmware.23.hex

       This is relatively simple to understand, but you can use even wider stripes.

       In this next example, the hardware requires  that  512‐byte  blocks  alternate  between  4
       EPROMs.  Generating the 4 images would be done as follows:

              srec_cat firmware.hex -split 0x800 0x000 0x200 -o firmware.0.hex
              srec_cat firmware.hex -split 0x800 0x200 0x200 -o firmware.1.hex
              srec_cat firmware.hex -split 0x800 0x400 0x200 -o firmware.2.hex
              srec_cat firmware.hex -split 0x800 0x600 0x200 -o firmware.3.hex

   Asymmetric Striping
       A  more peculiar example of striping is the Microchip dsPIC33F microcontroller, that has a
       weird memory storage pattern and they are able to store 3 bytes in an address that  should
       only contain 2 bytes.  The result is a hex file that has zero‐filled the top byte (little‐
       endian), and all addresses are doubled from what  they  are  in  the  chip.   Here  is  an
       example:

              S1130000000102000405060008090A000C0D0E0098
              S1130010101112001415160018191A001C1D1E00C8
              S1130020202122002425260028292A002C2D2E00F8
              S1130030303132003435360038393A003C3D3E0028

       To  get  rid of the 00 padding bytes, leaving only the 3/4 significant bytes, you also use
       the split filter, with its additional width argument, like this:

              srec_cat example.srec -split 4 0 3 -o no_dross.srec

       This results in a file with the 00 padding bytes removed.  It looks like this:

              S113000000010204050608090A0C0D0E1011121451
              S1130010151618191A1C1D1E2021222425262829EC
              S11300202A2C2D2E30313234353638393A3C3D3E87

       Notice how the addresses are 3/4 the size, as  well.   You  can  reverse  this  using  the
       -unsplit and -fill=0 filters.

   Unsplit ING Images
       The  unsplit filter may be used to reverse the effects of the split filter.  Note that the
       address range is expanded leaving holes between the stripes.  By using  all  the  stripes,
       the complete input is reassembled, without any holes.

              srec_cat -o firmware.hex \
                  firmware.even.hex -unsplit 2 0 \
                  firmware.odd.hex  -unsplit 2 1

       The  above example reverses the previous 16‐bit data bus example.  In general, you unsplit
       with the same parameters that you split with.

FILLING THE BLANKS

       Often EPROM load files will have “holes” in them, places where the compiler and linker did
       not  put  anything.  For some purposes this is OK, and for other purposes something has to
       be done about the holes.

   The Fill Filter
       It is possible to fill the blanks where your data does not lie.  The simplest  example  of
       this fills the entire EPROM:

              srec_cat infile -fill 0x00 0x200000 0x300000 -o outfile

       This  example  fills  the  holes,  if  any, with zeros.  You must specify a range - with a
       32‐bit address space, filling everything generates huge load files.

       If you only want to fill the gaps in your data, and don't want to fill the  entire  EPROM,
       try:

              srec_cat infile -fill 0x00 -over infile -o outfile

       This  example  demonstrates  the fact that wherever an address range may be specified, the
       -over and -within options may be used.

   Unfilling the Blanks
       It is common to need to “unfill” an EPROM image after you read it out of a chip.  Usually,
       it will have had all the holes filled with 0xFF (areas of the EPROM you don't program show
       as 0xFF when you read them back).

       To get rid of all the 0xFF bytes in the data, use this filter:

              srec_cat infile -unfill 0xFF -o outfile

       This will get rid of all the 0xFF bytes, including the ones you actually wanted in  there.
       There  are two ways to deal with this.  First, you can specify a minimum run length to the
       un‐fill:

              srec_cat infile -unfill 0xFF 5 -o outfile

       This says that runs of 1 to 4 bytes of 0xFF are OK, and that a hole should only be created
       for  runs  of  5  or  more  0xFF bytes in a row.  The second method is to re‐fill over the
       intermediate gaps:

              srec_cat outfile -fill 0xFF -over outfile \
                  -o outfile2

       Which method you choose depends on your needs, and the shape of the data  in  your  EPROM.
       You may need to combine both techniques.

   Address Range Padding
       Some  data  formats  are  16  bits  wide,  and automatically fill with 0xFF bytes if it is
       necessary to fill out the other half of a word which is not in the data.  If you  need  to
       fill with a different value, you can use a command like this:

              srec_cat infile -fill 0x0A \
                  -within infile -range‐padding 2 \
                  -o outfile

       This  gives  the  fill  filter an address range calculated from details of the input file.
       The address range is all the address ranges  covered  by  data  in  the  infile,  extended
       downwards  (if necessary) at the start of each sub‐range to a 2 byte multiple and extended
       upwards (if necessary) at the end of each sub‐range to a 2 byte multiple.  This also works
       for larger multiples, like 1kB page boundaries of flash chips.  This address range padding
       works anywhere an address range is required.

   Fill with Copyright
       It is possible to fill unused portions of your EPROM with a repeating  copyright  message.
       Anyone  trying  to  reverse  engineer  your EPROMs is going to see the copyright notice in
       their hex editor.

       This is accomplished with two input sources, one from  a  data  file,  and  one  which  is
       generated on‐the‐fly.

              srec_cat infile \
                  -generate '(' 0 0x100000 -minus -within infile ')' \
                      -repeat‐string 'Copyright (C) 1812 Tchaikovsky.  ' \
                  -o outfile

       Notice  the  address  range  for  the  data generation: it takes the address range of your
       EPROM, in this case 1MB starting from 0, and subtracts from it the address ranges used  by
       the input file.

       If  you  want to script this with the current year (because 1812 is a bit out of date) use
       the shell's output substitution (back ticks) ability:

              srec_cat infile \
                  -generate '(' 0 0x100000 -minus -within infile ')' \
                      -repeat‐string "Copyright (C) `date +%Y` Tchaikovsky.  " \
                  -o outfile

       The string specified is repeated over and over again, until it has filled all the holes.

   Obfuscating with Noise
       Sometimes you want to fill your EPROM images with noise, to conceal where  the  real  data
       stops and starts.  You can do this with the -random‐fill filter.

              srec_cat infile -random‐fill 0x200000 0x300000 \
                  -o outfile

       It  works  just  like the -fill filter, but uses random numbers instead of a constant byte
       value.

   Fill With 16‐bit Words
       When filling the image with a constant byte value doesn't work, and you  need  a  constant
       16‐bit word value instead, use the -repeat‐data generator, which takes an arbitrarily long
       sequence of bytes to use as the fill pattern:

              srec_cat infile \
                  -generator '(' 0x200000 0x300000 -minus -within infile ')' \
                      -repeat‐data 0x1B 0x08 \
                  -o outfile

       Notice how the generator's address range once again avoids the address ranges occupied  by
       the infile's data.  You have to get the endian‐ness right yourself.

INSERTING CONSTANT DATA

       From  time  to  time  you  will want to insert constant data, or data not produced by your
       compiler or assembler, into your EPROM load images.

   Binary Means Literal
       One simple way is to have the desired  information  in  a  file.   To  insert  the  file's
       contents literally, with no format interpretation, use the binary input format:

              srec_cat infile -binary -o outfile

       It  will  probably  be  necessary  to  use  an offset filter to move the data to where you
       actually want it within the image:

              srec_cat infile -binary -offset 0x1234 -o outfile

       It is also possible to use the standard input as a data  source,  which  lends  itself  to
       being scripted.  For example, to insert the current date and time into an EPROM load file,
       you could use a pipe:

              date | srec_cat - -bin -offset 0xFFE3 -o outfile

       The special file name “-” means to read from the standard input.  The output of  the  date
       command  is  always 29 characters long, and the offset shown will place it at the top of a
       64KB EPROM image.

   Repeating Once
       The Fill with Copyright section, above, shows how to repeat a string over  and  over.   We
       can use a single repeat to insert a string just once.

              srec_cat -generate 0xFFE3 0x10000 -repeat‐string "`date`" \
                  -o outfile

       Notice  how  the  address  range for the data generation exactly matches the length of the
       date(1) output size.  You can, of course, add your input file  to  the  above  srec_cat(1)
       command to catenate your EPROM image together with the date and time.

   Inserting A Long
       Another  possibility  is to add the Subversion commit number to your EPROM image.  In this
       example, we are inserting it a a  4‐byte  little‐endian  value  at  address  0x0008.   The
       Subversion commit number is in the $version shell variable in this example:

              srec_cat -generate 0x0008 0x000C -constant‐l‐e $version 4 \
                  infile -exclude 0x0008 0x000C \
                  -o outfile

       Note  that we use a filter to ensure there is a hole in the input where the version number
       goes, just in case the linker put something there.

DATA ABOUT THE DATA

       It is possible to add a variety of data about the data to the output.

   Checksums
       The -checksum‐negative‐big‐endian filter may be used to sum the data, and then insert  the
       negative  of  the  sum  into  the  data.   This has the effect of summing to zero when the
       checksum itself is summed across, provided the sum width matches the inserted value width.

              srec_cat infile \
                      -crop 0 0xFFFFFC \
                      -random‐fill 0 0xFFFFFC \
                      -checksum‐neg‐b‐e 0xFFFFFC 4 4 \
                  -o outfile

       In this example, we have an EPROM in the lowest megabyte  of  memory.   The  -crop  filter
       ensures  we  are  only  summing  the  data  within  the EPROM, and not anywhere else.  The
       -random‐fill filter fills any holes left in the data with  random  values.   Finally,  the
       -checksum‐neg‐b‐e  filter  inserts  a 32 bit (4 byte) checksum in big‐endian format in the
       last 4 bytes of the EPROM image.  Naturally, there is  a  little‐endian  version  of  this
       filter as well.

       Your embedded code can check the EPROM using C code similar to the following:

              unsigned long *begin = (unsigned long *)0;
              unsigned long *end = (unsigned long *)0x100000;
              unsigned long sum = 0;
              while (begin < end)
                  sum += *begin++;
              if (sum != 0)
              {
                  Oops
              }

       The  -checksum‐bitnot‐big‐endian  filter is similar, except that summing over the checksum
       should yield a value of all‐one‐bits (−1).  For example, using shorts rather than longs:

              srec_cat infile \
                      -crop 0 0xFFFFFE \
                      -fill 0xCC 0x00000 0xFFFFFE \
                      -checksum‐neg‐b‐e 0xFFFFFE 2 2 \
                  -o outfile

       Assuming you chose the correct endian‐ness filter, your embedded code can check the  EPROM
       using C code similar to the following:

              unsigned short *begin = (unsigned short *)0;
              unsigned short *end = (unsigned short *)0x100000;
              unsigned short sum = 0;
              while (begin < end)
                  sum += *begin++;
              if (sum != 0xFFFF)
              {
                  Oops
              }

       There  is also a -checksum‐positive‐b‐e filter, and a matching little‐endian filter, which
       inserts the simple sum, and which would be checked in C using an equality test.

              srec_cat infile \
                      -crop 0 0xFFFFFF \
                      -fill 0x00 0x00000 0xFFFFFF \
                      -checksum‐neg‐b‐e 0xFFFFFF 1 1 \
                  -o outfile

       Assuming you chose the correct endian‐ness filter, your embedded code can check the  EPROM
       using C code similar to the following:

              unsigned char *begin = (unsigned char *)0;
              unsigned char *end = (unsigned char *)0xFFFFF;
              unsigned char sum = 0;
              while (begin < end)
                  sum += *begin++;
              if (sum != *end)
              {
                  Oops
              }

       In  the  8‐bit  case,  it  doesn't  matter whether you use the big‐endian or little‐endian
       filter.

   Quick Hex‐Dump
       You can look at the checksum of your data, by using the “hex‐dump” output format.  This is
       useful  for  looking  at calculated values, or for debugging an srec_cat(1) command before
       immortalizing it in a script.

              srec_cat infile                        \
                      -crop 0 0x10000             \
                      -fill 0xFF 0x0000 0x10000   \
                      -checksum‐neg‐b‐e 0x10000 4 \
                      -crop 0x10000 0x10004       \
                  -o - -hex‐dump

       This command reads in the file, checksums the data and places  the  checksum  at  0x10000,
       crops  the  result  to  contain  only  the  checksum,  and then prints the checksum on the
       standard output in a classical hexadecimal dump format.  The special file name  “-”  means
       “the standard output” in this context.

   Cyclic Redundancy Checks
       The  simple additive checksums have a number of theoretical limitations, to do with errors
       they can and can't detect.  The CRC methods have fewer problems.

              srec_cat infile                        \
                      -crop 0 0xFFFFFC            \
                      -fill 0x00 0x00000 0xFFFFFC \
                      -crc32‐b‐e 0xFFFFFC         \
                  -o outfile

       In the above example, we have an EPROM in the lowest megabyte of memory.  The -crop filter
       ensures  we  are only summing the data within the EPROM, and not anywhere else.  The -fill
       filter fills any holes left in the data.  Finally, the -checksum‐neg‐b‐e filter inserts  a
       32  bit  (4  byte)  checksum  in big‐endian format in the last 4 bytes of the EPROM image.
       Naturally, there is a little‐endian version of this filter as well.

       The checksum is calculated using the industry standard 32‐bit  CRC.   Because  SRecord  is
       open source, you can always read the source code to see how it works.  There are many non‐
       GPL versions of this code available  on  the  Internet,  and  suitable  for  embedding  in
       proprietary firmware.

       There is also a 16‐bit CRC available.

              srec_cat infile                        \
                      -crop 0 0xFFFFFE            \
                      -fill 0x00 0x00000 0xFFFFFE \
                      -crc16‐b‐e 0xFFFFFE         \
                  -o outfile

       The  checksum  is calculated using the CCITT formula.  Because SRecord is open source, you
       can always read the source code to see how it works.  There are many  non‐GPL  version  of
       this code available on the Internet, and suitable for embedding in proprietary firmware.

       You can look at the CRC of your data, by using the “hex‐dump” output format.

              srec_cat infile                      \
                      -crop 0 0x10000           \
                      -fill 0xFF 0x0000 0x10000 \
                      -crc16‐b‐e 0x10000        \
                      -crop 0x10000 0x10002     \
                  -o - -hex‐dump

       This  command  reads  in  the  file,  calculates the CRC of the data and places the CRC at
       0x10000, crops the result to contain only the CRC, and then prints  the  checksum  on  the
       standard output in a classical hexadecimal dump format.

   Where Is My Data?
       There  are  several  properties  of  your EPROM image that you may wish to insert into the
       data.

              srec_cat infile -minimum‐b‐e 0xFFFE 2 -o outfile

       The above example inserts the minimum address of the data (low water) into  the  data,  as
       two  bytes  in  big‐endian order at address 0xFFFE.  This includes the minimum itself.  If
       the data already contains bytes at the given address, you need to use an  exclude  filter.
       The number of bytes defaults to 4.

       There  is  also  a  -minimum‐l‐e  filter  for inserting little‐endian values, and two more
       filters called -exclusive‐minimum‐b‐e and -exclusive‐minimum‐l‐e that do not  include  the
       minimum itself in the calculation of the minimum data address.

              srec_cat infile -maximum‐b‐e 0xFFFFFC 4 -o outfile

       The  above  example  inserts  the  maximum  address of the data (high water + 1, just like
       address ranges) into the data, as four bytes in  big‐endian  order  at  address  0xFFFFFC.
       This  includes  the  maximum  itself.   If  the  data  already contains bytes at the given
       address, you need to use an -exclude filter.  The number of bytes defaults to 4.

       There is also a -maximum‐l‐e filter for  inserting  little‐endian  values,  and  two  more
       filters  called  -exclusive‐maximum‐b‐e and -exclusive‐maximum‐l‐e that do not include the
       maximum itself in the calculation of the maximum data address.

              srec_cat infile -length‐b‐e 0xFFFFFC 4 -o outfile

       The above example inserts the length of the data (high water + 1 −  low  water)  into  the
       data,  as  four  bytes  in big‐endian order at address 0xFFFFFC.  This includes the length
       itself.  If the data already contains bytes at the length location, you  need  to  use  an
       -exclude filter.  The number of bytes defaults to 4.

       There  is  also  a  -length‐l‐e  filter  for  inserting  a  little‐endian  length, and the
       -exclusive‐length‐b‐e and -exclusive‐length‐l‐e filters that do  not  include  the  length
       itself in the calculation.

   What Format Is This?
       You can obtain a variety of information about an EPROM load file by using the srec_info(1)
       command.  For example:

              $ srec_info example.srec
              Format: Motorola S‐Record
              Header: "http://srecord.sourceforge.net/"
              Execution Start Address: 00000000
              Data:   0000 - 0122
                      0456 - 0FFF
              $

       This example shows that the file is a Motorola S‐Record.  The text in the file  header  is
       printed,  along  with  the  execution  start address.  The final section shows the address
       ranges containing data (the upper bound of each subrange is  inclusive,  rather  than  the
       exclusive form used on the command line.

              $ srec_info some‐weird‐file.hex -guess
              Format: Signetics
              Data:   0000 - 0122
                      0456 - 0FFF
              $

       The  above example guesses the EPROM load file format.  It isn't infallible but it usually
       gets it right.  You can use -guess anywhere you would give  an  explicit  format,  but  it
       tends  to  be  slower  and  for that reason is not recommended.  Also, for automated build
       systems, you want hard errors as early as possible;  if  a  file  isn't  in  the  expected
       format, you want it to barf.

MANGLING THE DATA

       It is possible to change the values of the data bytes in several ways.

              srec_cat infile -and 0xF0 -o outfile

       The  above  example  performs  a  bit‐wise  AND of the data bytes with the 0xF0 mask.  The
       addresses of records are unchanged.  I can't actually think of a use for this filter.

              srec_cat infile -or 0x0F -o outfile

       The above example performs a bit‐wise OR of the  data  bytes  with  the  0x0F  bits.   The
       addresses of records are unchanged.  I can't actually think of a use for this filter.

              srec_cat infile -xor 0xA5 -o outfile

       The  above  example performs a bit‐wise exclusive OR of the data bytes with the 0xA5 bits.
       The addresses of records are unchanged.  You could use this to obfuscate the  contents  of
       your EPROM.

              srec_cat infile -not -o outfile

       The above example performs a bit‐wise NOT of the data bytes.  The addresses of records are
       unchanged.  Security by obscurity?

COPYRIGHT

       srec_cat version 1.64
       Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,  2005,  2006,  2007,  2008,  2009,
       2010, 2011, 2012, 2013, 2014 Peter Miller

       The  srec_cat  program  comes  with  ABSOLUTELY NO WARRANTY; for details use the 'srec_cat
       -VERSion License' command.  This is free software and you are welcome to  redistribute  it
       under certain conditions; for details use the 'srec_cat -VERSion License' command.

MAINTAINER

       Scott Finneran   E‐Mail:   scottfinneran@yahoo.com.au
       Peter Miller     E‐Mail:   pmiller@opensource.org.au