tools: improve usability on OpenBSD
So far, I hadn't managed to run those tools properly on OpenBSD. I was too confused by its stty peculiarities. I'm still confused, but at least I managed to make them work... most of the time...
This commit is contained in:
parent
a8302920cb
commit
c2b507eaff
28
tools/README.md
Normal file
28
tools/README.md
Normal file
@ -0,0 +1,28 @@
|
||||
# Tools
|
||||
|
||||
This folder contains tools to communicate to Collapse OS machines from a modern
|
||||
environment or to manipulate a blkfs.
|
||||
|
||||
Communication tools all take a device path as a first argument. That device is
|
||||
the serial device that connects you to your machine. It's often a USB-to-TTL
|
||||
dongle. When `-` is specified, `stdin` is used as the device.
|
||||
|
||||
Note that for these tools to work well, you need the serial device to be
|
||||
properly set up, TTY-wise. You'll probably want to do that with `stty`. The tool
|
||||
itself takes care of setting the regular stuff (`cs8`, `-parenb`, etc), but you
|
||||
need to set the speed. Here's an example working on OpenBSD:
|
||||
|
||||
$ ( stty 115200 ; ./upload - a000 os.bin ) <>/dev/cuaU0
|
||||
|
||||
To be honest, I'm having a bit of troubles making these tools work as well on
|
||||
OpenBSD as they do in Linux. But it *does* work. Here are some advices:
|
||||
|
||||
* Use `cuaXX` instead of `ttyXX`.
|
||||
* Run `cu -l /dev/cuaXX` before running your tool and run a dummy command to
|
||||
make sure that the output buffer is flushed.
|
||||
|
||||
On Linux, it's generally easier:
|
||||
|
||||
* Run screen on the device (often `/dev/ttyUSBX`)
|
||||
* Quit with `CTRL+A :quit`
|
||||
* Run the tool on the same device
|
@ -22,13 +22,11 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "Can't open %s.\n", argv[3]);
|
||||
return 1;
|
||||
}
|
||||
int fd = open(argv[1], O_RDWR|O_NOCTTY|O_SYNC);
|
||||
int fd = ttyopen(argv[1]);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Could not open %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
set_interface_attribs(fd, 0, 0);
|
||||
set_blocking(fd, 1);
|
||||
char s[0x40];
|
||||
char buf[1024] = {0};
|
||||
sendcmdp(fd, ": _ 1024 0 DO KEY DUP .x I BLK( + C! LOOP ;");
|
||||
|
@ -4,18 +4,33 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define BREATHE usleep(2000)
|
||||
//#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
|
||||
#define DEBUG(...)
|
||||
|
||||
void mread(int fd, char *s, int count)
|
||||
{
|
||||
while (count) {
|
||||
while (read(fd, s, 1) == 0) {
|
||||
usleep(1000);
|
||||
BREATHE;
|
||||
}
|
||||
s++;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that nothing is waiting in the pipeline
|
||||
static void mempty(int fd)
|
||||
{
|
||||
char c;
|
||||
while (read(fd, &c, 1) == 1) {
|
||||
DEBUG("Emptying %d\n", c);
|
||||
BREATHE;
|
||||
}
|
||||
}
|
||||
|
||||
static void mexpect(int fd, char ec)
|
||||
{
|
||||
char c;
|
||||
@ -36,19 +51,23 @@ void readprompt(int fd)
|
||||
|
||||
void sendcmd(int fd, char *cmd)
|
||||
{
|
||||
DEBUG("Sending %s\n", cmd);
|
||||
char junk[2];
|
||||
while (*cmd) {
|
||||
DEBUG("W: %d\n", *cmd);
|
||||
write(fd, cmd, 1);
|
||||
BREATHE;
|
||||
read(fd, &junk, 1);
|
||||
DEBUG("R: %d\n", *junk);
|
||||
cmd++;
|
||||
// The other side is sometimes much slower than us and if we don't let
|
||||
// it breathe, it can choke.
|
||||
usleep(1000);
|
||||
BREATHE;
|
||||
}
|
||||
write(fd, "\r", 1);
|
||||
mexpect(fd, '\r');
|
||||
mexpect(fd, '\n');
|
||||
usleep(1000);
|
||||
BREATHE;
|
||||
}
|
||||
|
||||
// Send a cmd and also read the " ok" prompt
|
||||
@ -79,6 +98,7 @@ int set_interface_attribs(int fd, int speed, int parity)
|
||||
// disable IGNBRK for mismatched speed tests; otherwise receive break
|
||||
// as \000 chars
|
||||
tty.c_iflag &= ~IGNBRK; // disable break processing
|
||||
tty.c_iflag &= ~ICRNL; // disable CR->NL mapping
|
||||
tty.c_lflag = 0; // no signaling chars, no echo,
|
||||
// no canonical processing
|
||||
tty.c_oflag = 0; // no remapping, no delays
|
||||
@ -118,3 +138,15 @@ void set_blocking(int fd, int should_block)
|
||||
}
|
||||
}
|
||||
|
||||
int ttyopen(char *devname)
|
||||
{
|
||||
int fd = 0;
|
||||
if (strcmp(devname, "-") != 0) {
|
||||
fd = open(devname, O_RDWR|O_NOCTTY|O_SYNC);
|
||||
}
|
||||
set_interface_attribs(fd, 0, 0);
|
||||
set_blocking(fd, 0);
|
||||
mempty(fd);
|
||||
set_blocking(fd, 1);
|
||||
return fd;
|
||||
}
|
||||
|
@ -4,4 +4,4 @@ void mread(int fd, char *s, int count);
|
||||
void readprompt(int fd);
|
||||
int set_interface_attribs(int fd, int speed, int parity);
|
||||
void set_blocking(int fd, int should_block);
|
||||
|
||||
int ttyopen(char *devname);
|
||||
|
@ -14,12 +14,11 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "Usage: ./exec device\n");
|
||||
return 1;
|
||||
}
|
||||
int fd = open(argv[1], O_RDWR|O_NOCTTY|O_SYNC);
|
||||
int fd = ttyopen(argv[1]);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Could not open %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
set_interface_attribs(fd, 0, 0);
|
||||
set_blocking(fd, 0);
|
||||
int c = getchar();
|
||||
while (c != EOF) {
|
||||
|
@ -27,13 +27,17 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fd = open(argv[1], O_RDWR|O_NOCTTY);
|
||||
int fd = ttyopen(argv[1]);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Could not open %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
char s[0x30];
|
||||
sprintf(s, ": _ 0x%04x 0x%04x DO I @ .x LOOP ; _", memptr+bytecount, memptr);
|
||||
sendcmd(fd, s);
|
||||
|
||||
for (int i=0; i<bytecount; i++) {
|
||||
read(fd, s, 2); // read hex pair
|
||||
mread(fd, s, 2); // read hex pair
|
||||
s[2] = 0; // null terminate
|
||||
unsigned char c = strtol(s, NULL, 16);
|
||||
putchar(c);
|
||||
|
@ -35,13 +35,11 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
rewind(fp);
|
||||
int fd = open(argv[1], O_RDWR|O_NOCTTY|O_SYNC);
|
||||
int fd = ttyopen(argv[1]);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Could not open %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
set_interface_attribs(fd, 0, 0);
|
||||
set_blocking(fd, 1);
|
||||
char s[0x40];
|
||||
sprintf(s,
|
||||
": _ 0x%04x 0x%04x DO KEY DUP .x I C! LOOP ; _",
|
||||
@ -50,8 +48,8 @@ int main(int argc, char **argv)
|
||||
|
||||
int returncode = 0;
|
||||
while (fread(s, 1, 1, fp)) {
|
||||
putchar('.');
|
||||
fflush(stdout);
|
||||
putc('.', stderr);
|
||||
fflush(stderr);
|
||||
unsigned char c = s[0];
|
||||
write(fd, &c, 1);
|
||||
usleep(1000); // let it breathe
|
||||
@ -69,8 +67,11 @@ int main(int argc, char **argv)
|
||||
}
|
||||
readprompt(fd);
|
||||
sendcmdp(fd, "FORGET _");
|
||||
printf("Done!\n");
|
||||
fprintf(stderr, "Done!\n");
|
||||
fclose(fp);
|
||||
if (fd > 0) {
|
||||
close(fd);
|
||||
}
|
||||
return returncode;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user