Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
fileio.c File Reference
#include "ac_cfg.h"
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <stdint.h>
#include "avrdude.h"
#include "libavrdude.h"
+ Include dependency graph for fileio.c:

Go to the source code of this file.

Classes

struct  ihexrec
 

Macros

#define IHEX_MAXDATA   256
 
#define MAX_LINE_LEN   256 /* max line length for ASCII format input files */
 
#define MAX_MODE_LEN   32
 

Functions

static int b2ihex (unsigned char *inbuf, int bufsize, int recsize, int startaddr, char *outfile, FILE *outf)
 
static int ihex2b (char *infile, FILE *inf, AVRMEM *mem, int bufsize, unsigned int fileoffset)
 
static int b2srec (unsigned char *inbuf, int bufsize, int recsize, int startaddr, char *outfile, FILE *outf)
 
static int srec2b (char *infile, FILE *inf, AVRMEM *mem, int bufsize, unsigned int fileoffset)
 
static int ihex_readrec (struct ihexrec *ihex, char *rec)
 
static int srec_readrec (struct ihexrec *srec, char *rec)
 
static int fileio_rbin (struct fioparms *fio, char *filename, FILE *f, AVRMEM *mem, int size)
 
static int fileio_ihex (struct fioparms *fio, char *filename, FILE *f, AVRMEM *mem, int size)
 
static int fileio_srec (struct fioparms *fio, char *filename, FILE *f, AVRMEM *mem, int size)
 
static int fileio_num (struct fioparms *fio, char *filename, FILE *f, AVRMEM *mem, int size, FILEFMT fmt)
 
static int fmt_autodetect (char *fname, unsigned section)
 
FILE * fopen_utf8 (const char *filename, const char *mode)
 
static FILE * fopen_and_seek (const char *filename, const char *mode, unsigned section)
 
char * fmtstr (FILEFMT format)
 
static char * itoa_simple (int n, char *buf, int base)
 
static int fileio_imm (struct fioparms *fio, char *filename, FILE *f, AVRMEM *mem, int size)
 
int fileio_setparms (int op, struct fioparms *fp, struct avrpart *p, AVRMEM *m)
 
int fileio (int op, char *filename, FILEFMT format, struct avrpart *p, char *memtype, int size, unsigned section)
 

Class Documentation

◆ ihexrec

struct ihexrec
Class Members
unsigned char cksum
unsigned char data[IHEX_MAXDATA]
unsigned int loadofs
unsigned char reclen
unsigned char rectyp

Macro Definition Documentation

◆ IHEX_MAXDATA

#define IHEX_MAXDATA   256

◆ MAX_LINE_LEN

#define MAX_LINE_LEN   256 /* max line length for ASCII format input files */

◆ MAX_MODE_LEN

#define MAX_MODE_LEN   32

Function Documentation

◆ b2ihex()

static int b2ihex ( unsigned char *  inbuf,
int  bufsize,
int  recsize,
int  startaddr,
char *  outfile,
FILE *  outf 
)
static
183{
184 unsigned char * buf;
185 unsigned int nextaddr;
186 int n, nbytes, n_64k;
187 int i;
188 unsigned char cksum;
189
190 if (recsize > 255) {
191 avrdude_message(MSG_INFO, "%s: recsize=%d, must be < 256\n",
192 progname, recsize);
193 return -1;
194 }
195
196 n_64k = 0;
197 nextaddr = startaddr;
198 buf = inbuf;
199 nbytes = 0;
200
201 while (bufsize) {
202 n = recsize;
203 if (n > bufsize)
204 n = bufsize;
205
206 if ((nextaddr + n) > 0x10000)
207 n = 0x10000 - nextaddr;
208
209 if (n) {
210 cksum = 0;
211 fprintf(outf, ":%02X%04X00", n, nextaddr);
212 cksum += n + ((nextaddr >> 8) & 0x0ff) + (nextaddr & 0x0ff);
213 for (i=0; i<n; i++) {
214 fprintf(outf, "%02X", buf[i]);
215 cksum += buf[i];
216 }
217 cksum = -cksum;
218 fprintf(outf, "%02X\n", cksum);
219
220 nextaddr += n;
221 nbytes += n;
222 }
223
224 if (nextaddr >= 0x10000) {
225 int lo, hi;
226 /* output an extended address record */
227 n_64k++;
228 lo = n_64k & 0xff;
229 hi = (n_64k >> 8) & 0xff;
230 cksum = 0;
231 fprintf(outf, ":02000004%02X%02X", hi, lo);
232 cksum += 2 + 0 + 4 + hi + lo;
233 cksum = -cksum;
234 fprintf(outf, "%02X\n", cksum);
235 nextaddr = 0;
236 }
237
238 /* advance to next 'recsize' bytes */
239 buf += n;
240 bufsize -= n;
241 }
242
243 /*-----------------------------------------------------------------
244 add the end of record data line
245 -----------------------------------------------------------------*/
246 cksum = 0;
247 n = 0;
248 nextaddr = 0;
249 fprintf(outf, ":%02X%04X01", n, nextaddr);
250 cksum += n + ((nextaddr >> 8) & 0x0ff) + (nextaddr & 0x0ff) + 1;
251 cksum = -cksum;
252 fprintf(outf, "%02X\n", cksum);
253
254 return nbytes;
255}
#define MSG_INFO
Definition avrdude.h:51
char * progname
Definition main.c:61
int avrdude_message(const int msglvl, const char *format,...)
Definition main.c:93

References avrdude_message(), MSG_INFO, and progname.

Referenced by fileio_ihex().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ b2srec()

