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 or miniterm.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).

    0_1511701635524_uart_working.png

    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;
    }
    

Log in to reply
 

Looks like your connection to Onion Community was lost, please wait while we try to reconnect.