10. UART

UART (Universal Asynchronous Receiver-Transmitter) ist eine Komponente für die asynchrone, serielle Kommunikation zwischen zwei Geräten. Das BBB hat mehrer UART Sende (TX) und Empfangspins (RX).

In den Beispielen werde ich UART4 (Pin 11 ist RX, Pin 13 ist TX) verwenden. Die zwei Pins habe ich mit einem Kabel miteinander verbunden.

Zunächst müssen die Pins in den UART mode gebracht werden:

$ config-pin p9.11 uart

Current mode for P9_11 is:     uart

$ config-pin p9.13 uart

Current mode for P9_13 is:     uart

Anschließend kann mit minicom -b 115200 -o -D /dev/ttyO4 die Verbindung überprüft werden. Zuerst muss mit der Tastenkombination CTRL+A Z E um echo anzuschalten. Bei erfolgreicher Verbindung sollten nun alle Zeichen wiederholt werden:

Welcome to minicom 2.7.1

OPTIONS: I18n
Compiled on May  6 2018, 10:36:56.
Port /dev/ttyO4, 21:24:56

Press CTRL-A Z for help on special keys

hheelllloo  wwoorrlldd

In Python kann man die pyserial Bibliothek verwenden, um mit dem UART zu interagieren:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python3

import serial

ser = serial.Serial("/dev/ttyO4")

msg = b"Hello, World!\n"

print(f"Writing {msg}...")

ser.write(msg);

print("Reading: ", end="")
line = ser.readline()
print(line)

ser.close()

Natürlich kann man dies auch mit C tun:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>

int main(int argc, char* argv[]) 
{
  int file = open("/dev/ttyO4", O_RDWR);

  struct termios tty;
  memset(&tty, 0, sizeof tty);

  if(tcgetattr(file, &tty) != 0) {
      printf("UART: %s\n", strerror(errno));
  }

  tty.c_cflag &= ~PARENB;
  tty.c_cflag &= ~CSTOPB;
  tty.c_cflag |= CS8;
  tty.c_cflag &= ~CRTSCTS;
  tty.c_cflag |= CREAD | CLOCAL;
  tty.c_lflag &= ~ICANON;
  tty.c_lflag &= ~ECHO;
  tty.c_lflag &= ~ECHOE;
  tty.c_lflag &= ~ECHONL;
  tty.c_lflag &= ~ISIG;
  tty.c_iflag &= ~(IXON | IXOFF | IXANY);
  tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL);
  tty.c_oflag &= ~OPOST;
  tty.c_oflag &= ~ONLCR;
  tty.c_cc[VTIME] = 10;
  tty.c_cc[VMIN] = 0;

  cfsetispeed(&tty, B115200);
  cfsetospeed(&tty, B115200);

  if (tcsetattr(file, TCSANOW, &tty) != 0) {
      printf("UART: %s\n", strerror(errno));
  }

  char msg[] = "Hello, World!";
  printf("Writing: %s\n", msg);
  write(file, msg, sizeof(msg));

  char buffer [256];
  memset(&buffer, '\0', sizeof(buffer));

  int num_bytes = read(file, &buffer, sizeof(buffer));
  if (num_bytes < 0) {
      printf("UART: %s\n", strerror(errno));
  }

  printf("Read: %s\n", buffer);

  close(file);
}