static int b2srec ( unsigned char *  inbuf,
int  bufsize,
int  recsize,
int  startaddr,
char *  outfile,
FILE *  outf 
)
static
453{
454 unsigned char * buf;
455 unsigned int nextaddr;
456 int n, nbytes, addr_width;
457 int i;
458 unsigned char cksum;
459
460 char * tmpl=0;
461
462 if (recsize > 255) {
463 avrdude_message(MSG_INFO, "%s: ERROR: recsize=%d, must be < 256\n",
464 progname, recsize);
465 return -1;
466 }
467
468 nextaddr = startaddr;
469 buf = inbuf;
470 nbytes = 0;
471
472 addr_width = 0;
473
474 while (bufsize) {
475
476 n = recsize;
477
478 if (n > bufsize)
479 n = bufsize;
480
481 if (n) {
482 cksum = 0;
483 if (nextaddr + n <= 0xffff) {
484 addr_width = 2;
485 tmpl="S1%02X%04X";
486 }
487 else if (nextaddr + n <= 0xffffff) {
488 addr_width = 3;
489 tmpl="S2%02X%06X";
490 }
491 else if (nextaddr + n <= 0xffffffff) {
492 addr_width = 4;
493 tmpl="S3%02X%08X";
494 }
495 else {
496 avrdude_message(MSG_INFO, "%s: ERROR: address=%d, out of range\n",
497 progname, nextaddr);
498 return -1;
499 }
500
501 fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
502
503 cksum += n + addr_width + 1;
504
505 for (i = addr_width; i>0; i--) {
506 cksum += (nextaddr >> (i-1) * 8) & 0xff;
507 }
508
509 for (unsigned i = nextaddr; i < nextaddr + n; i++) {
510 fprintf(outf, "%02X", buf[i]);
511 cksum += buf[i];
512 }
513
514 cksum = 0xff - cksum;
515 fprintf(outf, "%02X\n", cksum);
516
517 nextaddr += n;
518 nbytes +=n;
519 }
520
521 /* advance to next 'recsize' bytes */
522 bufsize -= n;
523 }
524
525 /*-----------------------------------------------------------------
526 add the end of record data line
527 -----------------------------------------------------------------*/
528 cksum = 0;
529 n = 0;
530 nextaddr = 0;
531
532 if (startaddr <= 0xffff) {
533 addr_width = 2;
534 tmpl="S9%02X%04X";
535 }
536 else if (startaddr <= 0xffffff) {
537 addr_width = 3;
538 tmpl="S9%02X%06X";
539 }
540 else if (startaddr <= 0xffffffff) {
541 addr_width = 4;
542 tmpl="S9%02X%08X";
543 }
544
545 fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
546
547 cksum += n + addr_width +1;
548 for (i=addr_width; i>0; i--)
549 cksum += (nextaddr >> (i - 1) * 8) & 0xff;
550 cksum = 0xff - cksum;
551 fprintf(outf, "%02X\n", cksum);
552
553 return nbytes;
554}

References avrdude_message(), ihexrec::cksum, MSG_INFO, and progname.

Referenced by fileio_srec().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fileio()

