Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide Urclock programmer #1171

Merged
merged 31 commits into from
Nov 22, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e6c26d8
Provide urclock programmer
stefanrueger Nov 6, 2022
21d93ec
Update urclock programmer
stefanrueger Nov 7, 2022
715db4c
Make -A default for urclock programmer
stefanrueger Nov 7, 2022
cf3c81f
Update urclock's -x parameters
stefanrueger Nov 7, 2022
6a6d333
Update urclock documentation
stefanrueger Nov 8, 2022
20b86fb
Warn in uclock when bootloader cannot read/write memories
stefanrueger Nov 8, 2022
ea65918
Omit verify after write failure in term.c
stefanrueger Nov 9, 2022
c7ba53b
Harden urclock against terminal time outs and vector overwrites
stefanrueger Nov 9, 2022
84a3e2c
Fix avr.c comment
stefanrueger Nov 9, 2022
d5d0b94
Harden vector bootloaders more against reset overwrites
stefanrueger Nov 9, 2022
afa408e
Make urclock.c iron out a bug in some bootloaders
stefanrueger Nov 9, 2022
321bddb
Rename urclock's option forcetrim to restore
stefanrueger Nov 10, 2022
c67bfe3
Show input file staistics before patching in update.c
stefanrueger Nov 10, 2022
22bd977
Indent erasing chip message in main
stefanrueger Nov 10, 2022
6e3a99b
Add write statistics for patched flash input files at notice2 level
stefanrueger Nov 11, 2022
b178dee
Handle n_page_erase in urclock for parts t441, t841 and t1634
stefanrueger Nov 11, 2022
e2b69de
Remove MacOS compiler warnings for urclock.c
stefanrueger Nov 12, 2022
ff9c8bb
Silence min()/max() compiler warnings, fix urclock.c typo etc
stefanrueger Nov 12, 2022
afc2f7c
Hint at option -xdelay=... for urclock programmer not responding mess…
stefanrueger Nov 12, 2022
82b9491
Harden urclock against bootloader bricking
stefanrueger Nov 16, 2022
d901e0a
Update urbootPutVersion() to reflect urboot v7.7 changes
stefanrueger Nov 16, 2022
2abb666
Prepare urclock for autobaud synchronisation
stefanrueger Nov 16, 2022
a3eeedd
Silence some compiler warnings
stefanrueger Nov 16, 2022
d65a9a3
Adapt -c urclock to new reset vector protection in urboot v7.7
stefanrueger Nov 19, 2022
ee25a62
Emulate chip erase in terminal when pgm->chip_erase() soft fails
stefanrueger Nov 19, 2022
f276d32
Handle verification errors in read only memory areas gracefully
stefanrueger Nov 20, 2022
53de22c
Update avrintel.c for LGT8F(8|16|32)8P parts
stefanrueger Nov 20, 2022
c0e4dd4
Use file basename in -c urclock metadata under WIN32
stefanrueger Nov 20, 2022
7f4474f
Delete previous metadata when writing new file to flash in urclock
stefanrueger Nov 20, 2022
2e39891
Hash known bootloaders for urclock; they don't need -xbootsize=....
stefanrueger Nov 22, 2022
f9aea24
Reduce drain timeout value for Windows in urclock.c
stefanrueger Nov 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ add_library(libavrdude
updi_readwrite.h
updi_state.c
updi_state.h
urclock.c
urclock.h
urclock_private.h
usbasp.c
usbasp.h
usbdevs.h
Expand Down
3 changes: 3 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ libavrdude_a_SOURCES = \
updi_readwrite.h \
updi_nvm.c \
updi_nvm.h \
urclock.c \
urclock.h \
urclock_private.h \
usbdevs.h \
usb_hidapi.c \
usb_libusb.c \
Expand Down
120 changes: 114 additions & 6 deletions src/avrdude.1
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,17 @@ programming mode. The programmer type is ``wiring''. Note that the -D option
will likely be required in this case, because the bootloader will rewrite the
program memory, but no true chip erase can be performed.
.Pp
The Arduino (which is very similar to the STK500 1.x) is supported via
its own programmer type specification ``arduino''. This programmer works for
the Arduino Uno Rev3 or any AVR that runs the Optiboot bootloader.
Serial bootloaders that run a skeleton of the STK500 1.x protocol are
supported via their own programmer type ``arduino''. This programmer works
for the Arduino Uno Rev3 or any AVR that runs the Optiboot bootloader.
.Pp
Urprotocol is a leaner version of the STK500 1.x protocol that is designed
to be backwards compatible with STK500 v1.x, and allows bootloaders to be
much smaller, eg, as implemented in the urboot project
https://github.com/stefanrueger/urboot. The programmer type ``urclock''
caters for these urboot programmers. Owing to its backward compatibility,
any bootloader that can be served by the arduino programmer can normally
also be served by the urclock programmer.
.Pp
The BusPirate is a versatile tool that can also be used as an AVR programmer.
A single BusPirate can be connected to up to 3 independent AVRs. See
Expand Down Expand Up @@ -397,8 +405,8 @@ programming requires the memory be erased to 0xFF beforehand.
.Fl A
should be used when the programmer hardware, or bootloader
software for that matter, does not carry out chip erase and
instead handles the memory erase on a page level. The popular
Arduino bootloader exhibits this behaviour; for this reason
instead handles the memory erase on a page level. Popular
Arduino bootloaders exhibit this behaviour; for this reason
.Fl A
is engaged by default when specifying
. Fl c
Expand Down Expand Up @@ -432,7 +440,7 @@ contents would exclusively cause bits to be programmed from the value
.Ql 1
to
.Ql 0 .
Note that in order to reprogram EERPOM cells, no explicit prior chip
Note that in order to reprogram EEPROM cells, no explicit prior chip
erase is required since the MCU provides an auto-erase cycle in that
case before programming the cell.
.It Xo Fl E Ar exitspec Ns
Expand Down Expand Up @@ -1141,6 +1149,106 @@ programmer creates errors during initial sequence.
Specify how many connection retry attemps to perform before exiting.
Defaults to 10 if not specified.
.El
.It Ar Urclock
.Bl -tag -offset indent -width indent
.It Ar showall
Show all info for the connected part, then exit. The -xshow... options
below can be used to assemble a bespoke response consisting of a subset
(or only one item) of all available relevant information about the
connected part and bootloader.
.It Ar showid
Show a unique Urclock ID stored in either flash or EEPROM of the MCU, then exit.
.It Ar id=<E|F>.<addr>.<len>
Historically, the Urclock ID was a six-byte unique little-endian number
stored in Urclock boards at EEPROM address 257. The location of this
number can be set by the -xid=<E|F>.<addr>.<len> extended parameter. E
stands for EEPROM and F stands for flash. A negative address addr counts
from the end of EEPROM and flash, respectively. The length len of the
Urclock ID can be between 1 and 8 bytes.
.It Ar showdate
Show the last-modified date of the input file for the flash application,
then exit. If the input file was stdin, the date will be that of the
programming.
.It Ar showfilename
Show the input filename (or title) of the last flash writing session, then exit.
.It Ar title=<string>
When set, <string> will be used in lieu of the input filename. The maximum
string length for the title/filename field is 254 bytes including
terminating nul.
.It Ar showapp
Show the size of the programmed application, then exit.
.It Ar showstore
Show the size of the unused flash between the application and metadata, then exit.
.It Ar showmeta
Show the size of the metadata just below the bootloader, then exit.
.It Ar showboot
Show the size of the bootloader, then exit.
.It Ar showversion
Show bootloader version and capabilities, then exit.
.It Ar showvbl
Show the vector number and name of the interrupt table vector used by the
bootloader for starting the application, then exit. For hardware-supported
bootloaders this will be vector 0 (Reset), and for vector bootloaders this
will be any other vector number of the interrupt vector table or the slot
just behind the vector table with the name VBL_ADDITIONAL_VECTOR.
.It Ar showpart
Show the part for which the bootloader was compiled, then exit.
.It Ar bootsize=<size>
Manual override for bootloader size. Urboot bootloaders put the number of used
bootloader pages into a table at the top of flash, so the urclock programmer can
look up the bootloader size itself. In backward-compatibility mode, when programming
via other bootloaders, this option can be used to tell the programmer the
size, and therefore the location, of the bootloader.
.It Ar vectornum=<arg>
Manual override for vector number. Urboot bootloaders put the vector
number used by a vector bootloader into a table at the top of flash, so
this option is normally not needed for urboot bootloaders. However, it is
useful in backward-compatibility mode (or when the urboot bootloader does
not offer flash read). Specifying a vector number in these circumstances
implies a vector bootloader whilst the default assumption would be a
hardware-supported bootloader.
.It Ar eepromrw
Manual override for asserting EEPROM read/write capability. Not normally
needed for urboot bootloaders, but useful for in backward-compatibility
mode if the bootloader offers EEPROM read/write.
.It Ar emulate_ce
If an urboot bootloader does not offer a chip erase command it will tell
the urclock programmer so during handshake. In this case the urclock
programmer emulates a chip erase, if warranted by user command line
options, by filling the remainder of unused flash below the bootloader
with 0xff. If this option is specified, the urclock programmer will assume
that the bootloader cannot erase the chip itself. The option is useful
for backwards-compatible bootloaders that do not implement chip erase.
.It Ar forcetrim
Upload unchanged flash input files and trim below the bootloader if
needed. This is most useful when one has a backup of the full flash and
wants to play that back onto the device. No metadata are written in this
case and no vector patching happens either if it is a vector bootloader.
However, for vector bootloaders, even under the option -xforcetrim an
input file will not be uploaded for which the reset vector does not point
to the vector bootloader. This is to avoid writing an input file to the
device that would render the vector bootloader not functional as it would
not be reached after reset.
.It Ar initstore
On writing to flash fill the store space between the flash application and
the metadata section with 0xff.
.It Ar nofilename
On writing to flash do not store the application input filename (nor a title).
.It Ar nodate
On writing to flash do not store the application input filename (nor a
title) and no date either.
.It Ar nometadata
On writing to flash do not store any metadata. The full flash below the
bootloader is available for the application. In particular, no data store
frame is programmed.
.It Ar delay=<n>
Add a <n> ms delay after reset. This can be useful if a board takes a
particularly long time to exit from external reset. <n> can be negative,
in which case the default 80 ms delay after issuing reset will be
shortened accordingly.
.It Ar help
Show this help menu and exit
.El
.It Ar buspirate
.Bl -tag -offset indent -width indent
.It Ar reset={cs,aux,aux2}
Expand Down
13 changes: 13 additions & 0 deletions src/avrdude.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,19 @@ programmer
connection_type = serial;
;

#------------------------------------------------------------
# urclock
#------------------------------------------------------------

# See https://github.com/stefanrueger/urboot
programmer
id = "urclock";
desc = "Urclock programmer for urboot bootloaders (arduino compatible)";
Copy link
Collaborator

@mcuee mcuee Nov 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not always compatible with Arduino, right? -->
Edit: probably it is compatible with existing -c arduino bootloaders.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

type = "urclock";
prog_modes = PM_SPM;
connection_type = serial;
;

#------------------------------------------------------------
# xbee
#------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions src/avrintel.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
* Atmel AVR8L, AVR8, XMEGA and AVR8X family description of interrupts and more
*
* published under GNU General Public License, version 3 (GPL-3.0)
* meta-author: Stefan Rueger <stefan.rueger@urclocks.com>
* meta-author Stefan Rueger <stefan.rueger@urclocks.com>
*
* v 1.1
* 30.08.2022
* 04.11.2022
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering if this is good to change to 04-Nov-2022 as it is ambiguous and may get interpreted wrongly by US based people

*
*/

Expand Down
4 changes: 2 additions & 2 deletions src/avrintel.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* meta-author Stefan Rueger <stefan.rueger@urclocks.com>
*
* v 1.1
* 30.08.2022
* 04.11.2022
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering if this is good to change to 04-Nov-2022 as it is ambiguous and may get interpreted wrongly by US based people

*
*/

Expand Down Expand Up @@ -770,7 +770,7 @@ typedef struct { // Value of -1 typically means unknown
#define vts_avr128da64 64
#define vts_avr128db64 65

// Suggested vector bootloader interrupt number (first unused vector or, failing that, slot just above vector table)
// Suggested vector bootloader interrupt: first unused vector or slot just above vector table
#define vbu_attiny4 10
#define vbu_attiny5 11
#define vbu_attiny9 10
Expand Down
8 changes: 4 additions & 4 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ char *cfg_escape(const char *s) {
char buf[50*1024], *d = buf;

*d++ = '"';
for(; *s && d-buf < sizeof buf-7; s++) {
for(; *s && d-buf < (long) sizeof buf-7; s++) {
switch(*s) {
case '\n':
*d++ = '\\'; *d++ = 'n';
Expand Down Expand Up @@ -855,7 +855,7 @@ void cfg_update_mcuid(AVRPART *part) {
return;

// Find an entry that shares the same name, overwrite mcuid with known, existing mcuid
for(int i=0; i < sizeof uP_table/sizeof *uP_table; i++) {
for(size_t i=0; i < sizeof uP_table/sizeof *uP_table; i++) {
if(strcasecmp(part->desc, uP_table[i].name) == 0) {
if(part->mcuid != (int) uP_table[i].mcuid) {
if(part->mcuid >= 0 && verbose >= MSG_DEBUG)
Expand All @@ -867,7 +867,7 @@ void cfg_update_mcuid(AVRPART *part) {
}

// None have the same name: an entry with part->mcuid might be an error
for(int i=0; i < sizeof uP_table/sizeof *uP_table; i++)
for(size_t i=0; i < sizeof uP_table/sizeof *uP_table; i++)
if(part->mcuid == (int) uP_table[i].mcuid) {
// Complain unless it can be considered a variant, eg, ATmega32L and ATmega32
AVRMEM *flash = avr_locate_mem(part, "flash");
Expand All @@ -876,7 +876,7 @@ void cfg_update_mcuid(AVRPART *part) {
if(strncasecmp(part->desc, uP_table[i].name, l1 < l2? l1: l2) ||
flash->size != uP_table[i].flashsize ||
flash->page_size != uP_table[i].pagesize ||
part->n_interrupts != uP_table[i].ninterrupts)
part->n_interrupts != (int8_t) uP_table[i].ninterrupts)
yywarning("mcuid %d is reserved for %s, use a free number >= %d",
part->mcuid, uP_table[i].name, sizeof uP_table/sizeof *uP_table);
}
Expand Down
2 changes: 2 additions & 0 deletions src/libavrdude.h
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@ const char * pinmask_to_str(const pinmask_t * const pinmask);
The target file will be selected at configure time. */

extern long serial_recv_timeout; /* ms */
extern long serial_drain_timeout; /* ms */

union filedescriptor
{
Expand Down Expand Up @@ -798,6 +799,7 @@ typedef struct programmer_t {
int (*parseextparams) (const struct programmer_t *pgm, const LISTID xparams);
void (*setup) (struct programmer_t *pgm);
void (*teardown) (struct programmer_t *pgm);
int (*flash_readhook) (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *flm, const char *fname, int size);
// Cached r/w API for terminal reads/writes
int (*write_byte_cached)(const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
unsigned long addr, unsigned char value);
Expand Down
5 changes: 3 additions & 2 deletions src/pgm.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,12 @@ PROGRAMMER *pgm_new(void) {
pgm->err_led = pgm_default_led;
pgm->pgm_led = pgm_default_led;
pgm->vfy_led = pgm_default_led;
pgm->read_byte_cached = avr_read_byte_cached;
pgm->read_byte_cached = avr_read_byte_cached;
pgm->write_byte_cached = avr_write_byte_cached;
pgm->chip_erase_cached = avr_chip_erase_cached;
pgm->page_erase_cached = avr_page_erase_cached;
pgm->flush_cache = avr_flush_cache;
pgm->reset_cache = avr_reset_cache;
pgm->reset_cache = avr_reset_cache;

/*
* optional functions - these are checked to make sure they are
Expand Down Expand Up @@ -154,6 +154,7 @@ PROGRAMMER *pgm_new(void) {
pgm->parseextparams = NULL;
pgm->setup = NULL;
pgm->teardown = NULL;
pgm->flash_readhook = NULL;

// For allocating "global" memory by the programmer
pgm->cookie = NULL;
Expand Down
4 changes: 2 additions & 2 deletions src/pgm_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include "stk500generic.h"
#include "stk500v2.h"
#include "teensy.h"
#include "urclock.h"
#include "usbasp.h"
#include "usbtiny.h"
#include "wiring.h"
Expand Down Expand Up @@ -102,6 +103,7 @@ const PROGRAMMER_TYPE programmers_types[] = { // Name(s) the programmers call th
{"stk600hvsp", stk600hvsp_initpgm, stk600hvsp_desc}, // "STK600HVSP"
{"stk600pp", stk600pp_initpgm, stk600pp_desc}, // "STK600PP"
{"teensy", teensy_initpgm, teensy_desc}, // "teensy"
{"urclock", urclock_initpgm, urclock_desc}, // "Urclock"
{"usbasp", usbasp_initpgm, usbasp_desc}, // "usbasp"
{"usbtiny", usbtiny_initpgm, usbtiny_desc}, // "USBtiny" or "usbtiny"
{"wiring", wiring_initpgm, wiring_desc}, // "Wiring"
Expand Down Expand Up @@ -171,5 +173,3 @@ void walk_programmer_types(walk_programmer_types_cb cb, void *cookie)
cb(p->id, p->desc, cookie);
}
}


3 changes: 2 additions & 1 deletion src/ser_posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include "libavrdude.h"

long serial_recv_timeout = 5000; /* ms */
long serial_drain_timeout = 250; /* ms */

struct baud_mapping {
long baud;
Expand Down Expand Up @@ -549,7 +550,7 @@ static int ser_drain(const union filedescriptor *fd, int display) {
unsigned char buf;

timeout.tv_sec = 0;
timeout.tv_usec = 250000;
timeout.tv_usec = serial_drain_timeout*1000L;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is not related to this PR, or is it causing problem for this PR?


if (display) {
msg_info("drain>");
Expand Down
5 changes: 3 additions & 2 deletions src/ser_win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "libavrdude.h"

long serial_recv_timeout = 5000; /* ms */
long serial_drain_timeout = 250; /* ms */

#define W32SERBUFSIZE 1024

Expand Down Expand Up @@ -635,7 +636,7 @@ static int net_drain(const union filedescriptor *fd, int display) {
}

timeout.tv_sec = 0;
timeout.tv_usec = 250000;
timeout.tv_usec = serial_drain_timeout*1000L;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is not related to this PR, or is it causing problem for this PR?


while (1) {
FD_ZERO(&rfds);
Expand Down Expand Up @@ -712,7 +713,7 @@ static int ser_drain(const union filedescriptor *fd, int display) {
return -1;
}

serial_w32SetTimeOut(hComPort,250);
serial_w32SetTimeOut(hComPort, serial_drain_timeout);

if (display) {
msg_info("drain>");
Expand Down
11 changes: 11 additions & 0 deletions src/update.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,17 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, UPDATE *upd, enum updateflags
pmsg_error("read from file %s failed\n", update_inname(upd->filename));
return LIBAVRDUDE_GENERAL_FAILURE;
}
// Patch input if for flash, eg, for vector bootloaders?
if(pgm->flash_readhook) {
AVRMEM *mem = avr_locate_mem(p, upd->memtype);
if(mem && !strcmp(mem->desc, "flash")) {
rc = pgm->flash_readhook(pgm, p, mem, upd->filename, rc);
if (rc < 0) {
pmsg_notice("readhook for file %s failed\n", update_inname(upd->filename));
return LIBAVRDUDE_GENERAL_FAILURE;
}
}
}

size = rc;
pmsg_info("reading input file %s for %s%s\n",
Expand Down
Loading