本文主要是介绍mini210的串口驱动的应用程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
使用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;
}
这篇关于mini210的串口驱动的应用程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!