zoukankan      html  css  js  c++  java
  • am335x system upgrade kernel uart(七)

    1      Scope of Document

    This document describes UART hardware design, uart driver porting

    2      Requiremen

    2.1     Function Requirement

    Uboot enable uart0 for debug, Kernel enable uart0 uart1 uart2 uart3.

    2.2     Performance Requirement

    Support common uart rx tx function.

    3      Hardware Overview

    uart interface,pin map:

    // uart 0

    AM335X_UART0_RXD

    AM335X_UART0_TXD

    // uart 1

    AM335X_UART1_RXD

    AM335X_UART1_TXD

    // uart 2

    AM335X_UART2_RXD

    AM335X_UART2_TXD

    // uart 3

    AM335X_UART3_RXD

    AM335X_UART3_TXD

     

     

                      Figure 1 uart interface block diagram

    4      Functional Description

    4.1     UART DRIVER Overview

    The UART Driver enables the UART’s available on the device. The driver configures the UART hardware and interfaces with a number of standard linux tools (ex. stty, minicom, etc.) to enable the configuration and usage of the hardware. The H/W UARTs available will vary by SoC and system configuration.

                         

    4.2     UART

    4.2.1 Overview

    The UART driver can be used to send/receive raw ASCII characters from the User Interface as shown by the below diagram..

    4.2.1 User Layer

    The UART driver leverages the TTY framework within Linux. This framework uses typical file I/O operations to interact with the UART. This interface allows userspace modules to easily be developed to read/write the /dev/ttyxx to exchange data over the UART. Since this is a very common Linux framework, there are many standard tools that can be used to interact with it. These tools, like stty, minicom, picocom, and many others, can easily be used to exercise a UART for data exchange.

     

    Features

    • Exposes UART to User Space via /dev/tty*
    • Supports multiple baud rates and UART capabilities
    • Hardware Flow Control

    5      Porting

    5.1     Uboot porting

    In uboot default enable debug uart, so do not need to modify.

    5.2     Kernel porting

    Index: am335x-evm.dts

          uart1_pins: pinmux_uart1_pins {

                 pinctrl-single,pins = <

                      AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE1)      /* uart1_rxd.uart1_rxd */

                       AM33XX_IOPAD(0x984, PIN_OUTPUT_PULLDOWN | MUX_MODE1)  /* uart1_txd.uart1_txd */

                 >;

          };

         uart2_pins: pinmux_uart2_pins {

                pinctrl-single,pins = <

                       AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE1)      /* mii1_txclk.uart2_rxd */

                       AM33XX_IOPAD(0x930, PIN_OUTPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxclk.uart2_txd */

                >;

         };

         uart3_pins: pinmux_uart3_pins {

                pinctrl-single,pins = <

                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLUP | MUX_MODE1)      /* mii1_rxd3.uart3_rxd */

                       AM33XX_IOPAD(0x938, PIN_OUTPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxd2.uart3_txd */

                >;

         };

     &uart1 {

          pinctrl-names = "default";

          pinctrl-0 = <&uart1_pins>;

         status = "okay";

    };

    &uart2 {

         pinctrl-names = "default";

         pinctrl-0 = <&uart2_pins>;

          status = "okay";

     };

    &uart3 {

         pinctrl-names = "default";

         pinctrl-0 = <&uart3_pins>;

         status = "okay";

    };

    6      Follow-up

    Uart loop test code:

    #include     <stdio.h>

    #include     <stdlib.h>

    #include     <string.h>

    #include     <unistd.h>

    #include     <sys/types.h>

    #include     <sys/stat.h> 

    #include     <fcntl.h> 

    #include     <termios.h>

    #include     <errno.h>

    #include     <pthread.h>

    #include     <sys/ioctl.h>

    #define FALSE 1

    #define TRUE 0

    int fd=-1;

    char buff[512];

    int speed_arr[] = {  B115200, B57600, B38400, B19200, B9600, B4800,

                      B2400, B1200};

    int name_arr[] = {115200, 57600, 38400,  19200,  9600,  4800,  2400, 1200};

    #define debugnum(data,len,prefix) 

    {

            unsigned int i;  

            for (i = 0;i < len;i++) {

                    if(prefix) 

                            printf("0x%02x ",data[i]);

                    else 

                            printf("%02x ",data[i]);

            }

    }

    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);

        }

    }

    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 size ");

           return (FALSE);

        }

        switch (parity)

        {

        case 'n':

        case 'N':

           options.c_cflag &= ~PARENB;  

           options.c_iflag &= ~INPCK;  

           break;

        case 'o':

        case 'O':

           options.c_cflag |= (PARODD | PARENB);

           options.c_iflag |= INPCK;          

           break;

        case 'e':

        case 'E':

           options.c_cflag |= PARENB;    

           options.c_cflag &= ~PARODD;

           options.c_iflag |= INPCK;    

           break;

        case 'S':

        case 's': 

           options.c_cflag &= ~PARENB;

           options.c_cflag &= ~CSTOPB;

           break;

        default:

           fprintf(stderr,"Unsupported parity ");

           return (FALSE);

        }

        switch (stopbits)

        {

        case 1:

           options.c_cflag &= ~CSTOPB;

           break;

        case 2:

           options.c_cflag |= CSTOPB;

           break;

        default:

           fprintf(stderr,"Unsupported stop bits ");

           return (FALSE);

        }

           options.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);

           options.c_oflag &= ~OPOST;

           options.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);

        /* Set input parity option */

       

        if (parity != 'n')

           options.c_iflag |= INPCK;

        options.c_cc[VTIME] = 150; // 15 seconds

        options.c_cc[VMIN] = 0;

       

       

                  tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */

        if (tcsetattr(fd,TCSANOW,&options) != 0)

        {

           perror("SetupSerial 3");

           return (FALSE);

        }

        return (TRUE);

    }

    void receivethread(void)

    {

      int nread;

      while(1)   

      {

        

           if((nread = read(fd,buff,100))>0) //接收数据

           {

               printf("[RECEIVE] Len is %d,content is : ",nread);

               buff[nread]='';

               printf("%s ",buff);

           }

          

           usleep(100/**1000*/);

       }

     return;

    }

    int main(int argc, char *argv[])

    {

        char str[500];

        pthread_t receiveid;

        int  c, ctrlbits;

           /*

                  参数个数小于1则返回,按如下方式执行:

                  ./uart_test /dev/ttyAT1

           */

           if (argc < 2) {

                  printf("Useage: %s dev ", argv[0]);

                  exit(0);

        }

           printf("test ");

        fd = open(argv[1], O_RDWR);

           if (fd < 0){

                  printf("open device %s faild ", argv[1]);

                  exit(0);

           }

       

           set_speed(fd,115200); //设置串口波特率

          

           set_Parity(fd,8,1,'N'); //设置8位数据位,1位停止位,无校验等其他设置。

          

           pthread_create(&receiveid,NULL,(void*)receivethread,NULL);//创建接收线程

        while(1)

        {

          printf("Please Input string to send to %s :",argv[1]);

          scanf("%s", str);

          if(strlen(str)>0){

                  //发送数据

                         write(fd, str, strlen(str)); 

                         write(fd, " ", strlen(" "));

                                usleep(200*1000);     

             }  

             

          }     

        close(fd);

        exit(0);

    }

  • 相关阅读:
    Linked List Cycle leetcode java (链表检测环)
    Remove Duplicates from Sorted List II leetcode java
    Remove Duplicates from Sorted List leetcode java
    Merge Two Sorted Lists leetcode java
    Swap Nodes in Pairs leetcode java
    Median of Two Sorted Array leetcode java
    阿里云最便宜的四种域名注册
    nohup和&后台运行,进程查看及终止
    ipv6转ipv4 NAT64与DNS64基本原理概述
    ros使用pppoe拨号获取ipv6,并且下发IPV6的dns到客户机win7
  • 原文地址:https://www.cnblogs.com/lianghong881018/p/10026511.html
Copyright © 2011-2022 走看看