博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mini210的串口驱动的应用程序
阅读量:4137 次
发布时间:2019-05-25

本文共 6099 字,大约阅读时间需要 20 分钟。

使用mini210开发板通过串口与PC通信

即要发给串口的数据由android的NDK程序先放入管道,由应用程序读取发到串口给PC

pc发到串口的数据,mini210读到后放入管道,然后由android的NDK程序取走

用管道完成程序设计

 

 

代码如下

使用arm-linux-gcc -o xxx  xxx.c   -static编译 

#include <stdio.h>

#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/ioctl.h>

#define COM_PORT  "/dev/s3c2410_serial0"

#define SERIAL_FIFO0_NAME "/tmp/fifo0"  //管道0

#define SERIAL_FIFO1_NAME "/tmp/fifo1"  //管道1

#define BUFF_MAX_SIZE  600

//#define FIFO_BUF_SIZE PIPE_BUF
//#define FIFO_MSG_SIZE 1000
//#define FIFO_NAME_SIZE 40
#define MAX_FD_NUM 32

int serial_fd;

int fifor_fd;
int fifow_fd;
char send_buf[BUFF_MAX_SIZE];
char recv_buf[BUFF_MAX_SIZE];
 
typedef int (* fd_cb_t)(int, void *);
typedef int (* timeout_cb_t)(void *);

typedef struct

{
  int fd;
  fd_cb_t cb;
} fd_t;

typedef struct

{
  fd_t fds[MAX_FD_NUM];
  int fd_num;
  int fd_max;
  struct timeval tv;
  timeout_cb_t timeout_cb;
  fd_set readset;
} fd_list_t;

static fd_list_t serial_fd_list;

static int serial_rx_cb(int fd, void *ptr);
static int serial_tx_cb(int fd, void *ptr);
int fifo_create(const char *fifo_name);
int fifo_rd_open(const char *fifo_name);
int fifo_wr_open(const char *fifo_name);
int select_init(fd_list_t *fd_list);
int select_wait(fd_list_t *fd_list);
int select_add_fd(fd_list_t *fd_list, int fd, fd_cb_t cb);

int open_port()

{
  int fd_port;
  fd_port = open(COM_PORT, O_RDWR|O_NOCTTY|O_NDELAY); //打开串口
  if(fd_port < 0)
  {
    perror("open serial port");
    return -1;
  }
 
  if(fcntl(fd_port, F_SETFL, 0)<0)
  {
    perror("fcntl F_SETFL\n");
  }
 
//  if(isatty(STDIN_FILENO) == 0)
//  {
//    perror("standard input is not a terminal device");
//  }
  return fd_port;
 
}
       
int set_com_config(int fd, int baud_rate, int data_bits, char parity,
                    int stop_bits)
{
  struct termios new_cfg, old_cfg;
  int speed;
 
  if(tcgetattr(fd, &old_cfg) != 0)
  {
    perror("tcgetattr");
    return -1;
  }
 
  new_cfg = old_cfg;
  cfmakeraw(&new_cfg);
  new_cfg.c_cflag &= ~CSIZE;
 
 
  switch(baud_rate)
  {
    case 115200:
        speed = B115200;
    break;
   
    default:
        speed = B115200;
    break;
  }
  cfsetispeed(&new_cfg, speed);
  cfsetospeed(&new_cfg, speed);
 
  switch(data_bits)
  {
    case 8:
      new_cfg.c_cflag |= CS8;
    break;
   
    default: 
      new_cfg.c_cflag |= CS8;
    break;
  }
 
  switch(parity)
  {
    default:
    case 'n':
    case 'N':
    {
      new_cfg.c_cflag &= ~PARENB;
      new_cfg.c_iflag &= ~INPCK;
    }
    break;
  }
 
  switch(stop_bits)
  {
    default:
    case 1:
      new_cfg.c_cflag &= ~CSTOPB;
    break;
  }     
   
  new_cfg.c_cc[VTIME] = 0; //read 不用等待即返回
  new_cfg.c_cc[VMIN] = 1;  //至少读一个byte返回
 
  tcflush(fd, TCIFLUSH);
 
  if((tcsetattr(fd, TCSANOW, &new_cfg)) != 0)
  {
    perror("tcsetattr");
    return -1;
  }
 
  return 0;
}
      
                                     
int main(void)
{
 

  select_init(&serial_fd_list);

 
  if(mkdir("/tmp", 0777) == -1)
  {
    if(errno == EEXIST)
    {
      printf("/tmp  has been exist!\n");
    }
    else
    {
      perror("can't create tmp");
      return 1;
    }   
  } 
   
  if((serial_fd = open_port()) < 0)
  {
    perror("open_port");
    return 1;
  }

  if (fifo_create(SERIAL_FIFO0_NAME) < 0) exit(1);

  if ((fifor_fd = fifo_rd_open(SERIAL_FIFO0_NAME)) < 0) exit(1);
  if (fifo_create(SERIAL_FIFO1_NAME) < 0) exit(1);
  if ((fifow_fd = fifo_wr_open(SERIAL_FIFO1_NAME)) < 0) exit(1); 
     
 select_add_fd(&serial_fd_list, serial_fd, serial_rx_cb);      //PC串口-->管道-->A8
 select_add_fd(&serial_fd_list, fifor_fd, serial_tx_cb);       //A8-->管道-->PC串口

 

  if((set_com_config(serial_fd, 115200, 8, 'n', 1) < 0))
  {
    perror("set_com_config");
    return 1;
  }

 while(1)

  {
    select_wait(&serial_fd_list);
  }
 
  close(fifor_fd);
  close(fifow_fd);  
  close(serial_fd);
  return 0;
}

