clang: Fixes of warning and nasty bugs
[simavr] / examples / parts / uart_pty.c
index b442825..6fc3287 100644 (file)
  */
 
 #include <sys/select.h>
+#include <stdlib.h>
 #include <pthread.h>
 #include <string.h>
 #include <stdio.h>
 #include <errno.h>
 #include <unistd.h>
-#include <pty.h>
 #include <signal.h>
+#ifdef __APPLE__
+#include <util.h>
+#else
+#include <pty.h>
+#endif
 
 #include "uart_pty.h"
 #include "avr_uart.h"
 
 DEFINE_FIFO(uint8_t,uart_pty_fifo);
 
+//#define TRACE(_w) _w
+#ifndef TRACE
+#define TRACE(_w)
+#endif
+
 /*
  * called when a byte is send via the uart on the AVR
  */
-static void uart_pty_in_hook(struct avr_irq_t * irq, uint32_t value, void * param)
+static void
+uart_pty_in_hook(
+               struct avr_irq_t * irq,
+               uint32_t value,
+               void * param)
 {
        uart_pty_t * p = (uart_pty_t*)param;
-       //printf("uart_pty_in_hook %02x\n", value);
+       TRACE(printf("uart_pty_in_hook %02x\n", value);)
        uart_pty_fifo_write(&p->in, value);
 }
 
 // try to empty our fifo, the uart_pty_xoff_hook() will be called when
 // other side is full
-static void  uart_pty_flush_incoming(uart_pty_t * p)
+static void
+uart_pty_flush_incoming(
+               uart_pty_t * p)
 {
        while (p->xon && !uart_pty_fifo_isempty(&p->out)) {
                uint8_t byte = uart_pty_fifo_read(&p->out);
-       //      printf("uart_pty_flush_incoming send %02x\n", byte);
+               TRACE(printf("uart_pty_flush_incoming send %02x\n", byte);)
                avr_raise_irq(p->irq + IRQ_UART_PTY_BYTE_OUT, byte);
        }
 }
@@ -59,11 +75,14 @@ static void  uart_pty_flush_incoming(uart_pty_t * p)
  * Called when the uart has room in it's input buffer. This is called repeateadly
  * if necessary, while the xoff is called only when the uart fifo is FULL
  */
-static void uart_pty_xon_hook(struct avr_irq_t * irq, uint32_t value, void * param)
+static void
+uart_pty_xon_hook(
+               struct avr_irq_t * irq,
+               uint32_t value,
+               void * param)
 {
        uart_pty_t * p = (uart_pty_t*)param;
-       if (!p->xon)
-               printf("uart_pty_xon_hook\n");
+       TRACE(if (!p->xon) printf("uart_pty_xon_hook\n");)
        p->xon = 1;
        uart_pty_flush_incoming(p);
 }
@@ -71,15 +90,20 @@ static void uart_pty_xon_hook(struct avr_irq_t * irq, uint32_t value, void * par
 /*
  * Called when the uart ran out of room in it's input buffer
  */
-static void uart_pty_xoff_hook(struct avr_irq_t * irq, uint32_t value, void * param)
+static void
+uart_pty_xoff_hook(
+               struct avr_irq_t * irq,
+               uint32_t value,
+               void * param)
 {
        uart_pty_t * p = (uart_pty_t*)param;
-       if (p->xon)
-               printf("uart_pty_xoff_hook\n");
+       TRACE(if (p->xon) printf("uart_pty_xoff_hook\n");)
        p->xon = 0;
 }
 
-static void * uart_pty_thread(void * param)
+static void *
+uart_pty_thread(
+               void * param)
 {
        uart_pty_t * p = (uart_pty_t*)param;
 
@@ -107,7 +131,7 @@ static void * uart_pty_thread(void * param)
                        ssize_t r = read(p->s, p->buffer, sizeof(p->buffer)-1);
                        p->buffer_len = r;
                        p->buffer_done = 0;
-               //      hdump("pty recv", p->buffer, r);
+                       TRACE(hdump("pty recv", p->buffer, r);)
                }
                if (p->buffer_done < p->buffer_len) {
                        // write them in fifo
@@ -121,10 +145,10 @@ static void * uart_pty_thread(void * param)
                        while (!uart_pty_fifo_isempty(&p->in) && dst < (buffer+sizeof(buffer)))
                                *dst++ = uart_pty_fifo_read(&p->in);
                        size_t len = dst - buffer;
-                       size_t r = write(p->s, buffer, len);
-               //      hdump("pty send", buffer, r);
+                       TRACE(size_t r =) write(p->s, buffer, len);
+                       TRACE(hdump("pty send", buffer, r);)
                }
-       //      uart_pty_flush_incoming(p);
+               uart_pty_flush_incoming(p);
        }
        return NULL;
 }
@@ -134,7 +158,10 @@ static const char * irq_names[IRQ_UART_PTY_COUNT] = {
        [IRQ_UART_PTY_BYTE_OUT] = "8>uart_pty.out",
 };
 
-void uart_pty_init(struct avr_t * avr, uart_pty_t * p)
+void
+uart_pty_init(
+               struct avr_t * avr,
+               uart_pty_t * p)
 {
        p->avr = avr;
        p->irq = avr_alloc_irq(&avr->irq_pool, 0, IRQ_UART_PTY_COUNT, irq_names);
@@ -154,7 +181,9 @@ void uart_pty_init(struct avr_t * avr, uart_pty_t * p)
 
 }
 
-void uart_pty_stop(uart_pty_t * p)
+void
+uart_pty_stop(
+               uart_pty_t * p)
 {
        puts(__func__);
        pthread_kill(p->thread, SIGINT);
@@ -163,7 +192,10 @@ void uart_pty_stop(uart_pty_t * p)
        pthread_join(p->thread, &ret);
 }
 
-void uart_pty_connect(uart_pty_t * p, char uart)
+void
+uart_pty_connect(
+               uart_pty_t * p,
+               char uart)
 {
        // disable the stdio dump, as we are sending binary there
        uint32_t f = 0;
@@ -183,5 +215,20 @@ void uart_pty_connect(uart_pty_t * p, char uart)
                avr_irq_register_notify(xon, uart_pty_xon_hook, p);
        if (xoff)
                avr_irq_register_notify(xoff, uart_pty_xoff_hook, p);
+
+       char link[128];
+       sprintf(link, "/tmp/simavr-uart%c", uart);
+       unlink(link);
+       if (symlink(p->slavename, link) != 0) {
+               fprintf(stderr, "WARN %s: Can't create %s: %s", __func__, link, strerror(errno));
+       } else {
+               printf("%s: %s now points to %s\n", __func__, link, p->slavename);
+       }
+       if (getenv("SIMAVR_UART_XTERM") && atoi(getenv("SIMAVR_UART_XTERM"))) {
+               char cmd[256];
+               sprintf(cmd, "nohup xterm -e picocom -b 115200 %s >/dev/null 2>&1 &", p->slavename);
+               system(cmd);
+       } else
+               printf("note: export SIMAVR_UART_XTERM=1 and install picocom to get a terminal\n");
 }