int fileio ( int  op,
char *  filename,
FILEFMT  format,
struct avrpart p,
char *  memtype,
int  size,
unsigned  section 
)
1514{
1515 int rc;
1516 FILE * f;
1517 char * fname;
1518 struct fioparms fio;
1519 AVRMEM * mem;
1520 int using_stdio;
1521
1522 mem = avr_locate_mem(p, memtype);
1523 if (mem == NULL) {
1524 avrdude_message(MSG_INFO, "fileio(): memory type \"%s\" not configured for device \"%s\"\n",
1525 memtype, p->desc);
1526 return -1;
1527 }
1528
1529 rc = fileio_setparms(op, &fio, p, mem);
1530 if (rc < 0)
1531 return -1;
1532
1533 if (fio.op == FIO_READ)
1534 size = mem->size;
1535
1536 if (fio.op == FIO_READ) {
1537 /* 0xff fill unspecified memory */
1538 memset(mem->buf, 0xff, size);
1539 }
1540 memset(mem->tags, 0, size);
1541
1542 using_stdio = 0;
1543
1544 if (strcmp(filename, "-")==0) {
1545 return -1;
1546 // Note: we don't want to read stdin or write to stdout as part of Slic3r
1547 // if (fio.op == FIO_READ) {
1548 // fname = "<stdin>";
1549 // f = stdin;
1550 // }
1551 // else {
1552 // fname = "<stdout>";
1553 // f = stdout;
1554 // }
1555 // using_stdio = 1;
1556 }
1557 else {
1558 fname = filename;
1559 f = NULL;
1560 }
1561
1562 if (format == FMT_AUTO) {
1563 int format_detect;
1564
1565 if (using_stdio) {
1566 avrdude_message(MSG_INFO, "%s: can't auto detect file format when using stdin/out.\n"
1567 "%s Please specify a file format and try again.\n",
1568 progname, progbuf);
1569 return -1;
1570 }
1571
1572 format_detect = fmt_autodetect(fname, section);
1573 if (format_detect < 0) {
1574 avrdude_message(MSG_INFO, "%s: can't determine file format for %s, specify explicitly\n",
1575 progname, fname);
1576 return -1;
1577 }
1578 format = format_detect;
1579
1580 if (quell_progress < 2) {
1581 avrdude_message(MSG_INFO, "%s: %s file %s auto detected as %s\n",
1582 progname, fio.iodesc, fname, fmtstr(format));
1583 }
1584 }
1585
1586#if defined(WIN32NATIVE)
1587 /* Open Raw Binary and ELF format in binary mode on Windows.*/
1588 if(format == FMT_RBIN || format == FMT_ELF)
1589 {
1590 if(fio.op == FIO_READ)
1591 {
1592 fio.mode = "rb";
1593 }
1594 if(fio.op == FIO_WRITE)
1595 {
1596 fio.mode = "wb";
1597 }
1598 }
1599#endif
1600
1601 if (format != FMT_IMM) {
1602 if (!using_stdio) {
1603 f = fopen_and_seek(fname, fio.mode, section);
1604 if (f == NULL) {
1605 avrdude_message(MSG_INFO, "%s: can't open %s file %s: %s\n",
1606 progname, fio.iodesc, fname, strerror(errno));
1607 return -1;
1608 }
1609 }
1610 }
1611
1612 switch (format) {
1613 case FMT_IHEX:
1614 rc = fileio_ihex(&fio, fname, f, mem, size);
1615 break;
1616
1617 case FMT_SREC:
1618 rc = fileio_srec(&fio, fname, f, mem, size);
1619 break;
1620
1621 case FMT_RBIN:
1622 rc = fileio_rbin(&fio, fname, f, mem, size);
1623 break;
1624
1625 case FMT_ELF:
1626#ifdef HAVE_LIBELF
1627 rc = fileio_elf(&fio, fname, f, mem, p, size);
1628#else
1629 avrdude_message(MSG_INFO, "%s: can't handle ELF file %s, "
1630 "ELF file support was not compiled in\n",
1631 progname, fname);
1632 rc = -1;
1633#endif
1634 break;
1635
1636 case FMT_IMM:
1637 rc = fileio_imm(&fio, fname, f, mem, size);
1638 break;
1639
1640 case FMT_HEX:
1641 case FMT_DEC:
1642 case FMT_OCT:
1643 case FMT_BIN:
1644 rc = fileio_num(&fio, fname, f, mem, size, format);
1645 break;
1646
1647 default:
1648 avrdude_message(MSG_INFO, "%s: invalid %s file format: %d\n",
1649 progname, fio.iodesc, format);
1650 return -1;
1651 }
1652
1653 if (rc > 0) {
1654 if ((op == FIO_READ) && (strcasecmp(mem->desc, "flash") == 0 ||
1655 strcasecmp(mem->desc, "application") == 0 ||
1656 strcasecmp(mem->desc, "apptable") == 0 ||
1657 strcasecmp(mem->desc, "boot") == 0)) {
1658 /*
1659 * if we are reading flash, just mark the size as being the
1660 * highest non-0xff byte
1661 */
1662 rc = avr_mem_hiaddr(mem);
1663 }
1664 }
1665 if (format != FMT_IMM && !using_stdio) {
1666 fclose(f);
1667 }
1668
1669 return rc;
1670}
int avr_mem_hiaddr(AVRMEM *mem)
Definition avr.c:284
char progbuf[]
Definition main.c:62
int quell_progress
Definition main.c:199
AVRMEM * avr_locate_mem(AVRPART *p, char *desc)
Definition avrpart.c:354
static int fileio_imm(struct fioparms *fio, char *filename, FILE *f, AVRMEM *mem, int size)
Definition fileio.c:1171
static int fileio_num(struct fioparms *fio, char *filename, FILE *f, AVRMEM *mem, int size, FILEFMT fmt)
Definition fileio.c:1308
static FILE * fopen_and_seek(const char *filename, const char *mode, unsigned section)
Definition fileio.c:124
char * fmtstr(FILEFMT format)
Definition fileio.c:166
int fileio_setparms(int op, struct fioparms *fp, struct avrpart *p, AVRMEM *m)
Definition fileio.c:1380
static int fileio_rbin(struct fioparms *fio, char *filename, FILE *f, AVRMEM *mem, int size)
Definition fileio.c:1139
static int fileio_ihex(struct fioparms *fio, char *filename, FILE *f, AVRMEM *mem, int size)
Definition fileio.c:1217
static int fmt_autodetect(char *fname, unsigned section)
Definition fileio.c:1425
static int fileio_srec(struct fioparms *fio, char *filename, FILE *f, AVRMEM *mem, int size)
Definition fileio.c:1247
int op
Definition libavrdude.h:800
@ FIO_WRITE
Definition libavrdude.h:810
@ FIO_READ
Definition libavrdude.h:809
char desc[AVR_DESCLEN]
Definition libavrdude.h:218
@ FMT_AUTO
Definition libavrdude.h:787
@ FMT_RBIN
Definition libavrdude.h:790
@ FMT_HEX
Definition libavrdude.h:792
@ FMT_BIN
Definition libavrdude.h:795
@ FMT_OCT
Definition libavrdude.h:794
@ FMT_IHEX
Definition libavrdude.h:789
@ FMT_ELF
Definition libavrdude.h:796
@ FMT_IMM
Definition libavrdude.h:791
@ FMT_DEC
Definition libavrdude.h:793
@ FMT_SREC
Definition libavrdude.h:788
Definition libavrdude.h:799
Definition libavrdude.h:283
std::string format(const char *fmt, TArgs &&... args)
Definition format.hpp:44
constexpr auto size(const C &c) -> decltype(c.size())
Definition span.hpp:183
#define strcasecmp
Definition unistd.h:52

References avr_locate_mem(), avr_mem_hiaddr(), avrdude_message(), avrpart::desc, fileio_ihex(), fileio_imm(), fileio_num(), fileio_rbin(), fileio_setparms(), fileio_srec(), FIO_READ, FIO_WRITE, FMT_AUTO, fmt_autodetect(), FMT_BIN, FMT_DEC, FMT_ELF, FMT_HEX, FMT_IHEX, FMT_IMM, FMT_OCT, FMT_RBIN, FMT_SREC, fmtstr(), fopen_and_seek(), fioparms::iodesc, fioparms::mode, MSG_INFO, fioparms::op, progbuf, progname, quell_progress, and strcasecmp.

Referenced by do_op().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fileio_ihex()

static int fileio_ihex ( struct fioparms fio,
char *  filename,
FILE *  f,
AVRMEM mem,
int  size 
)
static
1219{
1220 int rc;
1221
1222 switch (fio->op) {
1223 case FIO_WRITE:
1224 rc = b2ihex(mem->buf, size, 32, fio->fileoffset, filename, f);
1225 if (rc < 0) {
1226 return -1;
1227 }
1228 break;
1229
1230 case FIO_READ:
1231 rc = ihex2b(filename, f, mem, size, fio->fileoffset);
1232 if (rc < 0)
1233 return -1;
1234 break;
1235
1236 default:
1237 avrdude_message(MSG_INFO, "%s: invalid Intex Hex file I/O operation=%d\n",
1238 progname, fio->op);
1239 return -1;
1240 break;
1241 }
1242
1243 return rc;
1244}
static int ihex2b(char *infile, FILE *inf, AVRMEM *mem, int bufsize, unsigned int fileoffset)
Definition fileio.c:346
static int b2ihex(unsigned char *inbuf, int bufsize, int recsize, int startaddr, char *outfile, FILE *outf)
Definition fileio.c:180
unsigned int fileoffset
Definition libavrdude.h:805
unsigned char * buf
Definition libavrdude.h:304

