Skip to content

Commit

Permalink
Implement reset, eeprom.write, eeprom.erase, eeprom.show in snek-ev3
Browse files Browse the repository at this point in the history
Signed-off-by: Misha Gusarov <dottedmag@dottedmag.net>
  • Loading branch information
dottedmag committed Oct 11, 2020
1 parent 36a617b commit b6ef826
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 12 deletions.
1 change: 1 addition & 0 deletions ports/ev3/Makefile
Expand Up @@ -36,6 +36,7 @@ SNEK_LOCAL_CFLAGS = -DSNEK_USE_GLIBC_2_4_MATH
SNEK_LOCAL_BUILTINS = \
snek-ev3.builtin \
$(SNEK_ROOT)/snek-math.builtin \
$(SNEK_ROOT)/snek-eeprom.builtin \
$(SNEK_ROOT)/snek-input.builtin

include $(SNEK_ROOT)/snek-install.defs
Expand Down
1 change: 1 addition & 0 deletions ports/ev3/snek-ev3.builtin
Expand Up @@ -57,6 +57,7 @@ hold, 0
ramp_up, 1
ramp_down, 1

reset, 0

#include "snek-ev3.h"
#define SNEK_POOL 262144
101 changes: 100 additions & 1 deletion ports/ev3/snek-main.c
Expand Up @@ -15,9 +15,15 @@
#include "snek.h"
#include "snek-io.h"
#include <getopt.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include "sensors.h"
#include "motors.h"
#include "utils.h"

// Not entirely clean, but ev3dev has got a single user, so OK for now
#define EEPROM_FILE "/home/robot/.snek-eeprom"

static FILE *snek_posix_input;

Expand All @@ -35,6 +41,7 @@ usage(char *program, int val)
exit(val);
}

static char **snek_argv;

static int
snek_getc_interactive(void)
Expand Down Expand Up @@ -107,6 +114,7 @@ main(int argc, char **argv)

snek_ev3_init_colors();
snek_init();
snek_argv = argv;

bool ret = true;

Expand All @@ -127,8 +135,20 @@ main(int argc, char **argv)
}
snek_interactive = interactive_flag;
} else {
snek_interactive = true;
printf("Welcome to Snek version %s\n", SNEK_VERSION);

// Try running the stored program if no files are supplied on
// the command line
snek_file = "<eeprom>";
snek_posix_input = fopen(EEPROM_FILE, "r");
if (snek_posix_input) {
// The return value is ignored: we know we're dropping
// into the REPL that will supply its own return value.
snek_parse();
fclose(snek_posix_input);
}

snek_interactive = true;
}

if (snek_interactive) { // -i or at no files are supplied on the command line
Expand All @@ -154,3 +174,82 @@ snek_builtin_read(snek_poly_t port)
return SNEK_NULL;
}
}

snek_poly_t
snek_builtin_eeprom_write(void)
{
int fd = open(EEPROM_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("open");
exit(1);
}

for (;;) {
int c = getc(stdin);
if (c == ('d' & 0x1f) || c == 0xff)
break;

char b = c;
if (write_noeintr(fd, &b, 1) != 1) {
perror("write");
exit(1);
}
}
close_noeintr(fd);
return SNEK_NULL;
}

snek_poly_t
snek_builtin_eeprom_erase(void)
{
unlink(EEPROM_FILE);
return SNEK_NULL;
}

snek_poly_t
snek_builtin_eeprom_show(uint8_t nposition, uint8_t nnamed, snek_poly_t *args)
{
(void) nnamed;
(void) args;

int fd = open(EEPROM_FILE, O_RDONLY);
if (nposition)
putc('b' & 0x1f, stdout);

if (fd != -1) {
for (;;) {
char buf[4096];
int read_ = read(fd, buf, sizeof(buf));
if (read_ == 0)
break;
if (read_ == -1) {
perror("read");
exit(1);
}
fputs(buf, stdout);
}
close(fd);
}

if (nposition)
putc('c' & 0x1f, stdout);
return SNEK_NULL;
}

snek_poly_t
snek_builtin_reset(void)
{
if (!snek_interactive) {
snek_error("reset() is not available in non-interactive mode");
return SNEK_NULL;
}

// Reset is done before \n from the input line is processed and echoed,
// so print it here to make sure Snek banner is not printed on the same
// line as reset() echo.
printf("\n");

execv("/proc/self/exe", snek_argv);
perror("execv");
exit(255);
}
11 changes: 0 additions & 11 deletions ports/ev3/snekserver.c
Expand Up @@ -76,17 +76,6 @@ accept4_noeintr(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags
}
}

static int
close_noeintr(int fd)
{
for (;;) {
int ret = close(fd);
if (ret == -1 && errno == EINTR)
continue;
return ret;
}
}

static int
dup2_noeintr(int fd, int fd2)
{
Expand Down
11 changes: 11 additions & 0 deletions ports/ev3/utils.c
Expand Up @@ -56,6 +56,17 @@ write_noeintr(int fd, const char *buf, size_t bufsize)
}
}

int
close_noeintr(int fd)
{
for (;;) {
int ret = close(fd);
if (ret == -1 && errno == EINTR)
continue;
return ret;
}
}

ssize_t
sysfs_read(int dirfd, const char *filename, char *buf, size_t bufsize)
{
Expand Down
6 changes: 6 additions & 0 deletions ports/ev3/utils.h
Expand Up @@ -36,6 +36,12 @@ read_noeintr(int fd, char *buf, size_t bufsize);
ssize_t
write_noeintr(int fd, const char *buf, size_t bufsize);

/*
* close(2) that retries in case of EINTR
*/
int
close_noeintr(int fd);

/*
* Reads up to bufsize bytes of data from sysfs file filename in directory dirfd
* and places it into bufffer buf.
Expand Down

0 comments on commit b6ef826

Please sign in to comment.