static int serial_rx_cb(int fd, void *ptr)
{
  memset(recv_buf, 0, BUFF_MAX_SIZE);
  if(read(fd, recv_buf, BUFF_MAX_SIZE) > 0) //从串口读数据存入recv_buf
  {
    printf("the received word are: %s\r\n", recv_buf);
  }
  printf("the received word length: %d\r\n", strlen(recv_buf));
  write(fifow_fd, recv_buf, strlen(recv_buf));  //写入管道
  return 0;
}

static int serial_tx_cb(int fd, void *ptr)

{
  int len,j = 0;
  read(fd, send_buf, BUFF_MAX_SIZE);  //从管道读出数据存入send_buf
  //len = strlen(send_buf);
  while(send_buf[j] != 0xfd)
  {
    printf("words will send are: 0x%x\r\n", send_buf[j]);
    j++;
  }
  printf("%d words will be send,last word 0x%x!\r\n", j+1, send_buf[j]);
  write(serial_fd, send_buf, j+1);  //发到串口,以0xfd为结尾字符
  return 0;
}

int fifo_create(const char *fifo_name) //创建管道
{
  char sys_str[50];

  sprintf(sys_str, "rm -rf %s", fifo_name);

  /* Remove old fifos */

  system(sys_str);

  if((mkfifo(fifo_name, 0777) < 0) && (errno != EEXIST))

  {
    fprintf(stderr, "cannot create fifo\n");
    return -1;
  }

  return 0;

}

int fifo_rd_open(const char *fifo_name)

{
  int fd;

  fd = open(fifo_name, O_RDWR | O_NONBLOCK);

  if (fd == -1)

  {
    fprintf(stderr, "fifo rd open failed. errno:%d\n", errno);
  }
 
  return fd;
}

int fifo_wr_open(const char *fifo_name)

{
  int fd;

  fd = open(fifo_name, O_RDWR);

  if (fd == -1)

  {
    fprintf(stderr, "fifo wr open failed. errno:%d\n", errno);
  }
  return fd;
}

/*

下面几个函数是内核驱动函数的poll函数对应的select函数

uart驱动对应一个select
管道对应一个select,当管道有数据时,会调用对应select的回调函数

*/

int select_init(fd_list_t *fd_list)

{
  fd_list->fd_num = 0;
  fd_list->fd_max = 0;
  FD_ZERO(&fd_list->readset);
}

int select_add_fd(fd_list_t *fd_list, int fd, fd_cb_t cb)

{
  if (fd > 0)
  {
    fd_list->fds[fd_list->fd_num].fd = fd;
    fd_list->fds[fd_list->fd_num].cb = cb;
    fd_list->fd_num++;

    if (fd > fd_list->fd_max) fd_list->fd_max = fd;

    FD_SET(fd, &(fd_list->readset));

  }

  return  fd_list->fd_num - 1;

}

int select_wait(fd_list_t *fd_list)
{
  int rc, i;

  FD_ZERO(&fd_list->readset);

  for (i=0; i<fd_list->fd_num; i++)
  {
    if (fd_list->fds[i].fd > 0)
    {
      FD_SET(fd_list->fds[i].fd, &(fd_list->readset));
    }
  }

  if (fd_list->tv.tv_sec == 0)

    rc = select(fd_list->fd_max+1, &(fd_list->readset), (void *)0, (void *)0, (void *)0);
  else
    rc = select(fd_list->fd_max+1, &(fd_list->readset), (void *)0, (void *)0, &fd_list->tv);

  //printf("select get rc:%d\n", rc);

  if (rc > 0)

  {
    for (i=0; i<fd_list->fd_num; i++)
    {
      if (FD_ISSET(fd_list->fds[i].fd, &(fd_list->readset)))
      {
//        printf("select get fd:%d\n", fd_list->fds[i].fd);
        if (fd_list->fds[i].cb)
        {
          fd_list->fds[i].cb(fd_list->fds[i].fd, (void *)0);
        }
        break;
      }
    }
  }
  else if (rc == 0)
  {
    if (fd_list->timeout_cb != NULL)
    {
      fd_list->timeout_cb(NULL);
    }
  }
  else
  {
    printf("select return error:%d\n", errno);
  }

  return rc;

}

转载地址:http://nelvi.baihongyu.com/

你可能感兴趣的文章
Spring MVC和Struts2的比较
查看>>
Hibernate和IBatis对比
查看>>
Spring MVC 教程,快速入门,深入分析
查看>>
Android 的source (需安装 git repo)
查看>>
Commit our mod to our own repo server
查看>>
LOCAL_PRELINK_MODULE和prelink-linux-arm.map
查看>>
Simple Guide to use the gdb tool in Android environment
查看>>
Netconsole to capture the log
查看>>
Build GingerBread on 32 bit machine.
查看>>
How to make SD Card world wide writable
查看>>
Detecting Memory Leaks in Kernel
查看>>
Linux initial RAM disk (initrd) overview
查看>>
Timestamping Linux kernel printk output in dmesg for fun and profit
查看>>
There's Much More than Intel/AMD Inside
查看>>
apache和tomcat整合
查看>>
java虚拟机错误问题
查看>>
oracle建立表空间
查看>>
oracle分区表的性能提升
查看>>
"Cannot allocate memory" OutofMemory when call Ant to build Polish project in Tomcat
查看>>
dumpcap抓包(python)
查看>>