References avrdude_message(), b2ihex(), avrmem::buf, fioparms::fileoffset, FIO_READ, FIO_WRITE, ihex2b(), MSG_INFO, fioparms::op, and progname.

Referenced by fileio().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fileio_imm()

static int fileio_imm ( struct fioparms fio,
char *  filename,
FILE *  f,
AVRMEM mem,
int  size 
)
static
1173{
1174 int rc = 0;
1175 char * e, * p;
1176 unsigned long b;
1177 int loc;
1178
1179 switch (fio->op) {
1180 case FIO_READ:
1181 loc = 0;
1182 p = strtok(filename, " ,");
1183 while (p != NULL && loc < size) {
1184 b = strtoul(p, &e, 0);
1185 /* check for binary formated (0b10101001) strings */
1186 b = (strncmp (p, "0b", 2))?
1187 strtoul (p, &e, 0):
1188 strtoul (p + 2, &e, 2);
1189 if (*e != 0) {
1190 avrdude_message(MSG_INFO, "%s: invalid byte value (%s) specified for immediate mode\n",
1191 progname, p);
1192 return -1;
1193 }
1194 mem->buf[loc] = (char)b;
1195 mem->tags[loc++] = TAG_ALLOCATED;
1196 p = strtok(NULL, " ,");
1197 rc = loc;
1198 }
1199 break;
1200 default:
1201 avrdude_message(MSG_INFO, "%s: fileio: invalid operation=%d\n",
1202 progname, fio->op);
1203 return -1;
1204 }
1205
1206 if (rc < 0 || (fio->op == FIO_WRITE && rc < size)) {
1207 avrdude_message(MSG_INFO, "%s: %s error %s %s: %s; %s %d of the expected %d bytes\n",
1208 progname, fio->iodesc, fio->dir, filename, strerror(errno),
1209 fio->rw, rc, size);
1210 return -1;
1211 }
1212
1213 return rc;
1214}
#define TAG_ALLOCATED
Definition libavrdude.h:215
char * dir
Definition libavrdude.h:803
char * rw
Definition libavrdude.h:804
unsigned char * tags
Definition libavrdude.h:305
char * iodesc
Definition libavrdude.h:802

References avrdude_message(), avrmem::buf, fioparms::dir, FIO_READ, FIO_WRITE, fioparms::iodesc, MSG_INFO, fioparms::op, progname, fioparms::rw, TAG_ALLOCATED, and avrmem::tags.

Referenced by fileio().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fileio_num()

static int fileio_num ( struct fioparms fio,
char *  filename,
FILE *  f,
AVRMEM mem,
int  size,
FILEFMT  fmt 
)
static
1311{
1312 const char *prefix;
1313 char cbuf[20];
1314 int base, i, num;
1315
1316 switch (fmt) {
1317 case FMT_HEX:
1318 prefix = "0x";
1319 base = 16;
1320 break;
1321
1322 default:
1323 case FMT_DEC:
1324 prefix = "";
1325 base = 10;
1326 break;
1327
1328 case FMT_OCT:
1329 prefix = "0";
1330 base = 8;
1331 break;
1332
1333 case FMT_BIN:
1334 prefix = "0b";
1335 base = 2;
1336 break;
1337
1338 }
1339
1340 switch (fio->op) {
1341 case FIO_WRITE:
1342 break;
1343 default:
1344 avrdude_message(MSG_INFO, "%s: fileio: invalid operation=%d\n",
1345 progname, fio->op);
1346 return -1;
1347 }
1348
1349 for (i = 0; i < size; i++) {
1350 if (i > 0) {
1351 if (putc(',', f) == EOF)
1352 goto writeerr;
1353 }
1354 num = (unsigned int)(mem->buf[i]);
1355 /*
1356 * For a base of 8 and a value < 8 to convert, don't write the
1357 * prefix. The conversion will be indistinguishable from a
1358 * decimal one then.
1359 */
1360 if (prefix[0] != '\0' && !(base == 8 && num < 8)) {
1361 if (fputs(prefix, f) == EOF)
1362 goto writeerr;
1363 }
1364 itoa_simple(num, cbuf, base);
1365 if (fputs(cbuf, f) == EOF)
1366 goto writeerr;
1367 }
1368 if (putc('\n', f) == EOF)
1369 goto writeerr;
1370
1371 return 0;
1372
1373 writeerr:
1374 avrdude_message(MSG_INFO, "%s: error writing to %s: %s\n",
1375 progname, filename, strerror(errno));
1376 return -1;
1377}
static char * itoa_simple(int n, char *buf, int base)
Definition fileio.c:1103

References avrdude_message(), avrmem::buf, FIO_WRITE, FMT_BIN, FMT_DEC, FMT_HEX, FMT_OCT, itoa_simple(), MSG_INFO, fioparms::op, and progname.

Referenced by fileio().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fileio_rbin()

static int fileio_rbin ( struct fioparms fio,
char *  filename,
FILE *  f,
AVRMEM mem,
int  size 
)
static
1141{
1142 int rc;
1143 unsigned char *buf = mem->buf;
1144
1145 switch (fio->op) {
1146 case FIO_READ:
1147 rc = (int)fread(buf, 1, size, f);
1148 if (rc > 0)
1149 memset(mem->tags, TAG_ALLOCATED, rc);
1150 break;
1151 case FIO_WRITE:
1152 rc = (int)fwrite(buf, 1, size, f);
1153 break;
1154 default:
1155 avrdude_message(MSG_INFO, "%s: fileio: invalid operation=%d\n",
1156 progname, fio->op);
1157 return -1;
1158 }
1159
1160 if (rc < 0 || (fio->op == FIO_WRITE && rc < size)) {
1161 avrdude_message(MSG_INFO, "%s: %s error %s %s: %s; %s %d of the expected %d bytes\n",
1162 progname, fio->iodesc, fio->dir, filename, strerror(errno),
1163 fio->rw, rc, size);
1164 return -1;
1165 }
1166
1167 return rc;
1168}

References avrdude_message(), avrmem::buf, fioparms::dir, FIO_READ, FIO_WRITE, fioparms::iodesc, MSG_INFO, fioparms::op, progname, fioparms::rw, TAG_ALLOCATED, and avrmem::tags.

