C programing of Uart peripheral in beaglebone black (Linux)

Hi,

I am using Beagle bone black board in Linux Ubuntu, i am new to BBB, i tried to check the programing of UART peripheral in the BBB…

Exact C - programs i am not able to found. like simple c program to initialize the UART with baud rate and other information and writing some data using buffer and i should see the data printing on to the mini com…

please help me…

Check out Derek Molloy.
http://derekmolloy.ie/beaglebone/

I use his approach to drive uart communication

Gwen

Linux has a universal UART driver built in called ‘termios’
Depending on what you are trying to do, this might work for you.

https://en.wikibooks.org/wiki/Serial_Programming/termios

http://tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html

— Graham

Hi,

I am using Beagle bone black board in Linux Ubuntu, i am new to BBB, i
tried to check the programing of UART peripheral in the BBB..

Exact C - programs i am not able to found. like simple c program to
initialize the UART with baud rate and other information and writing some
data using buffer and i should see the data printing on to the mini com..

please help me...

The UARTs are connected to /dev/ttySn:

UART0 (console header) /dev/ttyS0 -- note: /sbin/agetty is running on this port
UART1 P9.24,P9.26 /dev/ttyS1
UART2 P9.21,P9.22 /dev/ttyS2
UART3 P9.42 (tx only) /dev/ttyS3
UART4 P9.13,P9.11 /dev/ttyS4
UART5 P8.37,P8.38 /dev/ttyS5

In C, these are "files" and can be accessed via file I/O functions:

At a "lowlevel: open(), read(), write(), close(), and ioctl()/termios().
At a "highlevel: fopen(), fread()/fscanf()/fgets(),
                 fwrite()/fprintf()/fputs(), and fclose().
                 
Unfortunately, the "man" command is not installed in my BBB image, but it
should be there on your Ubuntu machine and all of the C functions listed above
are well documented.

Really simple C program (assumes BB-UART1-00A0.dtbo has been loaded by uBoot
and you have connected to P9.24 and P9.26):

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#define ERRORCHECK(cmd,message) \
if ((cmd) < 0) {\
   int err = errno; \
   perror(message); \
   exit(err); \
}

int main(int argc, char *argv[])
{
    int ttyfd;
    struct termios saved, current;
    
    ttyfd = open("/dev/ttyS1",O_RDWR);
    ERRORCHECK(ttyfd,"Open of /dev/ttyS1 failed:")
    ERRORCHECK(tcgetattr(ttyfd,&saved),"tcgetattr (saved) of /dev/ttyS1 failed:")
    ERRORCHECK(tcgetattr(ttyfd,&current),"tcgetattr (current) of /dev/ttyS1 failed:")
    ERRORCHECK(cfsetspeed(&current,B115200),"cfsetspeed (current) failed:");
    ERRORCHECK(tcsetattr(ttyfd,TCSANOW,&current),"tcsetattr (current) failed:");
    ERRORCHECK(write(ttyfd,"Hello World\r\n",13),"write failed");
    ERRORCHECK(tcsetattr(ttyfd,TCSADRAIN,&saved),"tcsetattr (saved) failed:");
    ERRORCHECK(close(ttyfd),"close failed");
    exit(0);
}

Hi robert,

i checked the enabled uarts in the BBB using the following command :

ls -l /dev/ttyO*, it showed all the uart like bellow

/dev/ttyO0 → ttyS0

/dev/ttyO1 → ttyS1
/dev/ttyO2 → ttyS2
/dev/ttyO3 → ttyS3
/dev/ttyO4 → ttyS4
/dev/ttyO5 → ttyS5

i connected Uart1 tx to Uart2 rx and Uart1 rx to Uart2tx on board to check the basic functionality using 2 minicom on two terminals

after that i opened the two terminals

for 1 terminal i used minicom -D /dev/ttyO1 -b 9600
for other terminal i used minicom -D /dev/ttyO2 -b 9600

two minicoms are opened but not able to communicate both…

please tell me anyhing i am missing??

Did you tie the pins of those peripherals together? You can’t just send a message to a serial port and expect something to happen. Rx1 needs to be tied to tx2, etc.

Also you need to config-pin the correct pins to the correct modes, or do it in the device tree.

Not sure what you were expecting to happen.

Hi jim,

i did hardware connections also like that…

my main idea to check the basic uart communication …

iam opening 2 minicom (for uart1 and uart2 with same baudrate )

i am typing the text in one minicom terminal and seeing in to other minicom terminal…

You need to enable the pins with uBoot overlays:

BB-UART1-00A0 => maps UART1 to P9.24 (Tx) and P9.26 (Rx)
BB-UART2-00A0 => maps UART2 to P9.21 (Tx) and P9.22 (Rx)

You need to edit /boot/uEnv.txt:

Change these two lines:

#uboot_overlay_addr6=/lib/firmware/<file6>.dtbo
#uboot_overlay_addr7=/lib/firmware/<file7>.dtbo

to

uboot_overlay_addr6=/lib/firmware/BB-UART1-00A0.dtbo
uboot_overlay_addr7=/lib/firmware/BB-UART2-00A0.dtbo

and then reboot.

Hi robert,

thanks for reply. you are right i not enabled the pins with device overlays.

as per your suggestion in the boot directory i got uEnv.txt file i opened it in terminal, but if i start adding anything changes means it is showing editing read only file…

i checked the permission using ls -l command it is showing :

