精华内容
下载资源
问答
  • 串口 UART的Loopback测试原理

    万次阅读 2013-04-28 17:47:00
    UART的Loopback测试原理 之前在X86的项目中,有现成的测试套件burnintest来完成UART的loopback测试。其中的原理可能并不是很命令。只是简单的认为只会是TX-RX数据对传,并判断发送接收的数据的一致性。其实,真正...

    UART的Loopback测试原理

    之前在X86的项目中,有现成的测试套件burnintest来完成UART的loopback测试。其中的原理可能并不是很命令。只是简单的认为只会是TX-RX数据对传,并判断发送接收的数据的一致性。其实,真正测试的时候,并不是如此千篇一律。

     

    目前在MIPS架构上测试UART,需要编译测试程序出来。大概的研究了下原理。下面是UART loopback测试的环节,以Function的方式呈现。

      /* Set of available UART tests */

    testDesc tests[] = {

           /*loopbackinternal*/

        { "SetLoopback",    test_uart_loopback,     UART1, 1,0, 0},

        {"Signal Check",    test_uart_signals,      UART1, 1,0, 0},

        { "LineBREAK",       test_uart_break,        UART1, 1, 0, 0},

        {"Internal RX FIFO", test_uart_rx_fifo,      UART1, 1, 0, 0},

        {"Internal TX FIFO", test_uart_tx_fifo,      UART1, 1, 0, 0},

        {"ASCII",           test_uart_data,         UART1, 1,0, 0},

        { "Commformats",    test_uart_comm_formats, UART1, 1, 0, 0},

        { "Baudrates",      test_uart_baud_rates,   UART1, 1,0, 0},

        {"Interrupts",      test_uart_interrupts,   UART1, 1,0, 0},

        /*loopbackexternal*/

        { "SetExternal",     test_uart_external,     UART1, 1, 0, 0},

        {"Signal Check",    test_uart_signals,      UART1, 1,0, 0},

        {"ASCII",           test_uart_data,         UART1, 1,0, 0},

        { "Commformats",    test_uart_comm_formats, UART1, 1, 0, 0},

        { "Baudrates",      test_uart_baud_rates,   UART1, 1,0, 0},

        {"Interrupts",      test_uart_interrupts2,  UART1, 1,0, 0},

     

        { NULL,NULL, 0, 0, 0, 0}

    };

     

     

    测试UART loopback还需要弄清楚下面几个问题:

    1、 UART的接口定义和各个Register。

    2、 测试治具。UART上需要插上什么治具?

    3、 测试中涉及到的autoflow。

     

    这里先解决这几个问题吧。

    UART全称为通用的异步收发装置。有9Pin,各个定义如下:

    DB-9 Pin

    EIA abbreviation

    Description

    1

    DCD

    Data carrier detect

    2

    RXD

    Receive data

    3

    TXD

    Transmit data

    4

    DTR

    Data terminal ready

    5

    GND

    Signal ground

    6

    DSR

    Data set ready

    7

    RTS

    Request to send

    8

    CTS

    Clear to send

    9

    RI

    Ring Indicator

     

    其他各个Register的说明还是参阅spec吧。

    参考: http://retired.beyondlogic.org/serial/serial.htm

     

    测试治具:

    Loopback原理本来就是tx-rx对接完成,完整的连接会涉及到CTS/RTS。下图是一般使用的loopback治具。

    其中连接的方式是这样的:

    1、 RX—TX;

    2、 RTS—CTS;

    3、 DCD—DTR—DSR.

    这个剖面是母头的接口,公头的接口顺序反过来。

     

    至于autoflow的功能,主要涉及到RTS和CTS的运作。RTS表示请求发送,CTS则是清零发送。在正常工作的时候,此UART的RTS会连接到另外UART的CTS。如果autoRTS功能打开,当RX FIFO的数据量达到设置的FIFO trigger,则会让RTS处于不工作状态。对面的UART的CTS则会检测到这个状态,停止TX的数据发送,直到RX的FIFO中清空了。

     

    下面简单的描述一下uart loopback测试程序的各个环节。

    1、 signalcheck

    internal和external的信号检测都是一样的,主要是RTS和CTS信号状态的动态设定和检测,通过内部register来设定:MCR和MSR。

    2、 ASCII

    通过分别对TX和RX的Write 和Read,比较数据的一致性。

    3、 commformats

    UART不同的基本设定:数据长度、stopbit、奇偶校验等。设定之后在通过ASCII方式测试,并检测是否有error。

    4、 Baudrate

    不同波特率的设置,在通过ASCII方式验证。并检测是否有error。

    5、 Interrupts

    通过设定内部register来使能各种中断,并将中断程式注册到CIU中。再通过相应的方式触发中断,使其进入中断程序中做相应动作:比如printf。

    在external interrupt测试环节,主要应该有两种方式:1、FIFO enable,通过RTS和CTS控制数据流,并适时的触发FIFO level Trigger,从而产生中断。2、FIFO disable,通过单字节的传输,RX有数据则产生中断。

    6、 LineBreak

    指在internal loopback中特意发一个break信号,将TX线保持低电位。同时会产生一个中断,并造成有数据发送的假象,如果rx有实际的数据接收到,则failed。

     

     

     

     

    展开全文
  • 串口LOOPBAC

    2012-10-18 10:55:29
    CONSOLE的測試串口LOOPBACK
  • 串行通讯之UARTLoopback

    千次阅读 2016-11-18 17:12:29
    串行通讯之UARTLoopback 2 1 USB转串口 2 2 USB Accessory 2 3 连入手机 3 4 代码改进 4 5 打开串口 4 6 写串口数据 4 7 主动读取串口数据 5 8 被动读取串口数据 5 9

     

    1串行通讯之UARTLoopback    2

    1 USB转串口    2

    2 USB Accessory    2

    3 连入手机    3

    4 代码改进    4

    5 打开串口    4

    6 写串口数据    4

    7 主动读取串口数据    5

    8 被动读取串口数据    5

    9 关闭串口    6

     

     

    1串行通讯之UARTLoopback

    1 USB转串口

    这两天在做Android手机上的串行通讯程序。手机没有串口,所以使用了USB转串口,如下图所示:

    1 USB转串口

    上图中,红色的USB A型插头用来给此设备供电;黑色的Micro USB插头用来连接Android手机;粉红色的9针插头用来连接串口设备。

    购买此产品时,附带了Java源代码,也就是工程UARTLoopback。本文对其进行说明及改进。

    2 USB Accessory

    USB设备分为两大类:USB HostUSB AccessoryUSB 附件)。USB键盘、鼠标连入手机后,由手机给其供电,它们属于USB Host;上面的USB转串口连入手机后,会给自己、手机供电,它属于USB Accessory

    查看UARTLoopback的代码可知:访问USB转串口的实质是访问USB Accessory

    关于USB Accessory的更多信息请参考如下博客:

    http://blog.csdn.net/yingzhao80/article/details/45511351

    3 连入手机

    Android 手机上安装UARTLoopbackActivity.apk后,将USB转串口接入手机,就会弹出如下界面:

    2

    这是如何实现的呢?请查看UARTLoopbackAndroidManifest.xml文件。下面是精简后的内容,重点是红色字体部分:

    ... ... ...

    <uses-feature android:name="android.hardware.usb.accessory"/>

    ... ... ...

    <intent-filter>

    <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"/>

    </intent-filter>

    <meta-data

    android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"

    android:resource="@xml/accessory_filter">

    </meta-data>

    ... ... ...

    4 代码改进

    串行通讯的核心类就是FT311UARTInterface,笔者对其进行了改进。改进版的下载网址为:http://download.csdn.net/detail/hanford/9686781

    下文的说明以改进版为准。

    5 打开串口

    打开串口的代码如下

    com.UARTLoopback.FT311UARTInterface m_Comm = new com.UARTLoopback.FT311UARTInterface(this);

    if(m_Comm.open(9600,'N',8,1,0))

    {//成功打开串口

    }

    else if(m_Comm.isExist())

    {//打开串口失败,可能是权限不够,申请权限

    m_Comm.requestPermission();

    }

    else

    {//说明手机未连接USB转串口

    }

    m_Comm.open 用来打开串口

    m_Comm.isExist 用来判断USB转串口是否已经插入手机

    m_Comm.requestPermission 用来申请权限

    打开串口的时候就设置通讯参数,为什么这么设计呢?因为:从USB转串口插入手机到拔出手机这段时间内,只能配置一次通讯参数。

    6 写串口数据

    请参考下面的代码

    if(m_Comm.isOpen()) {

    byte[] data = m_txtSend.getText().toString().getBytes();

    m_Comm.write(data,data.length);

    }

    m_Comm.isOpen 判断串口是否已经打开

    m_txtSend.getText().toString().getBytes() 获取文本框m_txtSend内的文本,然后转换为二进制数据

    m_Comm.write 发送二进制数据

    7 主动读取串口数据

    请参考下面的代码

    if(m_Comm.isOpen()) {

    byte[] data = new byte[1024];

    int nRead=m_Comm.read(data, data.length);

    try {

    m_txtRecv.setText(new String(data, 0, nRead, "UTF-8"));

    } catch (UnsupportedEncodingException ex) {

    }

    }

    m_Comm.read用来读取串口数据,返回读取到的字节数。接下来的代码,将读取到的二进制数据转换为字符串,并显示到文本框m_txtRecv里。

    8 被动读取串口数据

    被动读取串口数据,就是一旦获得了串口数据就通知程序。其代码有点多:

    m_Comm.setEventDataReceived(m_EventDataReceived);

    com.UARTLoopback.FT311UARTInterface.EventDataReceived m_EventDataReceived = new com.UARTLoopback.FT311UARTInterface.EventDataReceived(){

    public void onEvent(byte[] data,int nBytes)

    {//接收到串口数据,就调用此函数

    try {

    m_sRecv += new String(data, 0, nBytes, "UTF-8");

    } catch (UnsupportedEncodingException ex) {

    }

    m_Handler.sendEmptyMessage(1); //更新界面显示

    }

    };

    private Handler m_Handler = new Handler() {

    public void handleMessage(Message msg) {

    switch (msg.what) {

    case 1: m_txtRecv.setText(m_sRecv); break;

    }

    super.handleMessage(msg);

    }

    };

    代码m_Comm.setEventDataReceived(m_EventDataReceived);表示一旦接收到串口数据,马上调用m_EventDataReceived对象的onEvent函数。

    onEvent函数中,将串口数据(保存在数组byte[] data里,字节数为 nBytes)转换为文本,然后加到字符串变量m_sRecv的右边。

    因为onEvent函数不在主线程里,所以需要代码m_Handler.sendEmptyMessage(1);通知m_Handler更新主界面。其实就是handleMessage函数中的m_txtRecv.setText(m_sRecv)被执行。

    总结:

    1m_Comm.setEventDataReceived指定事件处理对象,一旦读取到串口数据,将调用该对象的onEvent函数;

    2onEvent函数是被多线程调用的,更新主界面请使用HandlersendEmptyMessage

    3)如果m_Comm.setEventDataReceived的参数不是null,那么就无法主动读取串口数据了。也就是说,此时m_Comm.read始终返回0

    9 关闭串口

    关闭串口的代码很简单,如下所示:

    m_Comm.close();

    不过,它的问题最严重:

    调用上述代码,读取串口数据的线程(FT311UARTInterface.ThreadRead.run)将被阻塞在如下代码行:

    nRead = FileInputStream_read(m_InputStream,data,data.length);

    上面的代码调用了FileInputStream.read函数,这是一个同步函数——没有读取到串口数据,就不会返回。这个时候,如果串口设备发送过来数据,线程将正常退出;如果串口设备一直未发送数据过来,那么这个线程将永远阻塞在这一行上。

    线程ThreadRead阻塞后,m_Comm.open将无法再打开串口。解决办法就是:拔下USB转串口,重新插入。

    总结:关闭串口会极大概率的导致一个僵尸线程的产生,不够完美的解决办法就是重新拔、插USB转串口。

    展开全文
  • android串口调试工具

    2018-07-31 16:11:56
    ANDROID 的串口调试工具 apk 能接收 能发送 loopback!ANDROID 的串口调试工具 apk 能接收 能发送 loopback
  • HC-05蓝牙串口通信模块应该是使用最广泛的一种蓝牙模块之一了。为什么呢? 因为HC05模块是一款高性能主从一体蓝牙串口模块,可以不用知道太多蓝牙相关知识就可以很好的上手。说白了,只是个蓝牙转串口的设备,你...

    HC-05蓝牙串口通信模块应该是使用最广泛的一种蓝牙模块之一了。为什么呢?

    因为HC05模块是一款高性能主从一体蓝牙串口模块,可以不用知道太多蓝牙相关知识就可以很好的上手。说白了,只是个蓝牙转串口的设备,你只要知道串口怎么编程使用,就可以了,实现了所谓的透明传输。

    但是就是这么一个很常见的模块,网上很多的博客写的都是错的,或者都是很不详细的。

    所以本文就介绍一下这款蓝牙通信模块的使用,包括蓝牙模块的调试、手机与蓝牙模块之间的传输、手机蓝牙控制STM32单片机,应该是逐渐深入的一个过程。但是这仅仅是使用,以后有时间应该会对蓝牙有一个稍微深度的学习,而不能仅仅是浮于表面,只会用。

     

    模块名称:HC-05蓝牙串口通信模块

    参考资料:HC-05蓝牙串口通信模块官方资料包

    知识储备:【STM32】串口通信基本原理(超基础、详细版)

    其他模块:USB转TTL模块、手机蓝牙串口助手app

    手机蓝牙串口助手软件,可以点击链接下载:蓝牙串口。因为这是我见过所有手机端界面最好看的了,其他的界面都有点太糟糕了。

     

    蓝牙模块的调试

    准备工作

    USB转TTL模块与HC-05蓝牙模块的接线:

    两模块共地,两模块共VCC(VCC取5V);蓝牙模块的RX接转换模块的TX,蓝牙模块的TX接转换模块的RX。如下图所示:

    这个时候就要将转换模块连接到电脑上,然后利用串口调试助手进行蓝牙模块的调试。

    附可能会用到的驱动:链接:https://pan.baidu.com/s/1bpYLfCr 密码:yabv

    蓝牙模块的调试

    HC-05蓝牙串口通讯模块具有两种工作模式:命令响应工作模式和自动连接工作模式。在自动连接工作模式下模块又可分为主(Master)、从(Slave)和回环(Loopback)三种工作角色。

    • 当模块处于自动连接工作模式时,将自动根据事先设定的方式连接的数据传输;
    • 当模块处于命令响应工作模式时能执行AT命令,用户可向模块发送各种AT 指令,为模块设定控制参数或发布控制命令。

    怎么进入命令响应工作模式?

    进入命令响应工作模式有两种方法:

    • 模块上电,未配对情况下就是AT模式,波特率为模块本身的波特率,默认:9600,发送一次AT指令时需要置高一次PIO11;
    • PIO11 置高电平后,再给模块上电,此时模块进入AT 模式,波特率固定为:38400,可以直接发送AT指令。

    什么叫做置高一次PIO11?

    在蓝牙模块中有一个小按键,按一下就置高一次PIO11。也就是说,第一种方法需要每发送一次AT指令按一次;而第二种方式是长按的过程中上电,之后就无需再管了,直接发送AT命令即可。

    需要注意一下,两种进入命令响应工作模式的方式使用的波特率是不一样的,建议使用第二种方式。

    怎么区分进了命令响应工作模式呢?

    在蓝牙模块上有灯,当灯快闪的时候,就是自动连接工作模式;当灯慢闪的时候,就是命令响应工作模式。

    AT命令

    进入到命令响应工作模式之后,就可以使用串口调试助手进行蓝牙调试了。

    首先有一点,AT指令不区分大小写,均以回车、换行结尾。下面介绍常用的AT指令:

    常用AT指令
    指令名 响应 含义
    AT OK 测试指令
    AT+RESET OK 模块复位
    AT+VERSION? +VERSION:<Param> OK 获得软件版本号
    AT+ORGL OK 恢复默认状态
    AT+ADDR? +ADDR:<Param> OK 获得蓝牙模块地址
    AT+NAME=<Param> OK 设置设备名称
    AT+NAME? +NAME:<Param> OK 获得设备名称
    AT+PSWD=<Param> OK 设置模块密码
    AT+PSWD? +PSWD:<Param> OK 获得模块密码
    AT+UART=<Param1>,<Param2>,<Param3> OK 设置串口参数
    AT+UART? +UART:<Param1>,<Param2>,<Param3> OK 获得串口参数

    对于AT指令,有几点注意:

    • AT+NAME?:获得设备名称,这个AT指令有很大可能性是没有返回的,因为我也看到了很多的例子……,但是其他的指令都是没有问题的,直接设置设备名称就行了;
    • AT+UART?:获得串口参数,串口的参数一共有三个,波特率、停止位、检验位。其取值如下:
    串口参数
    参数名称 取值
    波特率

    2400、4800、9600、19200、38400、5760、

    115200、230400、460800、921600、1382400

    停止位

    0:1位

    1:2位

    校验位 0:NONE  1:Odd  2:Even

    其默认值为:9600,0,0。

    例子:

    本文中,蓝牙串口的波特率设置成115200。之后的内容,就会采用这个波特率来进行通讯了。

     

    手机与蓝牙模块之间的传输

    直接将蓝牙模块与转换模块连接,再讲其连接到电脑上,蓝牙模块直接进入自动连接工作模式。

    此时手机打开蓝牙串口调试应用,用其来连接蓝牙模块。手机蓝牙串口助手软件,可以点击链接下载:蓝牙串口。万分推荐这款,因为界面脱离了那种黑不溜秋的感觉,比较简洁、清爽。

    这个软件的使用:点击界面右下角蓝牙的标志,选择蓝牙进行连接。

    然后在电脑上的调试助手和手机的蓝牙串口调试应用之间就可以相互传输了,比如:

    可以清楚的看到:电脑向手机发送了“hello you”,手机向电脑发送了“hello world”。

     

    手机蓝牙控制STM32单片机

    之前的两个例子都是相比较而言比较简单的,这个例子将会涉及到程序的内容了。

    实现功能:手机通过蓝牙,向STM32单片机发送消息,STM32接收到消息之后原封不动的返回给手机。当然如果掌握了这个例子,也可以修改成,手机发送特定的消息,然后,STM32单片机做出相对应的动作。比如:点亮LED等、发动电机等等。

    连接说明

    使用USART1进行试验,也就是说STM32选取PA9、PA10来和HC-05进行连接。同时手机通过蓝牙来和HC-05进行连接。

    原理就是:手机通过蓝牙传输到HC-05上,再通过串口通信和STM32通信;而之前一般都是电脑上通过USB线转串口的方式,通过串口和STM32通信。本质上没有区别的。

    这个时候就应该更加深刻地体会到了本文开篇的一句话:说白了,只是个蓝牙转串口的设备,你只要知道串口怎么编程使用,就可以了,实现了所谓的透明传输。蓝牙的相关一切都被封装起来了,都不需要接触到。

    STM32控制程序

    #include "stm32f10x.h"
    
     void My_USART1_Init(void)  
    {  
        GPIO_InitTypeDef GPIO_InitStrue;  
        USART_InitTypeDef USART_InitStrue;  
        NVIC_InitTypeDef NVIC_InitStrue;  
          
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//GPIO端口使能  
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//串口端口使能  
          
        GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;  
        GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;  
        GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;  
        GPIO_Init(GPIOA,&GPIO_InitStrue);  
          
        GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;  
        GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;  
        GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;  
        GPIO_Init(GPIOA,&GPIO_InitStrue);  
          
        USART_InitStrue.USART_BaudRate=115200;  
        USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  
        USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;  
        USART_InitStrue.USART_Parity=USART_Parity_No;  
        USART_InitStrue.USART_StopBits=USART_StopBits_1;  
        USART_InitStrue.USART_WordLength=USART_WordLength_8b;  
          
        USART_Init(USART1,&USART_InitStrue);
          
        USART_Cmd(USART1,ENABLE);//使能串口1  
          
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启接收中断  
          
        NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;  
        NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;  
        NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;  
        NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;  
        NVIC_Init(&NVIC_InitStrue);  
          
    }  
      
    void USART1_IRQHandler(void)  
    {  
        u8 res;  
         if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)  
     {  
         res= USART_ReceiveData(USART1); 	 
         USART_SendData(USART1,res);     
      }  
    }  
       
     int main(void)  
     {    
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
        My_USART1_Init();  
         while(1);  
           
     } 

    这段程序和【STM32】串口相关配置寄存器、库函数(UART一般步骤)中的程序一模一样,几乎没有什么改动。

    区别就是,在UART实验中,USART1是和USB转串口模块连接在一起的,然后与电脑上的串口调试助手进行通信;现在改成USART1是和蓝牙模块连接在一起的,然后和手机上的蓝牙串口调试助手进行通信。

     

    展开全文
  • 本次开发的虚拟串口提供的功能如下:提供两个串口实例串口名称的前缀为vttyU为了验证串口收发,提供了loopback机制,即应用程序向虚拟串口写入数据后,数据再回环至应用程序;在/sys目录下提供数据写入属性文件,可...

    在上一章我们已经说明了uart驱动的开发流程,本章我们就不再介绍uart相关的接口实现,仅通过实现一个虚拟的串口控制器程序,用以说明虚拟串口的开发流程。

    本次开发的虚拟串口提供的功能如下:

    1. 提供两个串口实例
    2. 串口名称的前缀为vttyU
    3. 为了验证串口收发,提供了loopback机制,即应用程序向虚拟串口写入数据后,数据再回环至应用程序;
    4. 在/sys目录下提供数据写入属性文件,可向虚拟串口中写入数据,用以模拟串口接收数据的功能

    本次开发的代码涉及的模块包括:

    1. 创建两个platform device,分别对应两个虚拟串口的platform device;
    2. 创建一个platform driver,在platform driver的probe接口中,完成虚拟串口的注册,主要是完成uart_add_one_port接口完成虚拟串口的注册;在platform driver的remove接口中,完成虚拟串口的注销;
    3. 在串口驱动的初始化函数中,调用uart_register_driver,uart driver的注册。

    数据结构说明

    在虚拟串口驱动中,定义了数据结构virtual_uart_port,该数据结构中包含了uart_port。并定义了tx_enable_flag、rx_enable_flag,分别用于控制串口收发,因是虚拟串口所以使用这两个变量进行表示,若是真是的串口控制器,则不需要这两个变量,而只需要在uart_ops->startup、uart_ops->stop_rx、uart_ops->stop_tx中关闭中断即可,这两个变量由自旋锁write_lock进行保护。

    692a7cbcb543f68b9e410dde6983fe0b.png

    uart_driver定义及注册

    定义virtual_uart_driver,本串口控制器驱动支持的串口个数为MAX_VIRTUAL_UART(6个)、而dev_name则为该虚拟串口对应字符设备文件名称的前缀,本次定义前缀为“vttyU”,本串口不支持控制台。调用uart_register_driver即完成本串口控制器驱动的注册与注销

    b7c7e4db045dd0bb3b014ea2fc4f0c1f.png

    Platform device定义及注册

    本次我们主要完成了串口的注册,因此我们定义并注册了两个platform device,而传递的参数为串口的index的。接口定义如下所示,platform device的name为“virtual_uart_port_dev”,根据该名称可完成与platform driver的匹配及探测功能(因我们在ubuntu16.04下完成的验证,没有设备树概念,因此就定义了这两个platform device,若支持设备树,则无须我们手动定义这两个platform device,只需要修改设备树文件即可)。

    9482e4ab4ee69f8660eb2f7d3fd02c6a.png

    Platform driver的定义及注册

    我们的platform driver的定义如下,支持probe、remove接口,probe接口主要完成uart port的注册、remove接口主要完成uart port注销,该platform driver的name为“virtual_uart_port_dev”,通过该名称可进行platform device与platform driver的匹配检测,同时我们也定义了of_device_id,若内核支持设备树,则在设备树中的compatible中也设置“jerry_chg,virtual-uart”,即可完成platform device与platform driver的匹配检测。

    76286daa6f0437ef185a427030165d7f.png

    virtual_uart_port_platform_probe接口的定义如下,主要实现的功能如下:

    1. 为uart_port申请内存,并设置uart_port的ops、fifosize、type、line等值,另外还可为该uart_port创建uart_port相关的私有属性文件(sysfs下),而在linux3.10的内核中uart_port中并没有定义attr_group变量,导致uart_add_one_port接口只能在tty_port对应device中创建uart核心定义的属性文件,而不能创建uart port私有的属性文件,而在后面的内核中特意增加了attr_group,用于创建uart port私有的属性文件,这个成员变量增加的挺好,本次虚拟串口就借助该变量创建了属性文件uart_receive_buff,用于模拟串口接收数据。
    2. 初始化一个工作队列及其回调函数virtual_uart_flush_to_port,该接口主要是模拟串口发送中断的功能,在真实的串口控制器中,则是申请串口中断,在串口中断的处理函数中进行数据的发送,而我们这个工作队列则是模拟串口中断函数的功能;
    3. 调用uart_add_one_port,完成串口的添加。
    564645ad82fa2e43a6b30e6c8655513a.png

    Uart port操作接口定义

    我们为虚拟串口定义的操作接口如下

    1. 其中tx_empty接口用于测试发送缓存是否为空(uart_port的环形缓冲区);
    2. stop_tx用于停止发送操作(在真实串口控制器驱动中,则关闭发送中断即可);
    3. start_tx用于启动发送操作(在真实串口控制器驱动中,则开启发送中断,然后则触发发送中断,继而在发送中断处理接口中执行数据的发送操作,而在我们的虚拟串口中,则调用schedule_work,启动工作队列,调用工作队列的回调函数进行数据发送);
    4. throttle、unthrottle则是流控操作,在真实串口中则设置相应定时器即可(本驱动未实现该功能);
    5. stop_rx用于停止接收操作(在真实串口控制器驱动中,则关闭接收中断即可)
    6. startup接口主要是启动串口功能(在真实串口控制器驱动中,则申请中断,并使能接收中断;而发送中断的使能在start_tx中实现,而在我们虚拟串口驱动中,则是使能收发数据的flag);
    7. set_termios则主要是设置termios相关参数(包括字节宽度、波特率等参数的设置);
    dc0e14caa818b7a647e124bdafb167b7.png

    而set_mctrl接口则一定要定义,即使是一个空函数也要定义。

    模拟串口接收功能实现

    因为我们是虚拟串口,但是又要模拟串口接收功能,因此我们在tty port对应的device中,定义了模拟串口接收数据的属性文件,定义如下:

    当用户向该属性文件(uart_receive_buff)中写数据时,则在该属性文件的store接口中,将写入的数据发送到tty_port的接收缓存中,并通过调用tty_flip_buffer_push接口,将tty_port接收缓存中的数据通过线路规程的receive_buff接口将数据刷新到tty_struct的接收缓存中,并wakeup读等待队列中sleep的读线程(这一系统的操作流程可参考我之前写的几篇文档),即将数据发送的该串口上的读线程中。

    55cad673f1e97eb7a64df7154b4ff61c.png

    我们可以通过如下脚本向uart_receive_buff写数据,从而模拟串口接收数据

    96f6c45b7ca9296e19cb5470bd48c030.png

    测试验证

    1. 在应用程序中打开/dev/vttyU1,进行数据接收;
    2. 向/sys/class/tty/vttyU1/uart_receive_buff写数据,则上述1中的进程即会接收到数据,测试截图如下
    8eeb605cfc1fd44b1764e3e09b2c4708.png
    4c7b527db6136148a5bd80325694cecf.png

    至此我们完成了虚拟串口驱动代码的实现以及验证工作,我们也完成了tty子系统、uart子系统架构内部实现流程的分析,也完成了对应虚拟控制器驱动的实现及验证,下一次我们开始进行input子系统的分析(关于本驱动的源码,后续我们会把链接发出来)。

    展开全文
  • uart loopback

    2011-07-18 14:19:37
     uart.v     module uart #( parameter clk_freq = 50000000, parameter baud = 9600 ) ( input sys_clk, input sys_rst, output rx_irq, output tx_irq, ...
  • Android串口工具.apk

    2019-12-12 17:04:38
    最近开发了一款Android串口小工具,具有Loopback和Send/Receive两种模式,比较简单,可以用于串口测试,也可以当标准的串口工具使用,使用起来特别方便,所以推荐给大家
  • 串口助手发送数据给单片机,单片机原样返回
  • Android串口工具

    千次阅读 2019-12-12 17:47:07
    最近开发了一款Android串口小工具,具有Loopback和Send/Receive两种模式,比较简单,可以用于串口测试,也可以当标准的串口工具使用,使用起来特别方便,所以推荐给大家 apk下载地址:...
  • 回环接口 loopback

    2016-11-22 15:21:30
    大多数的产品都支持 环回接口 (Loopback Interface),以允许运行在 同一台主机上 的客户程序和服务器程序通过TCP/IP进行通信。A类网络号127就是为环回接口预留的。根据惯例,大多数系统把IP地址 127.0.0.1 ...
  • Linux串口编程

    2014-07-10 17:54:32
    Linux串口编程 ... >Loopback模式  >红外模式  >自动流控模式  串口参数的配置主要包括:波特率、数据位、停止位、流控协议。  linux中的串口设备文件放于/de/目录下,串口一,串口二分别为"/de
  • linux 串口编程

    2015-08-10 16:34:44
     >Loopback模式  >红外模式  >自动流控模式  串口参数的配置主要包括:波特率、数据位、停止位、流控协议。  linux中的串口设备文件放于/de/目录下,串口一,串口二分别为"/dev/ttyS0","/dev
  • 9_uart_loopback_top.rar

    2020-08-22 00:39:17
    Verilog/FPGA串口详细带注释源码工程,收发回环模块亲测可用。非常适合初学者学习使用,资源来自正点原子,感谢他们的辛苦分享。
  • 回环接口(loopback

    千次阅读 2012-12-28 14:42:09
    1 引子 最近搭建web集群环境,采用了LVS+...Loopback接口是虚拟接口,是一种纯软件性质的虚拟接口。任何送到该接口的网络数据报文都会被认为是送往设备自身的。大多数平台都支持使用这种接口来模拟真正的接口。这
  • 串口概述

    2013-02-19 10:55:30
     >Loopback模式  >红外模式  >自动流控模式  串口参数的配置主要包括:波特率、数据位、停止位、流控协议。  linux中的串口设备文件放于/de/目录下,串口一,串口二分别为"/dev/ttyS0","/dev/
  • 原文网址:... 1:检查AP端串口配置是否ok: ...echo 1 > /sys/kernel/debug/msm_serial_hsl/loopback.0 //打开回环开关 adb shell cat /d
  • ZYNQ之DMA LOOPBACK实验

    2021-06-08 21:10:34
    ZYNQ之DMA LOOPBACK实验1 原理介绍1.1 AXI4(AXI-full)总线学习1.2 zynq ps端几种接口1.3 AXI DMA简介1.4 AXI DMA编程顺序1.5 实验目的2 实验步骤2.1 建立BD文件2.2 SDK文件3 结果分析3.1 实验条件3.2 实验结果3.3 ...
  • UART串口编程

    2018-09-15 12:27:29
    Loopback模式 红外模式 自动流控模式 串口参数的配置主要包括:波特率、数据位、停止位、流控协议。 linux中的串口设备文件放于/de/目录下,串口一,串口二分别为”/dev/ttyS0”,”/dev/ttyS1”.在...
  • 串口log

    2017-09-04 13:41:22
    1:检查AP端串口配置是否ok: a:高通平台查看DMA传输: echo 1 > /sys/kernel/debug/msm_serial_hsl/loopback.0 //打开回环开关 adb shell cat /dev/ttyHSL1 另起窗口 # adb shell # echo ...
  • linux串口编程

    2017-11-28 11:59:21
     >Loopback模式  >红外模式  >自动流控模式  串口参数的配置主要包括:波特率、数据位、停止位、流控协议。  linux中的串口设备文件放于/de/目录下,串口一,串口二分别为"/dev/ttyS0","/dev
  • 串口编程 一

    2016-05-13 20:57:08
    串口开发主要有三个方面介绍: 1、 串口概述 2、 串口设置 3、 串口的使用详解 一、串口的概述:常见的串口数据通信方式:并行通信和串行通信; 串行通信是计算机通信常见数据接口,如:RS-232-C,该标准...
  • 简单易用的PC串口测试工具, 使用时需要短接串口中的数据传输角 将需要测试的端口添加到Compo_Serial_LoopBack.ini中
  • 串口参数

    千次阅读 2010-11-20 10:14:00
    Loopback模式;红外模式;自动流控模式;  串口参数的配置主要包括:波特率、数据位、停止位、流控协议。 在linux下操作串口与操作文件相同。 在使用串口之前必须设置相关配置,包括:波特率、数据...
  • linux串口通信

    2016-02-17 18:08:52
    Loopback模式 红外模式 自动流控模式 串口参数的配置主要包括:波特率、数据位、停止位、流控协议。 linux中的串口设备文件放于/de/目录下,串口一,串口二分别为”/dev/ttyS0”,”/dev/ttyS1”.在li

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,613
精华内容 1,445
关键字:

串口loopback