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…

Hello Everyone out there,
I am using Beaglebone black and i have a PCB connected to it, in which i have RS485 driver and i want to transmit and receive modbus frame in c code.
in this i have to set enable pin of rs485 high before transmit and low after transmit but the problem is that transmission function is running but before transmitting full frame pin sets low in between them i just want 4.2ms delay but i am not able to do this, i tried mutex, sleep(), usleep(), nanosleep() function but nothing is happening according to my requirement can anyone have idea how to solve this issue?