Programming Serial(UART) in C or C++
-
I am new to the Omega but not new to programming. I have looked through the Omega docs and through this forum but I am not able to find any documentation on what I need to program and setup the serial port in C or C++ - an example would really help. I m sure this must be somewhere, I just can seem to be able to find it.
Thanks in advance for your help.
-
@Arun-Kapur Using the UART on the Omega2 should be like using any other Linux UART device. For starters, use the program
screen
orminiterm.py
(opkg install python-pyserial
) to use the device/dev/ttyS1
for UART1. For C code, search e.g. "linux C uart" or "linux C serial port" or see https://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c .Documentation is present from the Onion team. That's the first Google result for "Omega2 UART". https://docs.onion.io/omega2-docs/uart1.html
-
IS there a UART library for programming in C or C++ and is there example code I can see to get an idea of how to program the UART. I see examples and libraries programming the Omega in C for I2C, PWM and etc. I am not interested in python - just in C or C++
Any help would be appreciated.
Thank you!
-
@Arun-Kapur Suggest you take the advice of @Maximilian-Gerhardt and closely read the docs. Not explicitly stated is the UART is available as a character device in the file system. As such you can write to it and read from it in C(++) as with any other character device. IMHO, it's level of complexity, or lack thereof, does not warrant a separate library.
-
@William-Scott said in Programming Serial(UART) in C or C++:
@Arun-Kapur Suggest you take the advice of @Maximilian-Gerhardt and closely read the docs. Not explicitly stated is the UART is available as a character device in the file system. As such you can write to it and read from it in C(++) as with any other character device. IMHO, it's level of complexity, or lack thereof, does not warrant a separate library.
In actuality, correctly using the Omega's UART is a bit complex, requiring quite a bit of configuration, especially as the defaults are a bit unusually less appropriate than on many other systems.
-
@Chris-Stratton Would you be able to share any example code ?
-
@Maximilian-Gerhardt I read the Onion documentation you pointed me to and that is why asked the question. I don’t want to write scripts or to program in python as the examples show but do this in C or C++. Perhaps you can point me to the C or C++ libraries for the Omega for doing this.
-
@Arun-Kapur I don't see any problem with the C code I have pointed you to.
I have personally tested the C code to work as expected on my Omega2+ for UART1 on 115200 Baud (8N1 standard config, non-blocking).The receiving side is a USB-Serial converter on my Windows 10 system. Connections are already listed in the documentation (GND, RX1, TX1).
Code below.
#include <errno.h> #include <fcntl.h> #include <string.h> #include <termios.h> #include <unistd.h> #include <stdlib.h> #include <stdint.h> #include <stdio.h> #include <string.h> int set_interface_attribs (int fd, int speed, int parity) { struct termios tty; memset (&tty, 0, sizeof tty); if (tcgetattr (fd, &tty) != 0) { fprintf (stderr, "error %d from tcgetattr", errno); return -1; } cfsetospeed (&tty, speed); cfsetispeed (&tty, speed); tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars // disable IGNBRK for mismatched speed tests; otherwise receive break // as \000 chars tty.c_iflag &= ~IGNBRK; // disable break processing tty.c_lflag = 0; // no signaling chars, no echo, // no canonical processing tty.c_oflag = 0; // no remapping, no delays tty.c_cc[VMIN] = 0; // read doesn't block tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, // enable reading tty.c_cflag &= ~(PARENB | PARODD); // shut off parity tty.c_cflag |= parity; tty.c_cflag &= ~CSTOPB; tty.c_cflag &= ~CRTSCTS; if (tcsetattr (fd, TCSANOW, &tty) != 0) { fprintf (stderr, "error %d from tcsetattr", errno); return -1; } return 0; } void set_blocking (int fd, int should_block) { struct termios tty; memset (&tty, 0, sizeof tty); if (tcgetattr (fd, &tty) != 0) { fprintf (stderr, "error %d from tggetattr", errno); return; } tty.c_cc[VMIN] = should_block ? 1 : 0; tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout if (tcsetattr (fd, TCSANOW, &tty) != 0) fprintf (stderr, "error %d setting term attributes", errno); } /* use omega UART1 */ const char *portname = "/dev/ttyS1"; int uartFd = -1; void uart_writestr(const char* string) { write(uartFd, string, strlen(string)); } void uart_write(void* data, size_t len) { write(uartFd, data, len); } ssize_t uart_read(void* buffer, size_t charsToRead) { return read(uartFd, buffer, charsToRead); } int uart_open(const char* port, int baud, int blocking) { uartFd = open (port, O_RDWR | O_NOCTTY | O_SYNC); if (uartFd < 0) { fprintf (stderr, "error %d opening %s: %s", errno, port, strerror (errno)); return -1; } set_interface_attribs (uartFd, baud, 0); // set speed, 8n1 (no parity) set_blocking (uartFd, blocking); //set blocking mode printf("Port %s opened.\n", port); return 1; } int main(int argc, char* argv[] ) { if(!uart_open(portname, B115200, 0)) return -1; for(int i = 0; i < 10; i++) { printf("[+] Writing string to UART.\n"); uart_writestr("Hello world!\n"); usleep(1000 * 1000); } return 0; }