debian@beaglebone:/boot$ ls -l
total 18340
-rw-r–r-- 1 root root 160842 Oct 6 2018 config-4.14.71-ti-r80
drwxr-xr-x 3 root root 4096 Oct 7 2018 dtbs
-rw-r–r-- 1 root root 4530240 Oct 7 2018 initrd.img-4.14.71-ti-r80
-rw-r–r-- 1 root root 542 Oct 7 2018 SOC.sh
-rw-r–r-- 1 root root 3644943 Oct 6 2018 System.map-4.14.71-ti-r80
drwxr-xr-x 2 root root 4096 Oct 7 2018 uboot
-rw-r–r-- 1 root root 2042 Jan 1 2000 uEnv.txt
-rwxr-xr-x 1 root root 10416640 Oct 6 2018 vmlinuz-4.14.71-ti-r80
debian@beaglebone:/boot$ ^C
debian@beaglebone:/boot$

How can i add this?? i feel if i did this changes definitely it will work fine…
please help me for this

Hi robert,

i used sudo su command and entered to root directory and opened uEnv.txt file and edited the file and saved and closed the file .

rebooted the board. checked for the basic functionality it is working fine…typing on 1 minicom terminal and able to see the data on second minicom terminal.

thank you for your suggestion…

now i will try for C programing for UART.

Hi,

i am trying with c program for Uart peripheral like this :
#include<termios.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include <stdio.h>
#include<stdlib.h>

void main (void)
{
int file;
char buf[20];
size_t nbytes;
ssize_t bytes_written;
struct termios oldtio, newtio;

if ((file = open("/dev/ttyS1", O_RDWR | O_NOCTTY))<0)
{
printf(“UART: Failed to open the file.\n”);
return;
}

//save the current serial settings
tcgetattr(file, &oldtio);

//clear the structure for new port settings
bzero(&newtio, sizeof(newtio));

newtio.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
newtio.c_iflag = IGNPAR | ICRNL;

tcflush(file, TCIFLUSH);
tcsetattr(file, TCSANOW, &newtio);

strcpy(buf, “This is a test\n”);
nbytes = strlen(buf);

while (1)
{
bytes_written = write(file, buf, nbytes);
sleep(10);
}
close(file);

}

i am running the code in to one terminal using ./uart1.0 and checking the output into one more terminal using

debian@beaglebone:~$ minicom -D /dev/ttyO1 -b 9600

minicom is opening but not able to see the data, here i not did any hardware connection on board.

what is problem , where is the mistake please tell me…

suggest me any hardware connections i need to connect…

Hi robert,

thanks for reply. you are right i not enabled the pins with device overlays.

as per your suggestion in the boot directory i got uEnv.txt file i opened
it in terminal, but if i start adding anything changes means it is showing
editing read only file...

i checked the permission using ls -l command it is showing :

*debian@beaglebone:/boot$ ls -l*
total 18340
-rw-r--r-- 1 root root 160842 Oct 6 2018 config-4.14.71-ti-r80
drwxr-xr-x 3 root root 4096 Oct 7 2018 dtbs
-rw-r--r-- 1 root root 4530240 Oct 7 2018 initrd.img-4.14.71-ti-r80
-rw-r--r-- 1 root root 542 Oct 7 2018 SOC.sh
-rw-r--r-- 1 root root 3644943 Oct 6 2018 System.map-4.14.71-ti-r80
drwxr-xr-x 2 root root 4096 Oct 7 2018 uboot
*-rw-r--r-- 1 root root 2042 Jan 1 2000 uEnv.txt*
-rwxr-xr-x 1 root root 10416640 Oct 6 2018 vmlinuz-4.14.71-ti-r80
debian@beaglebone:/boot$ ^C
debian@beaglebone:/boot$

How can i add this?? i feel if i did this changes definitely it will work
fine..

You need to use sudo to raise your priviledge level to edit uEnv.txt:

sudo nano /boot/uEnv.txt

Be careful, and check your edits before rebooting.

Hi,

i am trying with c program for Uart peripheral like this :
#include<termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include<stdlib.h>

void main (void)
{
         int file;
     char buf[20];
    size_t nbytes;
    ssize_t bytes_written;
    struct termios oldtio, newtio;

    if ((file = open("/dev/ttyS1", O_RDWR | O_NOCTTY))<0)
    {
         printf("UART: Failed to open the file.\n");
         return;
     }

    //save the current serial settings
    tcgetattr(file, &oldtio);

    //clear the structure for new port settings
    bzero(&newtio, sizeof(newtio));

    newtio.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
    newtio.c_iflag = IGNPAR | ICRNL;

    tcflush(file, TCIFLUSH);
    tcsetattr(file, TCSANOW, &newtio);

    strcpy(buf, "This is a test\n");
    nbytes = strlen(buf);

    while (1)
     {
        bytes_written = write(file, buf, nbytes);
        sleep(10);
     }
        close(file);

  }
i am running the code in to one terminal using ./uart1.0 and checking the
output into one more terminal using

debian@beaglebone:~$ minicom -D /dev/ttyO1 -b 9600

minicom is opening but not able to see the data, here i not did any
hardware connection on board.

OK you can't open the *same* serial port with two programs and see what is

what is problem , where is the mistake please tell me...

suggest me any hardware connections i need to connect..

Go back to your earlier set up and cross-wire the pins for UART1 and UART2 and
open minicom on /dev/ttyO2.

Hi robert,

thanks for reply it is working fine…