Referenced by fileio().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fileio_setparms()

int fileio_setparms ( int  op,
struct fioparms fp,
struct avrpart p,
AVRMEM m 
)
1382{
1383 fp->op = op;
1384
1385 switch (op) {
1386 case FIO_READ:
1387 fp->mode = "r";
1388 fp->iodesc = "input";
1389 fp->dir = "from";
1390 fp->rw = "read";
1391 break;
1392
1393 case FIO_WRITE:
1394 fp->mode = "w";
1395 fp->iodesc = "output";
1396 fp->dir = "to";
1397 fp->rw = "wrote";
1398 break;
1399
1400 default:
1401 avrdude_message(MSG_INFO, "%s: invalid I/O operation %d\n",
1402 progname, op);
1403 return -1;
1404 break;
1405 }
1406
1407 /*
1408 * AVR32 devices maintain their load offset within the file itself,
1409 * but AVRDUDE maintains all memory images 0-based.
1410 */
1411 if ((p->flags & AVRPART_AVR32) != 0)
1412 {
1413 fp->fileoffset = m->offset;
1414 }
1415 else
1416 {
1417 fp->fileoffset = 0;
1418 }
1419
1420 return 0;
1421}
char * mode
Definition libavrdude.h:801
#define AVRPART_AVR32
Definition libavrdude.h:203
unsigned int offset
Definition libavrdude.h:289
unsigned flags
Definition libavrdude.h:230

References avrdude_message(), AVRPART_AVR32, fioparms::dir, fioparms::fileoffset, FIO_READ, FIO_WRITE, avrpart::flags, fioparms::iodesc, fioparms::mode, MSG_INFO, avrmem::offset, fioparms::op, progname, and fioparms::rw.

Referenced by fileio().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fileio_srec()

static int fileio_srec ( struct fioparms fio,
char *  filename,
FILE *  f,
AVRMEM mem,
int  size 
)
static
1249{
1250 int rc;
1251
1252 switch (fio->op) {
1253 case FIO_WRITE:
1254 rc = b2srec(mem->buf, size, 32, fio->fileoffset, filename, f);
1255 if (rc < 0) {
1256 return -1;
1257 }
1258 break;
1259
1260 case FIO_READ:
1261 rc = srec2b(filename, f, mem, size, fio->fileoffset);
1262 if (rc < 0)
1263 return -1;
1264 break;
1265
1266 default:
1267 avrdude_message(MSG_INFO, "%s: ERROR: invalid Motorola S-Records file I/O "
1268 "operation=%d\n",
1269 progname, fio->op);
1270 return -1;
1271 break;
1272 }
1273
1274 return rc;
1275}
static int b2srec(unsigned char *inbuf, int bufsize, int recsize, int startaddr, char *outfile, FILE *outf)
Definition fileio.c:450
static int srec2b(char *infile, FILE *inf, AVRMEM *mem, int bufsize, unsigned int fileoffset)
Definition fileio.c:633

References avrdude_message(), b2srec(), avrmem::buf, fioparms::fileoffset, FIO_READ, FIO_WRITE, MSG_INFO, fioparms::op, progname, and srec2b().

Referenced by fileio().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fmt_autodetect()

static int fmt_autodetect ( char *  fname,
unsigned  section 
)
static
1426{
1427 FILE * f;
1428 unsigned char buf[MAX_LINE_LEN];
1429 int i;
1430 int len;
1431 int found;
1432 int first = 1;
1433
1434#if defined(WIN32NATIVE)
1435 f = fopen_and_seek(fname, "r", section);
1436#else
1437 f = fopen_and_seek(fname, "rb", section);
1438#endif
1439
1440 if (f == NULL) {
1441 avrdude_message(MSG_INFO, "%s: error opening %s: %s\n",
1442 progname, fname, strerror(errno));
1443 return -1;
1444 }
1445
1446 while (fgets((char *)buf, MAX_LINE_LEN, f)!=NULL) {
1447 /* check for ELF file */
1448 if (first &&
1449 (buf[0] == 0177 && buf[1] == 'E' &&
1450 buf[2] == 'L' && buf[3] == 'F')) {
1451 fclose(f);
1452 return FMT_ELF;
1453 }
1454
1455 buf[MAX_LINE_LEN-1] = 0;
1456 len = (int)strlen((char *)buf);
1457 if (buf[len-1] == '\n')
1458 buf[--len] = 0;
1459
1460 /* check for binary data */
1461 found = 0;
1462 for (i=0; i<len; i++) {
1463 if (buf[i] > 127) {
1464 found = 1;
1465 break;
1466 }
1467 }
1468 if (found) {
1469 fclose(f);
1470 return FMT_RBIN;
1471 }
1472
1473 /* check for lines that look like intel hex */
1474 if ((buf[0] == ':') && (len >= 11)) {
1475 found = 1;
1476 for (i=1; i<len; i++) {
1477 if (!isxdigit(buf[1])) {
1478 found = 0;
1479 break;
1480 }
1481 }
1482 if (found) {
1483 fclose(f);
1484 return FMT_IHEX;
1485 }
1486 }
1487
1488 /* check for lines that look like motorola s-record */
1489 if ((buf[0] == 'S') && (len >= 10) && isdigit(buf[1])) {
1490 found = 1;
1491 for (i=1; i<len; i++) {
1492 if (!isxdigit(buf[1])) {
1493 found = 0;
1494 break;
1495 }
1496 }
1497 if (found) {
1498 fclose(f);
1499 return FMT_SREC;
1500 }
1501 }
1502
1503 first = 0;
1504 }
1505
1506 fclose(f);
1507 return -1;
1508}
#define MAX_LINE_LEN
Definition fileio.c:49

References avrdude_message(), FMT_ELF, FMT_IHEX, FMT_RBIN, FMT_SREC, fopen_and_seek(), MAX_LINE_LEN, MSG_INFO, and progname.

Referenced by fileio().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fmtstr()

