Appending text to .bin with srec_cat

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a compiled .bin file, filled with 0xFF bytes on unused areas. Now, using srec_cat, I want to read a text file which contains single value and append it to .bin at certain address. Right now, I've added post-build event in Atmel Studio which converts .hex to .bin, and also adds CRC to the end of flash area (AT90USB1286 with 8kB bootloader):

 

call "D:\Applications\AVRdude+AVRsize\srec_cat.exe" "$(MSBuildProjectDirectory)\$(Configuration)\$(OutputFileName).hex" -intel -fill 0xFF 0x0000 0x1DFFE -Cyclic_Redundancy_Check_16_Big_Endian 0x1DFFE -XMODEM -o "$(SolutionDir)\FLASH.bin" -binary

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Shantea wrote:
Now, using srec_cat, I want to read a text file which contains single value and append it to .bin at certain address.

Two things:

 

1) in what format is this "value". You say "text file" so can we assume it's in ASCII? If so what number base and is it float? Something like "123" or "3.141" or "0x3C" or what?

 

2) To be honest I'd say it's far easier to do something like this with a separate small program written in C or some scripting language like Python.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
1) in what format is this "value". You say "text file" so can we assume it's in ASCII? If so what number base and is it float? Something like "123" or "3.141" or "0x3C" or what?

 

Decimal value - but it could be hex as well.

 

clawson wrote:
To be honest I'd say it's far easier to do something like this with a separate small program written in C or some scripting language like Python.

 

I thought it should be fairly trivial with right set of srec commands, just like appending CRC - I'm just not sure how.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does srec have a "generator" that does ASCII decimal digit to binary conversions then? I suppose it may well have but I can't remember reading about it. Anyway in 2 minutes you could write something like this:

#include <stdio.h>

#define INSERT_OFFSET 0x1234

FILE * fbin;
FILE * fnum;

char line[1000];
int num;

int main(void) {
    fnum = fopen("num.txt", "rt");
    fbin = fopen("code.bin", "r+");
    if (fbin && fnum) {
        fgets(line, 1000, fnum);
        fclose(fnum);
        num = atoi(line);
        fseek(fbin, INSERT_OFFSET, SEEK_SET);
        fputc(i, fbin);
        fclose(fbin);
    }
    return 0;
}

That reads an ASCII decimal string from num.txt and inserts the lowest byte of it at offset 0x1234 in a file called num.bin

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the suggestion. I've tried that with slight modifications - I can write the number I want to specific location, but it completely overwrites entire binary file.

 

#include <stdio.h>
#include <inttypes.h>

#define INSERT_OFFSET   0x1DFFD
#define TEXT_LENGTH     10

FILE * f_bin;
FILE * f_major;
FILE * f_minor;
FILE * f_revision;

char line[TEXT_LENGTH];
int num;

int main(void) {

    f_bin       = fopen("FLASH.bin", "wb+");

    f_major     = fopen("major", "r");
    f_minor     = fopen("minor", "r");
    f_revision  = fopen("revision", "r");

    if (f_bin && f_major && f_minor && f_revision)   {

        fscanf(f_revision, "%d", &num);
        fseek(f_bin, INSERT_OFFSET, SEEK_SET);
        fputc(num, f_bin);

    }

    printf("%d", num);

    fclose(f_major);
    fclose(f_minor);
    fclose(f_revision);
    fclose(f_bin);

    return 0;

}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why have you opened it "wb+" ? I quite specifically used "r+" (b can be used but will probably be ignored). For details see:

 

http://www.cplusplus.com/referen...

 

As you can see from the table on that page:

"w+"write/update: Create an empty file and open it for update (both for input and output). If a file with the same name already exists its contents are discarded and the file is treated as a new empty file.

But for r+:

"r+"read/update: Open a file for update (both for input and output). The file must exist.

I guess I might have used "a+" but in my test case I'd already created a "test.bin" with some binary data in it.

 

BTW I don't see how your code would work anyway - you open 3 files but only read one of them so only your "rev" would be read/written anyway.

 

Also why on earth have major, minor and rev in 3 separate files? Why not something like "1,3,45" in a file then open that single file and parse the 3 values from it?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Why have you opened it "wb+" ? I quite specifically used "r+" (b can be used but will probably be ignored). For details see:

 

http://www.cplusplus.com/referen...

 

As you can see from the table on that page:

"w+"write/update: Create an empty file and open it for update (both for input and output). If a file with the same name already exists its contents are discarded and the file is treated as a new empty file.

But for r+:

"r+"read/update: Open a file for update (both for input and output). The file must exist.

I guess I might have used "a+" but in my test case I'd already created a "test.bin" with some binary data in it.

 

Wow, I haven't noticed that while I was changing stuff... really stupid mistake. Thanks!!

 

 

clawson wrote:
BTW I don't see how your code would work anyway - you open 3 files but only read one of them so only your "rev" would be read/written anyway.

 

It was a testing code, I had three files, but ran tests only on one.

 

clawson wrote:
Also why on earth have major, minor and rev in 3 separate files? Why not something like "1,3,45" in a file then open that single file and parse the 3 values from it?

 

See above. Anyways it works now, thanks for the help!

 

#include <stdio.h>
#include <inttypes.h>
#include <stdbool.h>

#define INSERT_OFFSET   0x1DFFB
#define POINTS          3

int main(void) {

    FILE *f_bin       = fopen("FLASH.bin", "r+");
    FILE *f_version   = fopen("version", "r");

    if (f_bin && f_version)   {

        int point = 0, points = 0;

        do {

            fscanf(f_version, "%d,", &point);
            fseek(f_bin, INSERT_OFFSET+points, SEEK_SET);
            fputc(point, f_bin);
            points++;

        }   while (points < POINTS);

    }

    fclose(f_version);
    fclose(f_bin);

    return 0;

}