avrdude: use sections instead of offsets

This commit is contained in:
Vojtech Kral 2018-06-25 18:19:51 +02:00 committed by bubnikv
parent 987fc4c6df
commit 6b801f250a
5 changed files with 61 additions and 46 deletions

View File

@ -98,11 +98,11 @@ static int fileio_num(struct fioparms * fio,
char * filename, FILE * f, AVRMEM * mem, int size,
FILEFMT fmt);
static int fmt_autodetect(char * fname, size_t offset);
static int fmt_autodetect(char * fname, unsigned section);
static FILE *fopen_and_seek(const char *filename, const char *mode, size_t offset)
static FILE *fopen_and_seek(const char *filename, const char *mode, unsigned section)
{
FILE *file;
// On Windows we need to convert the filename to UTF-16
@ -118,16 +118,38 @@ static FILE *fopen_and_seek(const char *filename, const char *mode, size_t offse
file = fopen(filename, mode);
#endif
if (file != NULL) {
// Some systems allow seeking past the end of file, so we need check for that first and disallow
if (fseek(file, 0, SEEK_END) != 0
|| offset >= ftell(file)
|| fseek(file, offset, SEEK_SET) != 0
) {
fclose(file);
file = NULL;
errno = EINVAL;
if (file == NULL) {
return NULL;
}
// Seek to the specified 'section'
static const char *hex_terminator = ":00000001FF\r";
unsigned terms_seen = 0;
char buffer[MAX_LINE_LEN + 1];
while (terms_seen < section && fgets(buffer, MAX_LINE_LEN, file) != NULL) {
size_t len = strlen(buffer);
if (buffer[len - 1] == '\n') {
len--;
buffer[len] = 0;
}
if (buffer[len - 1] != '\r') {
buffer[len] = '\r';
len++;
buffer[len] = 0;
}
if (strcmp(buffer, hex_terminator) == 0) {
// Found a section terminator
terms_seen++;
}
}
if (feof(file)) {
// Section not found
fclose(file);
return NULL;
}
return file;
@ -1392,7 +1414,7 @@ int fileio_setparms(int op, struct fioparms * fp,
static int fmt_autodetect(char * fname, size_t offset)
static int fmt_autodetect(char * fname, unsigned section)
{
FILE * f;
unsigned char buf[MAX_LINE_LEN];
@ -1402,9 +1424,9 @@ static int fmt_autodetect(char * fname, size_t offset)
int first = 1;
#if defined(WIN32NATIVE)
f = fopen_and_seek(fname, "r", offset);
f = fopen_and_seek(fname, "r", section);
#else
f = fopen_and_seek(fname, "rb", offset);
f = fopen_and_seek(fname, "rb", section);
#endif
if (f == NULL) {
@ -1480,7 +1502,7 @@ static int fmt_autodetect(char * fname, size_t offset)
int fileio(int op, char * filename, FILEFMT format,
struct avrpart * p, char * memtype, int size, size_t offset)
struct avrpart * p, char * memtype, int size, unsigned section)
{
int rc;
FILE * f;
@ -1539,7 +1561,7 @@ int fileio(int op, char * filename, FILEFMT format,
return -1;
}
format_detect = fmt_autodetect(fname, offset);
format_detect = fmt_autodetect(fname, section);
if (format_detect < 0) {
avrdude_message(MSG_INFO, "%s: can't determine file format for %s, specify explicitly\n",
progname, fname);
@ -1570,7 +1592,7 @@ int fileio(int op, char * filename, FILEFMT format,
if (format != FMT_IMM) {
if (!using_stdio) {
f = fopen_and_seek(fname, fio.mode, offset);
f = fopen_and_seek(fname, fio.mode, section);
if (f == NULL) {
avrdude_message(MSG_INFO, "%s: can't open %s file %s: %s\n",
progname, fio.iodesc, fname, strerror(errno));

View File

@ -821,7 +821,7 @@ extern "C" {
char * fmtstr(FILEFMT format);
int fileio(int op, char * filename, FILEFMT format,
struct avrpart * p, char * memtype, int size, size_t offset);
struct avrpart * p, char * memtype, int size, unsigned section);
#ifdef __cplusplus
}
@ -870,7 +870,7 @@ enum updateflags {
typedef struct update_t {
char * memtype;
int op;
size_t offset;
unsigned section;
char * filename;
int format;
} UPDATE;
@ -882,7 +882,7 @@ extern "C" {
extern UPDATE * parse_op(char * s);
extern UPDATE * dup_update(UPDATE * upd);
extern UPDATE * new_update(int op, char * memtype, int filefmt,
char * filename, size_t offset);
char * filename, unsigned section);
extern void free_update(UPDATE * upd);
extern int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd,
enum updateflags flags);

View File

@ -194,7 +194,7 @@ static void usage(void)
" -F Override invalid signature check.\n"
" -e Perform a chip erase.\n"
" -O Perform RC oscillator calibration (see AVR053). \n"
" -U <memtype>:r|w|v:<offset>:<filename>[:format]\n"
" -U <memtype>:r|w|v:<section>:<filename>[:format]\n"
" Memory operation specification.\n"
" Multiple -U options are allowed, each request\n"
" is performed in the order specified.\n"

View File

@ -101,22 +101,22 @@ UPDATE * parse_op(char * s)
p++;
// Extension: Parse file contents offset
size_t offset = 0;
// Extension: Parse file section number
unsigned section = 0;
for (; *p != ':'; p++) {
if (*p >= '0' && *p <= '9') {
offset *= 10;
offset += *p - 0x30;
section *= 10;
section += *p - 0x30;
} else {
avrdude_message(MSG_INFO, "%s: invalid update specification: offset is not a number\n", progname);
avrdude_message(MSG_INFO, "%s: invalid update specification: <section> is not a number\n", progname);
free(upd->memtype);
free(upd);
return NULL;
}
}
upd->offset = offset;
upd->section = section;
p++;
/*
@ -194,7 +194,7 @@ UPDATE * dup_update(UPDATE * upd)
return u;
}
UPDATE * new_update(int op, char * memtype, int filefmt, char * filename, size_t offset)
UPDATE * new_update(int op, char * memtype, int filefmt, char * filename, unsigned section)
{
UPDATE * u;
@ -208,7 +208,7 @@ UPDATE * new_update(int op, char * memtype, int filefmt, char * filename, size_t
u->filename = strdup(filename);
u->op = op;
u->format = filefmt;
u->offset = offset;
u->section = section;
return u;
}
@ -286,7 +286,7 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
progname,
strcmp(upd->filename, "-")==0 ? "<stdin>" : upd->filename);
}
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1, upd->offset);
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1, upd->section);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: read from file '%s' failed\n",
progname, upd->filename);
@ -351,7 +351,7 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
progname, mem->desc, upd->filename);
}
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1, upd->offset);
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1, upd->section);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: read from file '%s' failed\n",
progname, upd->filename);

View File

@ -95,7 +95,7 @@ struct FirmwareDialog::priv
void find_serial_ports();
void flashing_start(bool flashing_l10n);
void flashing_done(AvrDudeComplete complete);
size_t hex_lang_offset(const wxString &path);
size_t hex_num_sections(const wxString &path);
void perform_upload();
void cancel();
void on_avrdude(const wxCommandEvent &evt);
@ -158,7 +158,7 @@ void FirmwareDialog::priv::flashing_done(AvrDudeComplete complete)
}
}
size_t FirmwareDialog::priv::hex_lang_offset(const wxString &path)
size_t FirmwareDialog::priv::hex_num_sections(const wxString &path)
{
fs::ifstream file(fs::path(path.wx_str()));
if (! file.good()) {
@ -175,18 +175,11 @@ size_t FirmwareDialog::priv::hex_lang_offset(const wxString &path)
}
if (line == hex_terminator) {
if (res == 0) {
// This is the first terminator seen, save the position
res = file.tellg();
} else {
// We've found another terminator, return the offset just after the first one
// which is the start of the second 'section'.
return res;
}
res++;
}
}
return 0;
return res;
}
void FirmwareDialog::priv::perform_upload()
@ -202,10 +195,10 @@ void FirmwareDialog::priv::perform_upload()
if (filename.IsEmpty() || port.empty()) { return; }
const bool extra_verbose = false; // For debugging
const auto lang_offset = hex_lang_offset(filename);
const auto num_secions = hex_num_sections(filename);
const auto filename_utf8 = filename.utf8_str();
flashing_start(lang_offset > 0);
flashing_start(num_secions > 1);
// It is ok here to use the q-pointer to the FirmwareDialog
// because the dialog ensures it doesn't exit before the background thread is done.
@ -236,7 +229,7 @@ void FirmwareDialog::priv::perform_upload()
avrdude.push_args(std::move(args));
if (lang_offset > 0) {
if (num_secions > 1) {
// The hex file also contains another section with l10n data to be flashed into the external flash on MK3 (Einsy)
// This is done via another avrdude invocation, here we build arg list for that:
std::vector<std::string> args_l10n {{
@ -249,7 +242,7 @@ void FirmwareDialog::priv::perform_upload()
"-b", "115200",
"-D",
"-u", // disable safe mode
"-U", (boost::format("flash:w:%1%:%2%:i") % lang_offset % filename_utf8.data()).str(),
"-U", (boost::format("flash:w:1:%1%:i") % filename_utf8.data()).str(),
}};
BOOST_LOG_TRIVIAL(info) << "Invoking avrdude for external flash flashing, arguments: "