char * fmtstr ( FILEFMT  format)
167{
168 switch (format) {
169 case FMT_AUTO : return "auto-detect"; break;
170 case FMT_SREC : return "Motorola S-Record"; break;
171 case FMT_IHEX : return "Intel Hex"; break;
172 case FMT_RBIN : return "raw binary"; break;
173 case FMT_ELF : return "ELF"; break;
174 default : return "invalid format"; break;
175 };
176}

References FMT_AUTO, FMT_ELF, FMT_IHEX, FMT_RBIN, and FMT_SREC.

Referenced by fileio(), Slic3r::Utils::anonymous_namespace{Time.cpp}::process_format(), Slic3r::Utils::str2time(), and Slic3r::Utils::time2str().

+ Here is the caller graph for this function:

◆ fopen_and_seek()

static FILE * fopen_and_seek ( const char *  filename,
const char *  mode,
unsigned  section 
)
static
125{
126 FILE *file = fopen_utf8(filename, mode);
127
128 if (file == NULL) {
129 return NULL;
130 }
131
132 // Seek to the specified 'section'
133 static const char *hex_terminator = ":00000001FF\r";
134 unsigned terms_seen = 0;
135 char buffer[MAX_LINE_LEN + 1];
136
137 while (terms_seen < section && fgets(buffer, MAX_LINE_LEN, file) != NULL) {
138 size_t len = strlen(buffer);
139
140 if (buffer[len - 1] == '\n') {
141 len--;
142 buffer[len] = 0;
143 }
144 if (buffer[len - 1] != '\r') {
145 buffer[len] = '\r';
146 len++;
147 buffer[len] = 0;
148 }
149
150 if (strcmp(buffer, hex_terminator) == 0) {
151 // Found a section terminator
152 terms_seen++;
153 }
154 }
155
156 if (feof(file)) {
157 // Section not found
158 fclose(file);
159 return NULL;
160 }
161
162 return file;
163}
FILE * fopen_utf8(const char *filename, const char *mode)
Definition fileio.c:108

References fopen_utf8(), and MAX_LINE_LEN.

Referenced by fileio(), and fmt_autodetect().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fopen_utf8()

FILE * fopen_utf8 ( const char *  filename,
const char *  mode 
)
109{
110 // On Windows we need to convert the filename to UTF-16
111#if defined(WIN32NATIVE)
112 static wchar_t fname_buffer[PATH_MAX];
113 static wchar_t mode_buffer[MAX_MODE_LEN];
114
115 if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, fname_buffer, PATH_MAX) == 0) { return NULL; }
116 if (MultiByteToWideChar(CP_UTF8, 0, mode, -1, mode_buffer, MAX_MODE_LEN) == 0) { return NULL; }
117
118 return _wfopen(fname_buffer, mode_buffer);
119#else
120 return fopen(filename, mode);
121#endif
122}
#define MAX_MODE_LEN
Definition fileio.c:51
#define PATH_MAX
Definition libavrdude.h:51

References MAX_MODE_LEN, and PATH_MAX.

Referenced by fopen_and_seek(), and read_config().

+ Here is the caller graph for this function:

◆ ihex2b()

