mirror of
https://github.com/avrdudes/avrdude.git
synced 2026-09-29 12:28:41 +03:00
Provide urboot: autogenerated files
This commit is contained in:
@@ -285,6 +285,9 @@ set(SOURCES
|
||||
updi_readwrite.h
|
||||
updi_state.c
|
||||
updi_state.h
|
||||
urbootlist.c
|
||||
urbootlist.h
|
||||
urbootautogen.c
|
||||
urclock.c
|
||||
urclock.h
|
||||
urclock_hash.h
|
||||
|
||||
@@ -214,6 +214,9 @@ libavrdude_la_SOURCES = \
|
||||
updi_nvm_v4.h \
|
||||
updi_nvm_v5.c \
|
||||
updi_nvm_v5.h \
|
||||
urbootlist.c \
|
||||
urbootlist.h \
|
||||
urbootautogen.c \
|
||||
urclock.c \
|
||||
urclock.h \
|
||||
urclock_hash.h \
|
||||
|
||||
19
src/fileio.c
19
src/fileio.c
@@ -1627,7 +1627,15 @@ int fileio_fmt_autodetect_fp(FILE *f) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Read-only files that avrdude generates itself
|
||||
int is_generated_fname(const char *fname) {
|
||||
return str_starts(fname, "urboot:");
|
||||
}
|
||||
|
||||
int fileio_fmt_autodetect(const char *fname) {
|
||||
if(is_generated_fname(fname))
|
||||
return FMT_IHEX;
|
||||
|
||||
FILE *f = fileio_fopenr(fname);
|
||||
|
||||
if(f == NULL) {
|
||||
@@ -1642,12 +1650,15 @@ int fileio_fmt_autodetect(const char *fname) {
|
||||
return format;
|
||||
}
|
||||
|
||||
int fileio_mem(int op, const char *filename, FILEFMT format, const AVRPART *p, const AVRMEM *mem, int size) {
|
||||
int fileio_mem(int op, const char *filename, FILEFMT format, const AVRPART *p, const AVRMEM *mem, int msize) {
|
||||
|
||||
if(size < 0 || op == FIO_READ || op == FIO_READ_FOR_VERIFY)
|
||||
size = mem->size;
|
||||
if(msize < 0 || op == FIO_READ || op == FIO_READ_FOR_VERIFY)
|
||||
msize = mem->size;
|
||||
|
||||
const Segment seg = { 0, size };
|
||||
if(is_generated_fname(filename) && (op == FIO_READ || op == FIO_READ_FOR_VERIFY))
|
||||
return urbootautogen(p, mem, filename);
|
||||
|
||||
const Segment seg = { 0, msize };
|
||||
return fileio_segments(op, filename, format, p, mem, 1, &seg);
|
||||
}
|
||||
|
||||
|
||||
@@ -1264,6 +1264,7 @@ extern "C" {
|
||||
AVRMEM *fileio_any_memory(const char *name);
|
||||
unsigned fileio_mem_offset(const AVRPART *p, const AVRMEM *mem);
|
||||
FILE *fileio_fopenr(const char *fname);
|
||||
int is_generated_fname(const char *filename);
|
||||
int fileio_fmt_autodetect_fp(FILE *f);
|
||||
int fileio_fmt_autodetect(const char *fname);
|
||||
int fileio_mem(int oprwv, const char *filename, FILEFMT format, const AVRPART *p, const AVRMEM *mem, int size);
|
||||
@@ -1614,6 +1615,24 @@ typedef struct {
|
||||
|
||||
extern const AVR_opcode avr_opcodes[164];
|
||||
|
||||
// Urboot bootloader features
|
||||
#define URFEATURE_PR 1 // Vector bootloader protecting the reset vector
|
||||
#define URFEATURE_EE 2 // Bootloader supports EEPROM read/write
|
||||
#define URFEATURE_CE 4 // Bootloader provides a chip erase command
|
||||
#define URFEATURE_HW 8 // Hardware supported bootloader
|
||||
#define URFEATURE_U4 16 // Update flash as opposed to purely writing
|
||||
|
||||
typedef struct {
|
||||
int size, usage, update_level;
|
||||
int features; // Above 5 bits of features the bootloader has
|
||||
uint16_t *tofree; // This is the allocated space that needs freeing
|
||||
uint16_t *locs; // Index list in code where parameters can be set
|
||||
uint16_t *code; // size/2 - 3 words of 16-bit bootloader opcodes
|
||||
uint16_t *table; // 3-word-table at end of bootloader
|
||||
char urversion[32], type[64]; // Version string and bootloader type string
|
||||
int match_req; // Bootloader matches the requested features
|
||||
} Urboot_template;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -1703,6 +1722,7 @@ extern "C" {
|
||||
const char *str_ccaddress(int addr, int size);
|
||||
char *str_quote_bash(const char *s);
|
||||
const char *str_ccsharg(const char *str);
|
||||
char *str_vectorname(const Avrintel *up, int vn);
|
||||
|
||||
int led_set(const PROGRAMMER *pgm, int led);
|
||||
int led_clr(const PROGRAMMER *pgm, int led);
|
||||
@@ -1756,6 +1776,11 @@ extern "C" {
|
||||
void uint32tobuf(unsigned char *buf, uint32_t opcode32);
|
||||
void uint16tobuf(unsigned char *buf, uint16_t opcode16);
|
||||
|
||||
int urbootautogen(const AVRPART *part, const AVRMEM *mem, const char *filename);
|
||||
int urbootexists(const char *mcu, const char *io, const char *blt, int req_feats);
|
||||
Urboot_template **urboottemplate(const Avrintel *up, const char *mcu, const char *io, const char *blt,
|
||||
int req_feat, int req_ulevel, int showall, int *np);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1000,6 +1000,8 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m
|
||||
Return("unknown format%s suffix of file name", fmtstr);
|
||||
str[arglen -= 2] = 0;
|
||||
}
|
||||
if(format == FMT_AUTO && is_generated_fname(str))
|
||||
format = FMT_IHEX;
|
||||
if(format == FMT_AUTO) {
|
||||
f = fileio_fopenr(str);
|
||||
if(f == NULL)
|
||||
@@ -1567,3 +1569,21 @@ const char *str_ccsharg(const char *str) {
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
// Return malloc'd ISR vector name without _ (given the vector number)
|
||||
char *str_vectorname(const Avrintel *up, int vn) {
|
||||
if(!up->isrtable || vn < -1 || vn > up->ninterrupts)
|
||||
return mmt_strdup("unknown");
|
||||
|
||||
char *ret = mmt_strdup((unsigned) vn >= up->ninterrupts? "ADDITIONAL_VECTOR": up->isrtable[vn]);
|
||||
|
||||
// Remove all _ in vectorstr
|
||||
char *p = str_lc(ret), *q = p;
|
||||
do {
|
||||
while(*p == '_')
|
||||
p++;
|
||||
*q++ = *p;
|
||||
} while(*p++);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
19
src/term.c
19
src/term.c
@@ -647,7 +647,8 @@ typedef enum {
|
||||
|
||||
static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) {
|
||||
if(argc < 3 || (argc > 1 && str_eq(argv[1], "-?"))) {
|
||||
msg_error("Syntax: write <mem> <addr> <data>[,] {<data>[,]}\n"
|
||||
msg_error(
|
||||
"Syntax: write <mem> <addr> <data>[,] {<data>[,]}\n"
|
||||
" write <mem> <addr> <len> <data>[,] {<data>[,]} ... # Fill, see below\n"
|
||||
" write <mem> <data> # Any <data> incl file if memory has only 1 byte\n"
|
||||
" write <mem> <file> # Must be file if memory has more than 1 byte\n"
|
||||
@@ -662,8 +663,13 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch
|
||||
"<data> can be binary, octal, decimal or hexadecimal integers, floating point\n"
|
||||
"numbers or C-style strings and characters. If nothing matches, <data> will be\n"
|
||||
"interpreted as name of a file containing data. In absence of a :<f> format\n"
|
||||
"suffix, the terminal will try to auto-detect the file format.\n"
|
||||
"suffix, the terminal will try to auto-detect the file format.\n\n"
|
||||
"A file name that starts with urboot: autogenerates a bootloader file, try\n"
|
||||
"write flash urboot:help\n"
|
||||
"\n"
|
||||
);
|
||||
msg_error(
|
||||
verbose <= 0? "For more detail increase verbosity and rerun write -?\n":
|
||||
"For integers, an optional case-insensitive suffix specifies the data size: HH\n"
|
||||
"8 bit, H/S 16 bit, L 32 bit, LL 64 bit. Suffix D indicates a 64-bit double, F\n"
|
||||
"a 32-bit float, whilst a floating point number without suffix defaults to\n"
|
||||
@@ -689,7 +695,8 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch
|
||||
"smallest unsigned representation: For example, 255 is stored as one byte as\n"
|
||||
"255U would fit in one byte, though as a signed number it would not fit into a\n"
|
||||
"one-byte interval [-128, 127]. The number -1 is stored in one byte whilst -1U\n"
|
||||
"needs eight bytes as it is the same as 0xFFFFffffFFFFffffU.\n");
|
||||
"needs eight bytes as it is the same as 0xFFFFffffFFFFffffU.\n"
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -793,7 +800,8 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch
|
||||
str_freedata(sd);
|
||||
sd = str_todata(argv[i], STR_ANY, p, mem->desc);
|
||||
if(!sd->type || sd->errstr) {
|
||||
pmsg_error("(write) data %s: %s\n", argv[i], sd->errstr? sd->errstr: "str_todata");
|
||||
if(!is_generated_fname(argv[i]))
|
||||
pmsg_error("(write) data %s: %s\n", argv[i], sd->errstr? sd->errstr: "str_todata");
|
||||
mmt_free(buf);
|
||||
mmt_free(tags);
|
||||
str_freedata(sd);
|
||||
@@ -872,7 +880,8 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch
|
||||
msg_notice2("; remaining space filled with %s", argv[argc - 2]);
|
||||
msg_notice2("\n");
|
||||
|
||||
report_progress(0, 1, avr_has_paged_access(pgm, p, mem)? "Caching": "Writing");
|
||||
if(0 < len + bytes_grown)
|
||||
report_progress(0, 1, avr_has_paged_access(pgm, p, mem)? "Caching": "Writing");
|
||||
for(i = 0; i < len + bytes_grown; i++) {
|
||||
report_progress(i, len + bytes_grown, NULL);
|
||||
if(!tags[i])
|
||||
|
||||
15
src/update.c
15
src/update.c
@@ -77,7 +77,7 @@ UPDATE *parse_op(const char *s) {
|
||||
// Filename: last char is format if the penultimate char is a colon
|
||||
size_t len = strlen(fn);
|
||||
|
||||
if(len > 2 && fn[len - 2] == ':') { // Assume format specified
|
||||
if(!is_generated_fname(fn) && len > 2 && fn[len - 2] == ':') { // Format specifier
|
||||
upd->format = fileio_format_with_errmsg(fn[len - 1], "");
|
||||
if(upd->format == FMT_ERROR) {
|
||||
mmt_free(upd->memstr);
|
||||
@@ -253,6 +253,9 @@ int update_is_readable(const char *fn) {
|
||||
if(str_eq(fn, "-"))
|
||||
return 1;
|
||||
|
||||
if(is_generated_fname(fn)) // Will be autogenerated
|
||||
return 1;
|
||||
|
||||
// File exists, is readable by the process and an OK file type?
|
||||
return access(fn, R_OK) == 0 && update_is_okfile(fn);
|
||||
}
|
||||
@@ -408,7 +411,7 @@ int update_dryrun(const AVRPART *p, UPDATE *upd) {
|
||||
errno = 0;
|
||||
if(!known && !update_is_readable(upd->filename)) {
|
||||
ioerror("readable", upd);
|
||||
ret = LIBAVRDUDE_SOFTFAIL; // Even so it might still be there later on
|
||||
ret = LIBAVRDUDE_SOFTFAIL; // Even so it might still be there later on
|
||||
known = 1; // Pretend we know it, so no auto detect needed
|
||||
}
|
||||
}
|
||||
@@ -611,6 +614,10 @@ static int update_all_from_file(const UPDATE *upd, const PROGRAMMER *pgm, const
|
||||
int op = upd->op == DEVICE_WRITE? FIO_READ: FIO_READ_FOR_VERIFY;
|
||||
int allsize = fileio_mem(op, upd->filename, upd->format, p, all, -1);
|
||||
|
||||
if(is_generated_fname(upd->filename)) // Autogeneration prints its own errors
|
||||
if(allsize <= 0)
|
||||
return allsize;
|
||||
|
||||
if(allsize < 0) {
|
||||
pmsg_error("reading from file %s failed\n", str_infilename(upd->filename));
|
||||
return -1;
|
||||
@@ -771,6 +778,8 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat
|
||||
// Write the selected device memory/ies using data from a file
|
||||
if((allsize = update_all_from_file(upd, pgm, p, mem, mem_desc, &fs)) < 0)
|
||||
goto error;
|
||||
if(allsize == 0)
|
||||
break;
|
||||
if(umemlist) {
|
||||
for(int i = 0; i < ns; i++) {
|
||||
m = umemlist[i];
|
||||
@@ -814,6 +823,8 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat
|
||||
// Verify that the in memory file is the same as what is on the chip
|
||||
if((allsize = update_all_from_file(upd, pgm, p, mem, mem_desc, &fs)) < 0)
|
||||
goto error;
|
||||
if(allsize == 0)
|
||||
break;
|
||||
if(umemlist) {
|
||||
for(int i = 0; i < ns; i++) {
|
||||
m = umemlist[i];
|
||||
|
||||
1526
src/urbootautogen.c
Normal file
1526
src/urbootautogen.c
Normal file
File diff suppressed because it is too large
Load Diff
260589
src/urbootlist.c
Normal file
260589
src/urbootlist.c
Normal file
File diff suppressed because it is too large
Load Diff
35
src/urbootlist.h
Normal file
35
src/urbootlist.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Do not edit: automatically generated by the urboot project using
|
||||
* https://github.com/stefanrueger/urboot/blob/main/src/mkurbootlist.pl
|
||||
*
|
||||
* urbootlist.h
|
||||
*
|
||||
* Definitions for list of template urboot bootloaders
|
||||
*
|
||||
* Published under GNU General Public License, version 3 (GPL-3.0)
|
||||
* Meta-author Stefan Rueger <stefan.rueger@urclocks.com>
|
||||
*
|
||||
* v 1.2
|
||||
* 22.04.2025
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef urbootlist_h
|
||||
#define urbootlist_h
|
||||
|
||||
// Code locations (in words) for urboot parametrisation
|
||||
enum {
|
||||
UL_LDI_BRRLO, UL_LDI_BRRHI, UL_LDI_BRRSHARED, UL_LDI_LINBRRLO, UL_LDI_LINLBT, UL_SWIO_EXTRA12,
|
||||
UL_LDI_BVALUE, UL_LDI_WDTO, UL_LDI_STK_INSYNC, UL_LDI_STK_OK, UL_RJMP_APPLICATION,
|
||||
UL_JMP_APPLICATION, UL_SBI_DDRTX, UL_CBI_TX, UL_SBI_TX, UL_SBIC_RX_START, UL_SBIC_RX,
|
||||
UL_LDI_STARTHHZ, UL_LDI_STARTHI, UL_CPI_STARTHI, UL_CPI_STARTLO,
|
||||
UL_CODELOCS_N
|
||||
};
|
||||
|
||||
#define UL_MCU_N 166
|
||||
#define UL_IOTYPE_N 31
|
||||
#define UL_BLTYPE_N 3
|
||||
#define UL_CONFIG_N 14
|
||||
#define UL_BLN(mcu, io, blt, cfg) ((((mcu)*UL_IOTYPE_N + (io))*UL_BLTYPE_N + (blt))*UL_CONFIG_N + (cfg))
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user