avrdude: add file offset to update operation spec, refactoring
This commit is contained in:
parent
7863412687
commit
15f943938b
@ -80,6 +80,49 @@ static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int prusa_init_external_flash(PROGRAMMER * pgm)
|
||||
{
|
||||
// Note: send/receive as in _the firmare_ send & receives
|
||||
const char entry_magic_send [] = "start\n";
|
||||
const char entry_magic_receive[] = "w25x20cl_enter\n";
|
||||
const char entry_magic_cfm [] = "w25x20cl_cfm\n";
|
||||
const size_t buffer_len = 32; // Should be large enough for the above messages
|
||||
|
||||
int res;
|
||||
size_t recv_size;
|
||||
char *buffer = alloca(buffer_len);
|
||||
|
||||
// 1. receive the "start" command
|
||||
recv_size = sizeof(entry_magic_send) - 1;
|
||||
res = serial_recv(&pgm->fd, buffer, recv_size);
|
||||
if (res < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: prusa_init_external_flash(): MK3 printer did not boot up on time or serial communication failed\n", progname);
|
||||
return -1;
|
||||
} else if (strncmp(buffer, entry_magic_send, recv_size) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: prusa_init_external_flash(): MK3 printer emitted incorrect start code\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 2. Send the external flash programmer enter command
|
||||
if (serial_send(&pgm->fd, entry_magic_receive, sizeof(entry_magic_receive) - 1) < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: prusa_init_external_flash(): Failed to send command to the printer\n",progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 3. Receive the entry confirmation command
|
||||
recv_size = sizeof(entry_magic_cfm) - 1;
|
||||
res = serial_recv(&pgm->fd, buffer, recv_size);
|
||||
if (res < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: prusa_init_external_flash(): MK3 printer did not boot up on time or serial communication failed\n", progname);
|
||||
return -1;
|
||||
} else if (strncmp(buffer, entry_magic_cfm, recv_size) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: prusa_init_external_flash(): MK3 printer emitted incorrect start code\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arduino_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
union pinfo pinfo;
|
||||
@ -102,56 +145,10 @@ static int arduino_open(PROGRAMMER * pgm, char * port)
|
||||
*/
|
||||
stk500_drain(pgm, 0);
|
||||
|
||||
{
|
||||
//FIXME initialization sequence for programming the external FLASH.
|
||||
const char entry_magic_send [] = "start\n";
|
||||
const char entry_magic_receive[] = "w25x20cl_enter\n";
|
||||
const char entry_magic_cfm [] = "w25x20cl_cfm\n";
|
||||
const char *entry_magic_ptr = entry_magic_send;
|
||||
struct timeval tv;
|
||||
double tstart, tnow;
|
||||
char c;
|
||||
gettimeofday(&tv, NULL);
|
||||
tstart = tv.tv_sec;
|
||||
while (*entry_magic_ptr != 0) {
|
||||
if (serial_recv(&pgm->fd, &c, 1) < 0)
|
||||
goto timedout;
|
||||
printf("Received: %c (%d)\n", c, (int)c);
|
||||
if (c != *entry_magic_ptr ++) {
|
||||
avrdude_message(MSG_INFO, "%s: stk500v2_recv(): MK3 printer emited incorrect start code\n", progname);
|
||||
return -1;
|
||||
// Initialization sequence for programming the external FLASH on the Prusa MK3
|
||||
if (prusa_init_external_flash(pgm) < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: arduino_open(): Failed to initialize MK3 external flash programming mode\n", progname);
|
||||
}
|
||||
gettimeofday(&tv, NULL);
|
||||
tnow = tv.tv_sec;
|
||||
if (tnow-tstart > 2.) { // wuff - signed/unsigned/overflow
|
||||
timedout:
|
||||
avrdude_message(MSG_INFO, "%s: stk500v2_recv(): MK3 printer did not boot up on time\n", progname);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (serial_send(&pgm->fd, entry_magic_receive, strlen(entry_magic_receive)) < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: stk500v2_send(): failed to send command to serial port\n",progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
entry_magic_ptr = entry_magic_cfm;
|
||||
while (*entry_magic_ptr != 0) {
|
||||
if (serial_recv(&pgm->fd, &c, 1) < 0)
|
||||
goto timedout2;
|
||||
printf("Received: %c (%d)\n", c, (int)c);
|
||||
if (c != *entry_magic_ptr++) {
|
||||
avrdude_message(MSG_INFO, "%s: stk500v2_recv(): MK3 printer emited incorrect start code\n", progname);
|
||||
return -1;
|
||||
}
|
||||
gettimeofday(&tv, NULL);
|
||||
tnow = tv.tv_sec;
|
||||
if (tnow - tstart > 2.) { // wuff - signed/unsigned/overflow
|
||||
timedout2:
|
||||
avrdude_message(MSG_INFO, "%s: stk500v2_recv(): MK3 printer did not boot up on time\n", progname);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stk500_getsync(pgm) < 0)
|
||||
return -1;
|
||||
|
@ -45,7 +45,7 @@
|
||||
|
||||
#define MAX_LINE_LEN 256 /* max line length for ASCII format input files */
|
||||
|
||||
#define MAX_MODE_LEN 32 // For fopen_utf8()
|
||||
#define MAX_MODE_LEN 32 // For fopen_and_seek()
|
||||
|
||||
|
||||
struct ihexrec {
|
||||
@ -98,12 +98,13 @@ static int fileio_num(struct fioparms * fio,
|
||||
char * filename, FILE * f, AVRMEM * mem, int size,
|
||||
FILEFMT fmt);
|
||||
|
||||
static int fmt_autodetect(char * fname);
|
||||
static int fmt_autodetect(char * fname, size_t offset);
|
||||
|
||||
|
||||
|
||||
static FILE *fopen_utf8(const char *filename, const char *mode)
|
||||
static FILE *fopen_and_seek(const char *filename, const char *mode, size_t offset)
|
||||
{
|
||||
FILE *file;
|
||||
// On Windows we need to convert the filename to UTF-16
|
||||
#if defined(WIN32NATIVE)
|
||||
static wchar_t fname_buffer[PATH_MAX];
|
||||
@ -112,10 +113,24 @@ static FILE *fopen_utf8(const char *filename, const char *mode)
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, fname_buffer, PATH_MAX) == 0) { return NULL; }
|
||||
if (MultiByteToWideChar(CP_ACP, 0, mode, -1, mode_buffer, MAX_MODE_LEN) == 0) { return NULL; }
|
||||
|
||||
return _wfopen(fname_buffer, mode_buffer);
|
||||
file = _wfopen(fname_buffer, mode_buffer);
|
||||
#else
|
||||
return fopen(filename, mode);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
@ -1377,7 +1392,7 @@ int fileio_setparms(int op, struct fioparms * fp,
|
||||
|
||||
|
||||
|
||||
static int fmt_autodetect(char * fname)
|
||||
static int fmt_autodetect(char * fname, size_t offset)
|
||||
{
|
||||
FILE * f;
|
||||
unsigned char buf[MAX_LINE_LEN];
|
||||
@ -1387,9 +1402,9 @@ static int fmt_autodetect(char * fname)
|
||||
int first = 1;
|
||||
|
||||
#if defined(WIN32NATIVE)
|
||||
f = fopen_utf8(fname, "r");
|
||||
f = fopen_and_seek(fname, "r", offset);
|
||||
#else
|
||||
f = fopen(fname, "rb");
|
||||
f = fopen_and_seek(fname, "rb", offset);
|
||||
#endif
|
||||
|
||||
if (f == NULL) {
|
||||
@ -1465,7 +1480,7 @@ static int fmt_autodetect(char * fname)
|
||||
|
||||
|
||||
int fileio(int op, char * filename, FILEFMT format,
|
||||
struct avrpart * p, char * memtype, int size)
|
||||
struct avrpart * p, char * memtype, int size, size_t offset)
|
||||
{
|
||||
int rc;
|
||||
FILE * f;
|
||||
@ -1497,15 +1512,17 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
using_stdio = 0;
|
||||
|
||||
if (strcmp(filename, "-")==0) {
|
||||
if (fio.op == FIO_READ) {
|
||||
fname = "<stdin>";
|
||||
f = stdin;
|
||||
}
|
||||
else {
|
||||
fname = "<stdout>";
|
||||
f = stdout;
|
||||
}
|
||||
using_stdio = 1;
|
||||
return -1;
|
||||
// Note: we don't want to read stdin or write to stdout as part of Slic3r
|
||||
// if (fio.op == FIO_READ) {
|
||||
// fname = "<stdin>";
|
||||
// f = stdin;
|
||||
// }
|
||||
// else {
|
||||
// fname = "<stdout>";
|
||||
// f = stdout;
|
||||
// }
|
||||
// using_stdio = 1;
|
||||
}
|
||||
else {
|
||||
fname = filename;
|
||||
@ -1522,7 +1539,7 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
return -1;
|
||||
}
|
||||
|
||||
format_detect = fmt_autodetect(fname);
|
||||
format_detect = fmt_autodetect(fname, offset);
|
||||
if (format_detect < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: can't determine file format for %s, specify explicitly\n",
|
||||
progname, fname);
|
||||
@ -1553,7 +1570,7 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
|
||||
if (format != FMT_IMM) {
|
||||
if (!using_stdio) {
|
||||
f = fopen_utf8(fname, fio.mode);
|
||||
f = fopen_and_seek(fname, fio.mode, offset);
|
||||
if (f == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: can't open %s file %s: %s\n",
|
||||
progname, fio.iodesc, fname, strerror(errno));
|
||||
|
@ -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);
|
||||
struct avrpart * p, char * memtype, int size, size_t offset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@ -870,6 +870,7 @@ enum updateflags {
|
||||
typedef struct update_t {
|
||||
char * memtype;
|
||||
int op;
|
||||
size_t offset;
|
||||
char * filename;
|
||||
int format;
|
||||
} UPDATE;
|
||||
@ -881,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);
|
||||
char * filename, size_t offset);
|
||||
extern void free_update(UPDATE * upd);
|
||||
extern int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd,
|
||||
enum updateflags flags);
|
||||
|
@ -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:<filename>[:format]\n"
|
||||
" -U <memtype>:r|w|v:<offset>:<filename>[:format]\n"
|
||||
" Memory operation specification.\n"
|
||||
" Multiple -U options are allowed, each request\n"
|
||||
" is performed in the order specified.\n"
|
||||
|
@ -101,6 +101,25 @@ UPDATE * parse_op(char * s)
|
||||
|
||||
p++;
|
||||
|
||||
// Extension: Parse file contents offset
|
||||
size_t offset = 0;
|
||||
|
||||
for (; *p != ':'; p++) {
|
||||
if (*p >= '0' && *p <= '9') {
|
||||
offset *= 10;
|
||||
offset += *p - 0x30;
|
||||
} else {
|
||||
avrdude_message(MSG_INFO, "%s: invalid update specification: offset is not a number\n", progname);
|
||||
free(upd->memtype);
|
||||
free(upd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
upd->offset = offset;
|
||||
printf("parse_op: offset: %lu\n", offset);
|
||||
p++;
|
||||
|
||||
/*
|
||||
* Now, parse the filename component. Instead of looking for the
|
||||
* leftmost possible colon delimiter, we look for the rightmost one.
|
||||
@ -176,7 +195,7 @@ UPDATE * dup_update(UPDATE * upd)
|
||||
return u;
|
||||
}
|
||||
|
||||
UPDATE * new_update(int op, char * memtype, int filefmt, char * filename)
|
||||
UPDATE * new_update(int op, char * memtype, int filefmt, char * filename, size_t offset)
|
||||
{
|
||||
UPDATE * u;
|
||||
|
||||
@ -190,6 +209,7 @@ UPDATE * new_update(int op, char * memtype, int filefmt, char * filename)
|
||||
u->filename = strdup(filename);
|
||||
u->op = op;
|
||||
u->format = filefmt;
|
||||
u->offset = offset;
|
||||
|
||||
return u;
|
||||
}
|
||||
@ -250,7 +270,7 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
||||
progname,
|
||||
strcmp(upd->filename, "-")==0 ? "<stdout>" : upd->filename);
|
||||
}
|
||||
rc = fileio(FIO_WRITE, upd->filename, upd->format, p, upd->memtype, size);
|
||||
rc = fileio(FIO_WRITE, upd->filename, upd->format, p, upd->memtype, size, 0);
|
||||
if (rc < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: write to file '%s' failed\n",
|
||||
progname, upd->filename);
|
||||
@ -267,7 +287,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);
|
||||
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1, upd->offset);
|
||||
if (rc < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: read from file '%s' failed\n",
|
||||
progname, upd->filename);
|
||||
@ -296,11 +316,11 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
||||
report_progress(1,1,NULL);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* test mode, don't actually write to the chip, output the buffer
|
||||
* to stdout in intel hex instead
|
||||
*/
|
||||
rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, upd->memtype, size);
|
||||
// /*
|
||||
// * test mode, don't actually write to the chip, output the buffer
|
||||
// * to stdout in intel hex instead
|
||||
// */
|
||||
// rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, upd->memtype, size, 0);
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
@ -332,7 +352,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);
|
||||
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1, upd->offset);
|
||||
if (rc < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: read from file '%s' failed\n",
|
||||
progname, upd->filename);
|
||||
|
@ -182,8 +182,8 @@ void FirmwareDialog::priv::perform_upload()
|
||||
"-b", "115200", // XXX: is this ok to hardcode?
|
||||
"-D",
|
||||
"-u", // disable safe mode
|
||||
"-U", (boost::format("flash:w:%1%:i") % filename_utf8.data()).str()
|
||||
// "-v", "-v", "-v", "-v", "-v", // enable super verbose mode, logging each serial line exchange
|
||||
"-U", (boost::format("flash:w:0:%1%:i") % filename_utf8.data()).str(), // FIXME
|
||||
// "-vvvvv", //"-v", "-v", "-v", "-v", // enable super verbose mode, logging each serial line exchange
|
||||
}};
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "Invoking avrdude, arguments: "
|
||||
|
Loading…
Reference in New Issue
Block a user