static int ihex2b ( char *  infile,
FILE *  inf,
AVRMEM mem,
int  bufsize,
unsigned int  fileoffset 
)
static
348{
349 char buffer [ MAX_LINE_LEN ];
350 unsigned int nextaddr, baseaddr, maxaddr;
351 int i;
352 int lineno;
353 int len;
354 struct ihexrec ihex;
355 int rc;
356
357 lineno = 0;
358 baseaddr = 0;
359 maxaddr = 0;
360 nextaddr = 0;
361
362 while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
363 lineno++;
364 len = (int)strlen(buffer);
365 if (buffer[len-1] == '\n')
366 buffer[--len] = 0;
367 if (buffer[0] != ':')
368 continue;
369 rc = ihex_readrec(&ihex, buffer);
370 if (rc < 0) {
371 avrdude_message(MSG_INFO, "%s: invalid record at line %d of \"%s\"\n",
373 return -1;
374 }
375 else if (rc != ihex.cksum) {
376 avrdude_message(MSG_INFO, "%s: ERROR: checksum mismatch at line %d of \"%s\"\n",
378 avrdude_message(MSG_INFO, "%s: checksum=0x%02x, computed checksum=0x%02x\n",
379 progname, ihex.cksum, rc);
380 return -1;
381 }
382
383 switch (ihex.rectyp) {
384 case 0: /* data record */
385 if (fileoffset != 0 && baseaddr < fileoffset) {
386 avrdude_message(MSG_INFO, "%s: ERROR: address 0x%04x out of range (below fileoffset 0x%x) at line %d of %s\n",
387 progname, baseaddr, fileoffset, lineno, infile);
388 return -1;
389 }
390 nextaddr = ihex.loadofs + baseaddr - fileoffset;
391 if (nextaddr + ihex.reclen > (unsigned)bufsize) {
392 avrdude_message(MSG_INFO, "%s: ERROR: address 0x%04x out of range at line %d of %s\n",
393 progname, nextaddr+ihex.reclen, lineno, infile);
394 return -1;
395 }
396 for (i=0; i<ihex.reclen; i++) {
397 mem->buf[nextaddr+i] = ihex.data[i];
398 mem->tags[nextaddr+i] = TAG_ALLOCATED;
399 }
400 if (nextaddr+ihex.reclen > maxaddr)
401 maxaddr = nextaddr+ihex.reclen;
402 break;
403
404 case 1: /* end of file record */
405 return maxaddr;
406 break;
407
408 case 2: /* extended segment address record */
409 baseaddr = (ihex.data[0] << 8 | ihex.data[1]) << 4;
410 break;
411
412 case 3: /* start segment address record */
413 /* we don't do anything with the start address */
414 break;
415
416 case 4: /* extended linear address record */
417 baseaddr = (ihex.data[0] << 8 | ihex.data[1]) << 16;
418 break;
419
420 case 5: /* start linear address record */
421 /* we don't do anything with the start address */
422 break;
423
424 default:
425 avrdude_message(MSG_INFO, "%s: don't know how to deal with rectype=%d "
426 "at line %d of %s\n",
427 progname, ihex.rectyp, lineno, infile);
428 return -1;
429 break;
430 }
431
432 } /* while */
433
434 if (maxaddr == 0) {
435 avrdude_message(MSG_INFO, "%s: ERROR: No valid record found in Intel Hex "
436 "file \"%s\"\n",
438
439 return -1;
440 }
441 else {
442 avrdude_message(MSG_INFO, "%s: WARNING: no end of file record found for Intel Hex "
443 "file \"%s\"\n",
445
446 return maxaddr;
447 }
448}
const char * infile
Definition config.c:55
int lineno
Definition config.c:54
static int ihex_readrec(struct ihexrec *ihex, char *rec)
Definition fileio.c:258
Definition fileio.c:54

References avrdude_message(), avrmem::buf, ihexrec::cksum, ihexrec::data, ihex_readrec(), infile, lineno, ihexrec::loadofs, MAX_LINE_LEN, MSG_INFO, progname, ihexrec::reclen, ihexrec::rectyp, TAG_ALLOCATED, and avrmem::tags.

Referenced by fileio_ihex().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ihex_readrec()

static int ihex_readrec ( struct ihexrec ihex,
char *  rec 
)
static
259{
260 int i, j;
261 char buf[8];
262 int offset, len;
263 char * e;
264 unsigned char cksum;
265 int rc;
266
267 len = (int)strlen(rec);
268 offset = 1;
269 cksum = 0;
270
271 /* reclen */
272 if (offset + 2 > len)
273 return -1;
274 for (i=0; i<2; i++)
275 buf[i] = rec[offset++];
276 buf[i] = 0;
277 ihex->reclen = (unsigned char)strtoul(buf, &e, 16);
278 if (e == buf || *e != 0)
279 return -1;
280
281 /* load offset */
282 if (offset + 4 > len)
283 return -1;
284 for (i=0; i<4; i++)
285 buf[i] = rec[offset++];
286 buf[i] = 0;
287 ihex->loadofs = strtoul(buf, &e, 16);
288 if (e == buf || *e != 0)
289 return -1;
290
291 /* record type */
292 if (offset + 2 > len)
293 return -1;
294 for (i=0; i<2; i++)
295 buf[i] = rec[offset++];
296 buf[i] = 0;
297 ihex->rectyp = (unsigned char)strtoul(buf, &e, 16);
298 if (e == buf || *e != 0)
299 return -1;
300
301 cksum = ihex->reclen + ((ihex->loadofs >> 8) & 0x0ff) +
302 (ihex->loadofs & 0x0ff) + ihex->rectyp;
303
304 /* data */
305 for (j=0; j<ihex->reclen; j++) {
306 if (offset + 2 > len)
307 return -1;
308 for (i=0; i<2; i++)
309 buf[i] = rec[offset++];
310 buf[i] = 0;
311 ihex->data[j] = (char)strtoul(buf, &e, 16);
312 if (e == buf || *e != 0)
313 return -1;
314 cksum += ihex->data[j];
315 }
316
317 /* cksum */
318 if (offset + 2 > len)
319 return -1;
320 for (i=0; i<2; i++)
321 buf[i] = rec[offset++];
322 buf[i] = 0;
323 ihex->cksum = (char)strtoul(buf, &e, 16);
324 if (e == buf || *e != 0)
325 return -1;
326
327 rc = -cksum & 0x000000ff;
328
329 return rc;
330}
unsigned char reclen
Definition fileio.c:55
unsigned char cksum
Definition fileio.c:59
unsigned char data[IHEX_MAXDATA]
Definition fileio.c:58
unsigned int loadofs
Definition fileio.c:56
unsigned char rectyp
Definition fileio.c:57
void offset(Slic3r::ExPolygon &sh, coord_t distance, const PolygonTag &)
Definition geometries.hpp:132

References ihexrec::cksum, ihexrec::data, ihexrec::loadofs, ihexrec::reclen, and ihexrec::rectyp.

Referenced by ihex2b().

+ Here is the caller graph for this function:

◆ itoa_simple()

static char * itoa_simple ( int  n,
char *  buf,
int  base 
)
static
1104{
1105 div_t q;
1106 char c, *cp, *cp2;
1107
1108 cp = buf;
1109 /*
1110 * Divide by base until the number disappeared, but ensure at least
1111 * one digit will be emitted.
1112 */
1113 do {
1114 q = div(n, base);
1115 n = q.quot;
1116 if (q.rem >= 10)
1117 c = q.rem - 10 + 'a';
1118 else
1119 c = q.rem + '0';
1120 *cp++ = c;
1121 } while (q.quot != 0);
1122
1123 /* Terminate the string. */
1124 *cp-- = '\0';
1125
1126 /* Now revert the result string. */
1127 cp2 = buf;
1128 while (cp > cp2) {
1129 c = *cp;
1130 *cp-- = *cp2;
1131 *cp2++ = c;
1132 }
1133
1134 return buf;
1135}

Referenced by fileio_num().

+ Here is the caller graph for this function:

◆ srec2b()

static int srec2b ( char *  infile,
FILE *  inf,
AVRMEM mem,
int  bufsize,
unsigned int  fileoffset 
)
static
635{
636 char buffer [ MAX_LINE_LEN ];
637 unsigned int nextaddr, maxaddr;
638 int i;
639 int lineno;
640 int len;
641 struct ihexrec srec;
642 int rc;
643 int reccount;
644 unsigned char datarec;
645
646 char * msg = 0;
647
648 lineno = 0;
649 maxaddr = 0;
650 reccount = 0;
651
652 while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
653 lineno++;
654 len = (int)strlen(buffer);
655 if (buffer[len-1] == '\n')
656 buffer[--len] = 0;
657 if (buffer[0] != 0x53)
658 continue;
659 rc = srec_readrec(&srec, buffer);
660
661 if (rc < 0) {
662 avrdude_message(MSG_INFO, "%s: ERROR: invalid record at line %d of \"%s\"\n",
664 return -1;
665 }
666 else if (rc != srec.cksum) {
667 avrdude_message(MSG_INFO, "%s: ERROR: checksum mismatch at line %d of \"%s\"\n",
669 avrdude_message(MSG_INFO, "%s: checksum=0x%02x, computed checksum=0x%02x\n",
670 progname, srec.cksum, rc);
671 return -1;
672 }
673
674 datarec=0;
675 switch (srec.rectyp) {
676 case 0x30: /* S0 - header record*/
677 /* skip */
678 break;
679
680 case 0x31: /* S1 - 16 bit address data record */
681 datarec=1;
682 msg="%s: ERROR: address 0x%04x out of range %sat line %d of %s\n";
683 break;
684
685 case 0x32: /* S2 - 24 bit address data record */
686 datarec=1;
687 msg="%s: ERROR: address 0x%06x out of range %sat line %d of %s\n";
688 break;
689
690 case 0x33: /* S3 - 32 bit address data record */
691 datarec=1;
692 msg="%s: ERROR: address 0x%08x out of range %sat line %d of %s\n";
693 break;
694
695 case 0x34: /* S4 - symbol record (LSI extension) */
696 avrdude_message(MSG_INFO, "%s: ERROR: not supported record at line %d of %s\n",
698 return -1;
699
700 case 0x35: /* S5 - count of S1,S2 and S3 records previously tx'd */
701 if (srec.loadofs != reccount){
702 avrdude_message(MSG_INFO, "%s: ERROR: count of transmitted data records mismatch "
703 "at line %d of \"%s\"\n",
705 avrdude_message(MSG_INFO, "%s: transmitted data records= %d, expected "
706 "value= %d\n",
707 progname, reccount, srec.loadofs);
708 return -1;
709 }
710 break;
711
712 case 0x37: /* S7 Record - end record for 32 bit address data */
713 case 0x38: /* S8 Record - end record for 24 bit address data */
714 case 0x39: /* S9 Record - end record for 16 bit address data */
715 return maxaddr;
716
717 default:
718 avrdude_message(MSG_INFO, "%s: ERROR: don't know how to deal with rectype S%d "
719 "at line %d of %s\n",
720 progname, srec.rectyp, lineno, infile);
721 return -1;
722 }
723
724 if (datarec == 1) {
725 nextaddr = srec.loadofs;
726 if (nextaddr < fileoffset) {
727 avrdude_message(MSG_INFO, msg, progname, nextaddr,
728 "(below fileoffset) ",
729 lineno, infile);
730 return -1;
731 }
732 nextaddr -= fileoffset;
733 if (nextaddr + srec.reclen > (unsigned)bufsize) {
734 avrdude_message(MSG_INFO, msg, progname, nextaddr+srec.reclen, "",
735 lineno, infile);
736 return -1;
737 }
738 for (i=0; i<srec.reclen; i++) {
739 mem->buf[nextaddr+i] = srec.data[i];
740 mem->tags[nextaddr+i] = TAG_ALLOCATED;
741 }
742 if (nextaddr+srec.reclen > maxaddr)
743 maxaddr = nextaddr+srec.reclen;
744 reccount++;
745 }
746
747 }
748
749 avrdude_message(MSG_INFO, "%s: WARNING: no end of file record found for Motorola S-Records "
750 "file \"%s\"\n",
752
753 return maxaddr;
754}
static int srec_readrec(struct ihexrec *srec, char *rec)
Definition fileio.c:557

References avrdude_message(), avrmem::buf, ihexrec::cksum, ihexrec::data, infile, lineno, ihexrec::loadofs, MAX_LINE_LEN, MSG_INFO, progname, ihexrec::reclen, ihexrec::rectyp, srec_readrec(), TAG_ALLOCATED, and avrmem::tags.

Referenced by fileio_srec().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ srec_readrec()

static int srec_readrec ( struct ihexrec srec,
char *  rec 
)
static
558{
559 int i, j;
560 char buf[8];
561 int offset, len, addr_width;
562 char * e;
563 unsigned char cksum;
564 int rc;
565
566 len = (int)strlen(rec);
567 offset = 1;
568 cksum = 0;
569 addr_width = 2;
570
571 /* record type */
572 if (offset + 1 > len)
573 return -1;
574 srec->rectyp = rec[offset++];
575 if (srec->rectyp == 0x32 || srec->rectyp == 0x38)
576 addr_width = 3; /* S2,S8-record */
577 else if (srec->rectyp == 0x33 || srec->rectyp == 0x37)
578 addr_width = 4; /* S3,S7-record */
579
580 /* reclen */
581 if (offset + 2 > len)
582 return -1;
583 for (i=0; i<2; i++)
584 buf[i] = rec[offset++];
585 buf[i] = 0;
586 srec->reclen = (char)strtoul(buf, &e, 16);
587 cksum += srec->reclen;
588 srec->reclen -= (addr_width+1);
589 if (e == buf || *e != 0)
590 return -1;
591
592 /* load offset */
593 if (offset + addr_width > len)
594 return -1;
595 for (i=0; i<addr_width*2; i++)
596 buf[i] = rec[offset++];
597 buf[i] = 0;
598 srec->loadofs = strtoul(buf, &e, 16);
599 if (e == buf || *e != 0)
600 return -1;
601
602 for (i=addr_width; i>0; i--)
603 cksum += (srec->loadofs >> (i - 1) * 8) & 0xff;
604
605 /* data */
606 for (j=0; j<srec->reclen; j++) {
607 if (offset+2 > len)
608 return -1;
609 for (i=0; i<2; i++)
610 buf[i] = rec[offset++];
611 buf[i] = 0;
612 srec->data[j] = (char)strtoul(buf, &e, 16);
613 if (e == buf || *e != 0)
614 return -1;
615 cksum += srec->data[j];
616 }
617
618 /* cksum */
619 if (offset + 2 > len)
620 return -1;
621 for (i=0; i<2; i++)
622 buf[i] = rec[offset++];
623 buf[i] = 0;
624 srec->cksum = (char)strtoul(buf, &e, 16);
625 if (e == buf || *e != 0)
626 return -1;
627
628 rc = 0xff - cksum;
629 return rc;
630}

References ihexrec::cksum, ihexrec::data, ihexrec::loadofs, ihexrec::reclen, and ihexrec::rectyp.

Referenced by srec2b().

+ Here is the caller graph for this function: