zoukankan      html  css  js  c++  java
  • I.MX6 Android Linux UART send receive with multi-thread and multi-mode demo

    /*******************************************************************************************
     *       I.MX6 Android Linux UART send receive with multi-thread and multi-mode demo 
     * 声明:
     *  1. 本软件是为了测试Android底层的Linux驱动以及硬件是否存在缺陷而编写的测试软件;
     *  2. 本软件可以设置为发送、接收、发送并接收模式,并且提供q+enter键退出程序;
     *  3. 本人是采用NDK的方式进行编译的,并采用autorun.sh脚本进行调用,主要是不想敲太多键盘;
     *  4. 本程序并不打算给出太多的注释,没有理由;
     *  5. 如果想知道波特率更多细节,可以参考本人的《I.MX6 Linux Serial Baud Rate hacking》。
     *
     *                                                 2015-8-22 晴 深圳 南山平山村 曾剑锋
     ******************************************************************************************/
    
                                \\\\-*- 目录 -*-////////
                                |     一、cat uartRS.c      |
                                |     二、cat Android.mk    |
                                |     三、cat autorun.sh    |
                                \\\\\\\//////////////
    
    一、cat uartRS.c
        #include <stdio.h>  
        #include <stdlib.h>  
        #include <unistd.h>  
        #include <sys/types.h>  
        #include <sys/stat.h>  
        #include <fcntl.h>      
        #include <termios.h>    
        #include <errno.h>  
        #include <pthread.h>
        
        #define SENDWORKMODE        1
        #define RECVWORKMODE        2
        #define SENDANDRECVWORKMODE 3
        
        int  serial_fd          = 0;  
        int  serialNumber       = 0;
        int  baudRate           = 0;
        int  workMode           = 0;        // 1 send; 2 recv; 3 send and recv
        char serialString[20]   = {0};
        
        char sendString[512]    = {0};
        char recvString[512]    = {0};
        
        int  help ( int argc );
        int  initSerial ( void );
        
        int  getBaudRate ( char *baudRateString );
        void getSerial ( char* commandLineserialString );
        int  getWorkMode ( char *workMode );
        
        int  uart_send ( int fd, char *data, int datalen );
        int  uart_recv ( int fd, char *data, int datalen );
        
        pthread_t recv_thread;
        void *recvDataThread ( void *arg );
        
        pthread_t quitOut_thread;
        void *quitOutThead ( void *arg );
        
        int main(int argc, char **argv)  
        {  
            
            if ( help( argc ) != 0)
                return -1;
            
            getSerial ( argv[1] );
            baudRate = getBaudRate ( argv[2] );
            workMode = getWorkMode ( argv[3] );
        
            initSerial ();
        
            if ( workMode == RECVWORKMODE || workMode == SENDANDRECVWORKMODE ) {
                pthread_create ( &recv_thread, NULL, recvDataThread, NULL );
            }
        
            pthread_create ( &quitOut_thread, NULL, quitOutThead, NULL );
        
            int i = 0;
            while ( 1 ) {
        
                if ( workMode == SENDWORKMODE || workMode == SENDANDRECVWORKMODE ) {
                    sprintf ( sendString, "%03d: %s
    ", i++, argv[4] );
                    uart_send ( serial_fd, sendString, strlen ( sendString ) );  
                }
                usleep ( 100000 );
            } 
              
            close ( serial_fd );  
            return 0;  
        }
        
        int getWorkMode ( char *workModeString ) {
        
            int ret = atoi( workModeString );
        
            switch ( ret ) {
                case 1 :
                    printf ( "workMode: send.
    " );
                    break;
                case 2 :
                    printf ( "workMode: recv.
    " );
                    break;
                case 3 :
                    printf ( "workMode: send and recv.
    " );
                    break;
                default:
                    printf ( "none of this workMode.
    " );
                    exit ( 0 );
            }
        
            return ret;
        }
        
        void *quitOutThead(void *arg) {
        
            //system("stty raw -echo");     can't work well in Android linux
            char ch = '';
        
            while ( 1 ) {
                scanf ( "%c", &ch );
                if ( ch == 'q' || ch == 'Q' ) {
                    exit ( 0 );
                }
            }
        }
        
        void *recvDataThread(void *arg) {
        
            int ret = 0;
            int i = 0;
        
            while ( 1 ) {
                ret = uart_recv ( serial_fd, recvString, sizeof(recvString) );
                printf ( "%03d %s
    ", i++, recvString );
                bzero ( recvString, sizeof(recvString) );
                usleep ( 100000 );
            }
        }
        
        int help( int argc ) {
        
            if ( argc != 5 ) {
                printf ( "USAGE:
    " );
                printf ( "    command <serial absolute path> <baudRate> <workMode> <send String>
    " );
                printf ( "    example:
    " );
                printf ( "        ./uartRS /dev/ttymxc1 115200 3 "1234567890ABCDEFG"
    " );
                return -1;
            }
        
            return 0;
        }
        
        int uart_recv(int fd, char *data, int datalen) {  
        
            int ret = 0;
        
            ret = read ( fd, data, datalen );
              
            return ret;  
        }
        
        int uart_send(int fd, char *data, int datalen) {  
        
            int len = 0;  
        
            len = write ( fd, data, datalen );      //实际写入的长度  
            if(len == datalen) {  
                return len;  
            } else {  
                tcflush(fd, TCOFLUSH);              //TCOFLUSH刷新写入的数据但不传送  
                return -1;  
            }  
              
            return 0;  
        }  
        
        int initSerial( void ) {  
        
            //serial_fd = open( serialString, O_RDWR | O_NOCTTY | O_NDELAY );  
            serial_fd = open ( serialString, O_RDWR );  
            if ( serial_fd < 0 ) {  
                perror ( "open" );  
                return -1;  
            }  
              
            // 串口主要设置结构体termios <termios.h>  
            struct termios options;  
              
            /**
             * tcgetattr函数用于获取与终端相关的参数,参数fd为终端的文件描述符,
             * 返回的结果保存在termios结构体中 
             */  
            tcgetattr ( serial_fd, &options );  
            /**2. 修改所获得的参数*/  
            options.c_cflag |= (CLOCAL | CREAD);    //设置控制模式状态,本地连接,接收使能  
            options.c_cflag &= ~CSIZE;              //字符长度,设置数据位之前一定要屏掉这个位  
            options.c_cflag &= ~CRTSCTS;            //无硬件流控  
            options.c_cflag |= CS8;                 //8位数据长度  
            options.c_cflag &= ~CSTOPB;             //1位停止位  
            options.c_iflag |= IGNPAR;              //无奇偶检验位  
            options.c_oflag = 0;                    //输出模式  
            options.c_lflag = 0;                    //不激活终端模式  
            cfsetospeed ( &options, baudRate );     //设置波特率  
            //cfsetospeed(&options, B2000000);      //设置波特率  
              
            /* 设置新属性,TCSANOW:所有改变立即生效*/  
            tcflush ( serial_fd, TCIFLUSH );        //溢出数据可以接收,但不读  
            tcsetattr ( serial_fd, TCSANOW, &options );  
              
            return 0;  
        }  
        
        void getSerial ( char* commandLineserialString ) {
        
            sprintf ( serialString, "%s", commandLineserialString );
            printf ( "serialString : %s.
    ", serialString );
        }
        
        /**
         * 该函数之所以采用这种方式,主要是为了波特率出错时方便调试
         */
        int getBaudRate ( char* baudRateString ) {
            int ret = atoi ( baudRateString );
            switch ( ret ) {
                case 0:
                    printf ( "baudRate %s.
    ", "0" );
                    ret = B0;
                    break;
                case 50:
                    printf ( "baudRate %s.
    ", "50" );
                    ret = B50;
                    break;
                case 75:
                    printf ( "baudRate %s.
    ", "75" );
                    ret = B75;
                    break;
                case 110:
                    printf ( "baudRate %s.
    ", "110" );
                    ret = B110;
                    break;
                case 134:
                    printf ( "baudRate %s.
    ", "134" );
                    ret = B134;
                    break;
                case 150:
                    printf ( "baudRate %s.
    ", "150" );
                    ret = B150;
                    break;
                case 200:
                    printf ( "baudRate %s.
    ", "200" );
                    ret = B200;
                    break;
                case 300:
                    printf ( "baudRate %s.
    ", "300" );
                    ret = B300;
                    break;
                case 600:
                    printf ( "baudRate %s.
    ", "600" );
                    ret = B600;
                    break;
                case 1200:
                    printf ( "baudRate %s.
    ", "1200" );
                    ret = B1200;
                    break;
                case 1800:
                    printf ( "baudRate %s.
    ", "1800" );
                    ret = B1800;
                    break;
                case 2400:
                    printf ( "baudRate %s.
    ", "2400" );
                    ret = B2400;
                    break;
                case 4800:
                    printf ( "baudRate %s.
    ", "4800" );
                    ret = B4800;
                    break;
                case 9600:
                    printf ( "baudRate %s.
    ", "9600" );
                    ret = B9600;
                    break;
                case 19200:
                    printf ( "baudRate %s.
    ", "19200" );
                    ret = B19200;
                    break;
                case 38400:
                    printf ( "baudRate %s.
    ", "38400" );
                    ret = B38400;
                    break;
                case 57600:
                    printf ( "baudRate %s.
    ", "57600" );
                    ret = B57600;
                    break;
                case 115200:
                    printf ( "baudRate %s.
    ", "115200" );
                    ret = B115200;
                    break;
                case 230400:
                    printf ( "baudRate %s.
    ", "230400" );
                    ret = B230400;
                    break;
                case 460800:
                    printf ( "baudRate %s.
    ", "460800" );
                    ret = B460800;
                    break;
                case 500000:
                    printf ( "baudRate %s.
    ", "500000" );
                    ret = B500000;
                    break;
                case 576000:
                    printf ( "baudRate %s.
    ", "576000" );
                    ret = B576000;
                    break;
                case 921600:
                    printf ( "baudRate %s.
    ", "921600" );
                    ret = B921600;
                    break;
                case 1000000:
                    printf ( "baudRate %s.
    ", "1000000" );
                    ret = B1000000;
                    break;
                case 1152000:
                    printf ( "baudRate %s.
    ", "1152000" );
                    ret = B1152000;
                    break;
                case 1500000:
                    printf ( "baudRate %s.
    ", "1500000" );
                    ret = B1500000;
                    break;
                case 2000000:
                    printf ( "baudRate %s.
    ", "2000000" );
                    ret = B2000000;
                    break;
                case 2500000:
                    printf ( "baudRate %s.
    ", "2500000" );
                    ret = B2500000;
                    break;
                case 3000000:
                    printf ( "baudRate %s.
    ", "3000000" );
                    ret = B3000000;
                    break;
                case 3500000:
                    printf ( "baudRate %s.
    ", "3500000" );
                    ret = B3500000;
                    break;
                case 4000000:
                    printf ( "baudRate %s.
    ", "4000000" );
                    ret = B4000000;
                    break;
                default:
                    printf ( "baudRate is not exist %s.
    ", "0" );
                    ret = B0;
            }
            //printf ("baudRate %s.
    ", baudRateString);
            return ret;
        }
        
    二、cat Android.mk
        LOCAL_PATH := $(call my-dir)
        
        include $(CLEAR_VARS)
        LOCAL_MODULE    := uartRs 
        #LOCAL_STATIC_LIBRARIES :=libpthread
        #LOCAL_SHARED_LIBRARIES :=libpthread
        LOCAL_STATIC_LIBRARIES :=libpthread
        LOCAL_SRC_FILES := uartRS.c
        #LOCAL_LDLIBS    += -lpthread 
        
        include $(BUILD_EXECUTABLE)
    
    三、cat autorun.sh
        # ./uartRS <serial absolute path> <baudRate> <work mode> <send String>
        #   1.serial absolute path
        #     the absolute path for serial port, example:
        #         /dev/ttymxc1
        #   2. referrence baudrate:
        #      0
        #      50
        #      75
        #      110
        #      134
        #      150
        #      200
        #      300
        #      600
        #      1200
        #      1800
        #      2400
        #      4800
        #      9600
        #      19200
        #      38400
        #      57600
        #      115200
        #      230400
        #      460800
        #      500000
        #      576000
        #      921600
        #      1000000
        #      1152000
        #      1500000
        #      2000000
        #      2500000
        #      3000000
        #      3500000
        #      4000000
        #   3. work mode
        #     1. send;
        #     2. recv;
        #     3. send and recv
        #   4. send string
        #     the string what you want to send
        
        chmod 777 ./uartRS              # give excute-permission
        # ./uartRS <serial absolute path> <baudRate> <work mode> <send String>
        ./uartRS      /dev/ttymxc1          115200        3       "1234567890ABCDEF"
  • 相关阅读:
    音乐分类/生成杂记
    音视频编码笔记
    《The challenge of realistic music generation: modelling raw audio at scale》论文阅读笔记
    使用基于Caffe的MobileNet分类踩坑备忘录
    四大轻量化模型对比(转)
    WaveNet: 原始音频生成模型
    《SONG FROM PI: A MUSICALLY PLAUSIBLE NETWORK FOR POP MUSIC GENERATION》论文笔记
    上采样 及 Sub-pixel Convolution (子像素卷积)
    python之sys._getframe() 用于查看函数被什么函数调用以及被第几行调用及被调用函数所在文件
    11
  • 原文地址:https://www.cnblogs.com/zengjfgit/p/4749766.html
Copyright © 2011-2022 走看看