ref: 4ff7f599491c5d29de20583490b5dc4b8d43c8fc
parent: 252d709ce24e5544d9a6fc6faea2adf861c957ff
author: k <k@santiago>
date: Mon Oct 30 15:43:43 EDT 2023
new commands; now can flash
--- a/README.md
+++ b/README.md
@@ -10,6 +10,8 @@
info - get device information and id
read - read device memory
write - write device memory
+ erase - erase memory
+ flash - erase everything, write, and go
go - jump to address
readp - protect memory from reads
readunp - unprotect memory from reads
--- a/stm32up.c
+++ b/stm32up.c
@@ -8,6 +8,8 @@
Doinfo,
Doread,
Dowrite,
+ Doerase,
+ Doflash,
Dogo,
Doreadprot,
Doreadunprot,
@@ -47,18 +49,18 @@
// get the protocol version and commands
buf[0] = Get; buf[1] = Full ^ Get;
- if(write(dev, buf, 2) < 0) {+ if(write(dev, buf, 2) != 2) {fprint(2, "unable to write: %r\n");
- exits("protoerr");;+ exits("deverr");}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {fprint(2, "'get' rejected\n");
- exits("protoerr");;+ exits("protoerr");}
if(readn(dev, buf, 14) == 0 || buf[0] != 11 || buf[13] != Ack) {fprint(2, "protocol error while getting device info\n");
- exits("protoerr");;+ exits("protoerr");}
fprint(2, "protocol version: %x\n", buf[1]);
@@ -88,7 +90,7 @@
if(debug)
fprint(2, "getting device id\n");
buf[0] = Getid; buf[1] = Full ^ Getid;
- if(write(dev, buf, 2) < 0) {+ if(write(dev, buf, 2) != 2) {fprint(2, "unable to write\n");
exits("protoerr");;}
@@ -124,9 +126,9 @@
fprint(2, "%s device\n", cmds);
buf[0] = cmd; buf[1] = Full ^ cmd;
- if(write(dev, buf, 2) < 0) {+ if(write(dev, buf, 2) != 2) {fprint(2, "unable to write\n");
- exits("protoerr");;+ exits("deverr");;}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {@@ -135,9 +137,9 @@
}
buf[0] = Ack;
- if(write(dev, buf, 1) < 0) {+ if(write(dev, buf, 1) != 1) {fprint(2, "unable to ack %s", cmds);
- exits("protoerr");;+ exits("deverr");;}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {@@ -157,9 +159,9 @@
}
buf[0] = Read; buf[1] = Full ^ Read;
- if(write(dev, buf, 2) < 0) {+ if(write(dev, buf, 2) != 2) {fprint(2, "unable to write\n");
- exits("protoerr");+ exits("deverr");}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {@@ -174,9 +176,9 @@
buf[3] = addr & 0xFF;
buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3];
- if(write(dev, buf, 5) < 0) {+ if(write(dev, buf, 5) != 5) {fprint(2, "unable to write\n");
- exits("protoerr");+ exits("deverr");}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {@@ -187,9 +189,9 @@
// send the size
buf[0] = sz; buf[1] = Full ^ buf[0];
- if(write(dev, buf, 2) < 0) {+ if(write(dev, buf, 2) != 2) {fprint(2, "unable to write\n");
- exits("protoerr");+ exits("deverr");}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {@@ -207,21 +209,21 @@
}
void
-stm_writepage(int dev, uvlong addr, uchar sz) // size - 1
+stm_writepage(int dev, uvlong addr, uchar sz)
{- if(addr + (sz + 1) < addr) {+ if(addr + sz < addr) {fprint(2, "addr + sz < addr; please check values\n");
exits("protoerr");}
buf[0] = Write; buf[1] = Full ^ Write;
- if(write(dev, buf, 2) < 0) {+ if(write(dev, buf, 2) != 2) {fprint(2, "unable to write\n");
- exits("protoerr");+ exits("deverr");}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {- fprint(2, "'write memory' command rejected\n");
+ fprint(2, "'write memory' command rejected 0x%02x\n", buf[0]);
exits("protoerr");}
@@ -232,9 +234,9 @@
buf[3] = addr & 0xFF;
buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3];
- if(write(dev, buf, 5) < 0) {+ if(write(dev, buf, 5) != 5) {fprint(2, "unable to write\n");
- exits("protoerr");+ exits("deverr");}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {@@ -243,25 +245,39 @@
}
// send the size
- buf[0] = sz; buf[1] = Full ^ buf[0];
+ buf[0] = sz - 1;
- if(write(dev, buf, 2) < 0) {+ if(write(dev, buf, 1) != 1) {fprint(2, "unable to write\n");
- exits("protoerr");+ exits("deverr");}
- if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {- fprint(2, "write command rejected; check address and count\n");
- exits("protoerr");- }
-
// write contents
- int c = readn(0, buf, sz + 1);
- if(c != sz + 1) {- fprint(2, "memory write error, address 0x%08llx, size-1 0x%02x, c %d\n", addr, sz, c);
+ int c = readn(0, buf, sz);
+ if(c != sz) {+ fprint(2, "error reading stdin\n");
exits("apperr");}
- write(dev, buf, c);
+ if(write(dev, buf, c) != c) {+ fprint(2, "unable to write data\n");
+ exits("deverr");+ }
+
+ // write data checksum
+ buf[0] = (sz - 1) ^ buf[0];
+ for(int i = 1; i < c; i++)
+ buf[0] ^= buf[i];
+
+ if(write(dev, buf, 1) != 1) {+ fprint(2, "unable to write checksum\n");
+ exits("deverr");+ }
+
+ // ack the command and finish
+ if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {+ fprint(2, "write data rejected, got 0x%02x\n", buf[0]);
+ exits("protoerr");+ }
}
void
@@ -276,7 +292,6 @@
exits("protoerr");}
-
fprint(2, "reading device memory 0x%08llx, size: 0x%08llx\n", addr, sz);
// start read memory command
@@ -304,6 +319,10 @@
fprint(2, "write size cannot be 0\n");
exits("protoerr");}
+ if(addr & 0x3 || sz & 0x3) {+ fprint(2, "address and lenght must be 4 byte aligned\n");
+ exits("apperr");+ }
if(addr + sz < addr) {fprint(2, "addr + sz < addr; please check values\n");
exits("protoerr");@@ -312,18 +331,22 @@
fprint(2, "writing device memory 0x%08llx, size: 0x%08llx\n", addr, sz);
// start read memory command
- uvlong caddr = addr;
+ uvlong caddr = addr, laddr = addr;
uvlong csz = sz;
while(caddr < (addr + sz)) {- uchar rsz = 0xFF;
- if(csz < 0x100)
- rsz = csz - 1;
+ uchar rsz = 0x20;
+ if(csz < 0x20)
+ rsz = csz;
stm_writepage(dev, caddr, rsz);
- caddr = caddr + (rsz + 1);
- csz = csz - (rsz + 1);
+ if(debug && caddr - laddr >= 2048) {+ fprint(2, "progress: 0x%08llx / 0x%08llx\n", caddr, addr + sz);
+ laddr = caddr;
+ }
+ caddr = caddr + rsz;
+ csz = csz - rsz;
}
fprint(2, "memory written\n");
@@ -330,6 +353,83 @@
}
void
+stm_erase(int dev, uint n, uchar spage)
+{+ if(n > 256) {+ fprint(2, "unable to erase more than 256 pages\n");
+ exits("apperr");+ }
+
+ if(debug)
+ fprint(2, "erasing memory, %d pages, start %d\n", n, spage);
+
+ uchar csum = 0;
+
+ // send erase command
+ buf[0] = Erase; buf[1] = Full ^ Erase;
+ if(write(dev, buf, 2) != 2) {+ fprint(2, "unable to write: %r\n");
+ exits("deverr");+ }
+
+ if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {+ fprint(2, "'erase' rejected\n");
+ exits("protoerr");+ }
+
+ buf[0] = n - 1;
+ if(write(dev, buf, 1) != 1) {+ fprint(2, "unable to write: %r\n");
+ exits("deverr");+ }
+
+ // full erase
+ if(n == 256) {+ if(debug)
+ fprint(2, "trying a full erase\n");
+
+ buf[0] = 0;
+ if(write(dev, buf, 1) != 1) {+ fprint(2, "unable to write: %r\n");
+ exits("deverr");+ }
+
+ if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {+ fprint(2, "unable to fully erase, got 0x%02x\n", buf[0]);
+ exits("protoerr");+ }
+
+ if(debug)
+ fprint(2, "performed a full erase\n");
+
+ return;
+ }
+
+ csum = n - 1;
+ for(int i = 0; i < n; i++) {+ buf[i] = spage + i;
+ csum ^= buf[i];
+ }
+ buf[n] = csum;
+ for(int i = 0; i < n + 1; i++)
+ fprint(2, "0x%02x ", buf[i]);
+ fprint(2, "\n");
+
+ if(write(dev, buf, (uint)n + 1) != (uint)n + 1) {+ fprint(2, "unable to write: %r\n");
+ exits("deverr");+ }
+
+ if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {+ fprint(2, "'erase' rejected\n");
+ exits("protoerr");+ }
+
+ if(debug)
+ fprint(2, "erased successfully performed\n");
+}
+
+void
stm_go(int dev, uvlong addr)
{if(debug)
@@ -337,14 +437,14 @@
// get the protocol version and commands
buf[0] = Go; buf[1] = Full ^ Go;
- if(write(dev, buf, 2) < 0) {+ if(write(dev, buf, 2) != 2) {fprint(2, "unable to write: %r\n");
- exits("protoerr");;+ exits("deverr");}
if(readn(dev, buf, 1) == 0 || buf[0] != Ack) {fprint(2, "'go' rejected\n");
- exits("protoerr");;+ exits("protoerr");}
// send the start address
@@ -354,7 +454,7 @@
buf[3] = addr & 0xFF;
buf[4] = buf[0] ^ buf[1] ^ buf[2] ^ buf[3];
- if(write(dev, buf, 5) < 0) {+ if(write(dev, buf, 5) != 5) {fprint(2, "unable to write\n");
exits("protoerr");}
@@ -375,10 +475,12 @@
void
usage(void)
{- fprint(2, "usage: %s [-d] [-D device] command args ..\n", argv0);
+ fprint(2, "usage: %s [-d] [-D device] [-b baud] command args ..\n", argv0);
fprint(2, " info\n");
fprint(2, " read addr size\n");
fprint(2, " write addr size\n");
+ fprint(2, " erase page n\n");
+ fprint(2, " flash addr size\n");
fprint(2, " go addr\n");
fprint(2, " readp, readunp, writeunp\n");
fprint(2, " TODO: writep,csum\n");
@@ -389,6 +491,8 @@
main(int argc, char **argv)
{char* devpath = "/dev/eia0";
+ char* baudstr = "9600";
+ char tmp[256];
int action = -1;
int dev = -1;
@@ -396,6 +500,9 @@
uvlong sz = 0;
ARGBEGIN {+ case 'b':
+ baudstr = ARGF();
+ break;
case 'd':
debug = 1;
break;
@@ -424,6 +531,20 @@
sz = strtoull(argv[2], nil, 16);
action = Dowrite;
}
+ if(!strcmp(argv[0], "erase")) {+ if(argv[1] == 0 || argv[2] == 0)
+ usage();
+ addr = strtoull(argv[1], nil, 16);
+ sz = strtoull(argv[2], nil, 16);
+ action = Doerase;
+ }
+ if(!strcmp(argv[0], "flash")) {+ if(argv[1] == 0 || argv[2] == 0)
+ usage();
+ addr = strtoull(argv[1], nil, 16);
+ sz = strtoull(argv[2], nil, 16);
+ action = Doflash;
+ }
if(!strcmp(argv[0], "go")) {if(argv[1] == 0)
usage();
@@ -443,7 +564,7 @@
// set serial operating parameters
if(debug)
- fprint(2, "setting modem to 9600 8E1\n");
+ fprint(2, "setting modem to b%s 8E1\n", baudstr);
int devctl = open(smprint("%sctl", devpath), OWRITE); if(devctl < 0) {fprint(2, "unable to open device ctl %sctl: %r\n", devpath);
@@ -450,7 +571,8 @@
exits("deverr");}
- if(write(devctl, "b9600\n", 8) < 0) {+ sprint(tmp, "b%s\n", baudstr);
+ if(write(devctl, tmp, 8) < 0) {fprint(2, "error: unable to set serial baud: %r\n");
exits("deverr");}
@@ -466,13 +588,14 @@
fprint(2, "error: unable to set serial stop bits: %r\n");
exits("deverr");}
- if(write(devctl, "f\n", 3) < 0) {- fprint(2, "error: unable to flush the serial line: %r\n");
- exits("deverr");- }
+ // if(write(devctl, "f\n", 3) < 0) {+ // fprint(2, "error: unable to flush the serial line: %r\n");
+ // exits("deverr");+ // }
if(debug)
fprint(2, "modem set up accordingly\n");
+ close(devctl);
// opening serial line
if(debug)
@@ -487,12 +610,12 @@
if(debug)
fprint(2, "initiating connection\n");
buf[0] = Conninit;
- if(write(dev, buf, 1) < 0) {+ if(write(dev, buf, 1) != 1) {fprint(2, "error writing while initiating\n");
exits("connerr");}
- if(readn(dev, buf, 1) <= 0 || buf[0] != Ack) {+ if(readn(dev, buf, 1) != 1 || buf[0] != Ack) {fprint(2, "connection could not be initiated, got %x\n", buf[0]);
exits("connerr");}
@@ -502,6 +625,12 @@
case Doinfo: stm_info(dev); break;
case Doread: stm_read(dev, addr, sz); break;
case Dowrite: stm_write(dev, addr, sz); break;
+ case Doerase: stm_erase(dev, addr, sz); break;
+ case Doflash:
+ stm_erase(dev, 256, 0);
+ stm_write(dev, addr, sz);
+ stm_go(dev, addr);
+ break;
case Doreadprot:
case Doreadunprot:
case Dowriteunprot:
--
⑨