首先,介绍一下tty设备驱动,这个是基础。 串口终端(/dev/ttySn)
串行端口终端(Serial Port Terminal)是使用计算机串行端口连接的终端设备。计算机把每个串行端口都看作是一个字符设备。有段时间串行端口设备通常被称为终端设备,那时它的最大用途就是用来连接终端,所以这些串行端口所对应的设备名称是/dev/tts/0(或/dev/ttyS0)、/dev/tts/1(或/dev /ttyS1)等,设备号分别是(4,0)、(4,1)等(对应于win系统下的COM1、COM2等)。若要向一个端口发送数据,可以在命令行上把标准输出重定向到这些特殊文件名上即可。
例如,在命令行提示符下键入:echo tekkaman> /dev/ttyS1会把“tekkaman”发送到连接在ttyS1(COM2)端口的设备上。
在2.6以后的内核中,部分三星芯片(例如S3C24x0等)将串口终端设备节点命名为ttySACn。ti的Omap系列芯片从2.6.37开始芯片自带的UART设备开始使用专有的的omap-uart驱动,故设备节点命名为ttyOn,以区别于使用8250驱动时的设备名“ttySn”。
在mp1开发板中,我们使用uart1进行评测:
源代码如下:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define FALSE 1
- #define TRUE 0
- char *recchr="We received:"";
- void print_usage();
- int speed_arr[] = {
- B921600, B460800, B230400, B115200, B57600, B38400, B19200,
- B9600, B4800, B2400, B1200, B300,
- };
- int name_arr[] = {
- 921600, 460800, 230400, 115200, 57600, 38400, 19200,
- 9600, 4800, 2400, 1200, 300,
- };
- void set_speed(int fd, int speed)
- {
- int i;
- int status;
- struct termios Opt;
- tcgetattr(fd, &Opt);
- for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) {
- if (speed == name_arr[i]) {
- tcflush(fd, TCIOFLUSH);
- cfsetispeed(&Opt, speed_arr[i]);
- cfsetospeed(&Opt, speed_arr[i]);
- status = tcsetattr(fd, TCSANOW, &Opt);
- if (status != 0)
- perror("tcsetattr fd1");
- return;
- }
- tcflush(fd,TCIOFLUSH);
- }
- if (i == 12){
- printf("tSorry, please set the correct baud rate!nn");
- print_usage(stderr, 1);
- }
- }
- /*
- *[url=home.php?mod=space&uid=2666770]@Brief[/url] 设置串口数据位,停止位和效验位
- *[url=home.php?mod=space&uid=3142012]@param[/url] fd 类型 int 打开的串口文件句柄*
- *@param databits 类型 int 数据位 取值 为 7 或者8*
- *@param stopbits 类型 int 停止位 取值为 1 或者2*
- *@param parity 类型 int 效验类型 取值为N,E,O,,S
- */
- int set_Parity(int fd,int databits,int stopbits,int parity)
- {
- struct termios options;
- if ( tcgetattr( fd,&options) != 0) {
- perror("SetupSerial 1");
- return(FALSE);
- }
- options.c_cflag &= ~CSIZE ;
- switch (databits) /*设置数据位数*/ {
- case 7:
- options.c_cflag |= CS7;
- break;
- case 8:
- options.c_cflag |= CS8;
- break;
- default:
- fprintf(stderr,"Unsupported data sizen");
- return (FALSE);
- }
-
- switch (parity) {
- case 'n':
- case 'N':
- options.c_cflag &= ~PARENB; /* Clear parity enable */
- options.c_iflag &= ~INPCK; /* Enable parity checking */
- break;
- case 'o':
- case 'O':
- options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
- options.c_iflag |= INPCK; /* Disnable parity checking */
- break;
- case 'e':
- case 'E':
- options.c_cflag |= PARENB; /* Enable parity */
- options.c_cflag &= ~PARODD; /* 转换为偶效验*/
- options.c_iflag |= INPCK; /* Disnable parity checking */
- break;
- case 'S':
- case 's': /*as no parity*/
- options.c_cflag &= ~PARENB;
- options.c_cflag &= ~CSTOPB;
- break;
- default:
- fprintf(stderr,"Unsupported parityn");
- return (FALSE);
- }
- /* 设置停止位*/
- switch (stopbits) {
- case 1:
- options.c_cflag &= ~CSTOPB;
- break;
- case 2:
- options.c_cflag |= CSTOPB;
- break;
- default:
- fprintf(stderr,"Unsupported stop bitsn");
- return (FALSE);
- }
- /* Set input parity option */
- if (parity != 'n')
- options.c_iflag |= INPCK;
- options.c_cc[VTIME] = 150; // 15 seconds
- options.c_cc[VMIN] = 0;
- options.c_lflag &= ~(ECHO | ICANON);
- tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */
- if (tcsetattr(fd,TCSANOW,&options) != 0) {
- perror("SetupSerial 3");
- return (FALSE);
- }
- return (TRUE);
- }
- /**
- *@breif 打开串口
- */
- int OpenDev(char *Dev)
- {
- int fd = open( Dev, O_RDWR ); //| O_NOCTTY | O_NDELAY
- if (-1 == fd) { /*设置数据位数*/
- perror("Can't Open Serial Port");
- return -1;
- } else
- return fd;
- }
- /* The name of this program */
- const char * program_name;
- /* Prints usage information for this program to STREAM (typically
- * stdout or stderr), and exit the program with EXIT_CODE. Does not
- * return.
- */
- void print_usage (FILE *stream, int exit_code)
- {
- fprintf(stream, "Usage: %s option [ dev... ] n", program_name);
- fprintf(stream,
- "t-h --help Display this usage information.n"
- "t-d --device The device ttyS[0-3] or ttySCMA[0-1]n"
- "t-b --baudrate Set the baud rate you can selectn"
- "t [230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300]n"
- "t-s --string Write the device datan");
- exit(exit_code);
- }
- /*
- *@breif main()
- */
- int main(int argc, char *argv[])
- {
- int fd, next_option, havearg = 0;
- char *device;
- int i=0,j=0;
- int nread; /* Read the counts of data */
- char buff[512]; /* Recvice data buffer */
- pid_t pid;
- char *xmit = "1234567890"; /* Default send data */
- int speed, send_mode = 0;
- const char *const short_options = "hd:s:b:m:";
- const struct option long_options[] = {
- { "help", 0, NULL, 'h'},
- { "device", 1, NULL, 'd'},
- { "string", 1, NULL, 's'},
- { "baudrate", 1, NULL, 'b'},
- { "send/recv mode", 0, NULL, 'm'},
- { NULL, 0, NULL, 0 }
- };
-
- program_name = argv[0];
- do {
- next_option = getopt_long (argc, argv, short_options, long_options, NULL);
- switch (next_option) {
- case 'h':
- print_usage (stdout, 0);
- case 'd':
- device = optarg;
- havearg = 1;
- break;
- case 'b':
- speed = atoi(optarg);
- break;
- case 's':
- xmit = optarg;
- havearg = 1;
- break;
- case 'm':
- send_mode = atoi(optarg);
- break;
- case -1:
- if (havearg) break;
- case '?':
- print_usage (stderr, 1);
- default:
- abort ();
- }
- }while(next_option != -1);
- sleep(1);
- fd = OpenDev(device);
- if (fd > 0) {
- set_speed(fd, speed);
- } else {
- fprintf(stderr, "Error opening %s: %sn", device, strerror(errno));
- exit(1);
- }
- if (set_Parity(fd,8,1,'N')== FALSE) {
- fprintf(stderr, "Set Parity Errorn");
- close(fd);
- exit(1);
- }
- #if 0
- pid = fork();
- if (pid < 0) {
- fprintf(stderr, "Error in fork!n");
- } else if (pid == 0){
- #endif
- if (send_mode){
- while(1) {
- printf("%s SEND: %sn",device, xmit);
- write(fd, xmit, strlen(xmit));
- sleep(1);
- i++;
- }
- }else {
- while(1) {
- nread = read(fd, buff, sizeof(buff));
- if (nread > 0) {
- buff[nread] = '\0';
- printf("%s RECV[%d]: %sn", device, nread, buff);
- }
- }
- }
- close(fd);
- exit(0);
- }
复制代码
最后,加上makefile:
- include ../env.mk
- TARGET = $(notdir $(CURDIR))
- objs := $(patsubst %c, %o, $(shell ls *.c))
- $(TARGET)_test:$(objs)
- $(CC) -o $@ $^
- %.o:%.c
- $(CC) -c -o $@ [ DISCUZ_CODE_392 ]lt;
- clean:
- rm -f $(TARGET)_test *.all *.o
复制代码
执行测试结果:
程序开辟一个进程,每隔1s向终端中输出字符串 “1234567890”。
|