Simple linux serial port programming in C.



It is very often to use minicom, putty and gtkterm.. and so forth program to communicate the other device by serial port.

  It is interest to know how to use c code to control the serial port.


My C code be below:

/*refer to 
* http://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c
* http://www.tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html
*/

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

#include <fcntl.h>
#include <termios.h> /*termio.h for serial IO api*/ 

#include <pthread.h>    /* POSIX Threads */

#define MAX_STR_LEN       256

/*
 * The values for speed are 
 * B115200, B230400, B9600, B19200, B38400, B57600, B1200, B2400, B4800, etc
 * 
 *  The values for parity are 0 (meaning no parity), 
 * PARENB|PARODD (enable parity and use odd), 
 * PARENB (enable parity and use even), 
 * PARENB|PARODD|CMSPAR (mark parity), 
 * and PARENB|CMSPAR (space parity).
 * */
 
 
int SetInterfaceAttribs(int fd, int speed, int parity)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0) /* save current serial port settings */
        {
   printf("__LINE__ = %d, error %s\n", __LINE__, strerror(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]  = 1;            // read doesn't block
        tty.c_cc[VTIME] = 0;            // 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)
        {
                printf("__LINE__ = %d, error %s\n", __LINE__, strerror(errno));
                return -1;
        }
        return 0;
}/*set_interface_attribs*/


void SetBlocking(int fd, int should_block)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr(fd, &tty) != 0)
        {
                printf("__LINE__ = %d, error %s\n", __LINE__, strerror(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)
                 printf("__LINE__ = %d, error %s\n", __LINE__, strerror(errno));
}/*SetBlocking*/


void *sendThread(void *parameters)
{
 char sendBuff[MAX_STR_LEN];
 
 memset(&sendBuff[0], 0, MAX_STR_LEN);
 snprintf(&sendBuff[0], MAX_STR_LEN, "hello!");
 
 int fd;
 
 fd = *((int*)parameters);
 
 while(1)
 {
  write(fd, &sendBuff[0], strlen(&sendBuff[0]) ); 
 
  // sleep enough to transmit the length plus receive 25:  
  // approx 100 uS per char transmit
  usleep((strlen(&sendBuff[0]) + 25) * 100);     
 
  usleep(500*1000);        
 }/*while*/
 
 pthread_exit(0); 
}/*sendThread */


void *readThread(void *parameters)
{
 char readBuff[MAX_STR_LEN];
 
 int fd;
 
 fd = *((int*)parameters);
 
 while(1)
 {
  ssize_t len;
  
  memset(&readBuff[0], 0, MAX_STR_LEN);
 
  len = read(fd, &readBuff[0], MAX_STR_LEN); 
 
  if (-1 == len)
  { 
   switch(errno) 
   {
    case EAGAIN:
    printf("__FUNCTION__ = %s, __LINE__ = %d\n", __FUNCTION__, __LINE__);
    usleep(5*1000); 
    continue;
    break;
    
    default:
    printf("__FUNCTION__ = %s, __LINE__ = %d\n", __FUNCTION__, __LINE__);
     pthread_exit(0); 
    break;  
   }
  }
  
  if(0 == len) 
  {
   printf("devic is lost!\n"); /*device maybe be unplugged*/
   exit(0); 
  }/*if*/ 
    
  
  
  // sleep enough to transmit the length plus receive 25:  
  // approx 100 uS per char transmit
  usleep((len + 25) * 100);
  printf("len = %d\n", (int)len);
  
  int i;
  
  for(i = 0; i< len; i++)
   printf("%c(%d %#x)\t", readBuff[i], readBuff[i], readBuff[i]);
   
  printf("\n");    
 }/*while*/
 
 pthread_exit(0); 
}/*readThread */


int main(int argc, char *argv[])
{
 int fd, c, res;
 struct termios oldtio,newtio;
 char buf[MAX_STR_LEN];
 int k;
 char deviceName[MAX_STR_LEN];
 
 
 memset(&deviceName[0], 0, MAX_STR_LEN);
 snprintf(&deviceName[0], MAX_STR_LEN, "/dev/ttyUSB0");
 
 k = 1;
 while(argc > k)
 { 
  if(0 == strncmp(argv[k], "-d", MAX_STR_LEN))
  {
   if(k + 1 < argc)
   {
    snprintf(&deviceName[0], MAX_STR_LEN, "%s", argv[k + 1]);
   }
   else
   {
    printf("error : -d should be follow a device!\n");  
    return 0;
   }/*if */
  }
  k++; 
 }/*while k*/
 
 printf("__FUNCTION__ = %s, __LINE__ = %d\n", __FUNCTION__, __LINE__);
 
 //non-blocking mode
 //fd = open(&deviceName[0], O_RDWR | O_NOCTTY |O_NONBLOCK| O_NDELAY); 
 
 fd = open(&deviceName[0], O_RDWR | O_NOCTTY); 
 if(0 > fd) 
 {
  perror(&deviceName[0]); 
  exit(-1); 
 }/*if */
 
 
 SetInterfaceAttribs(fd, B115200, 0); /* set speed to 115,200 bps, 8n1 (no parity)*/
 SetBlocking(fd, 1); 
 
 pthread_t readThread_t, sendThread_t;  /* thread variables */
 
 pthread_create(&readThread_t, NULL, (void *)readThread, (void *)&fd);
 pthread_create(&sendThread_t, NULL, (void *)sendThread, (void *)&fd);
 
 pthread_join(readThread_t, NULL);   
 pthread_join(sendThread_t, NULL);
 
 close(fd);
 
 return 0;
}/*main*/

 the code would send "hello" string to the uart ( Universal Asynchronous Receiver/Transmitter) per 500 milli-second, and print data which have been received.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值