一般来说,车载导航主机都需要外接若干个UART的外设,如支持HFP的蓝牙模块、与原车通信的CAN解码盒模块、u-blox的GPS模块和DVD机芯等。早年使用Telechips TCC8902+WinCE6.0的方案,该芯片串口比较多,基本够用。最后实在不够时想了一招,动态复用调试串口,参见《WinCE下调试串口的动态复用》。后来改用RK3188+Android做车机,RK3188没那么多串口,于是将所有串口外设都接到了STM32上,甚至把触摸屏和收音机等IIC的设备也一并接了过去。STM32负责在RK3188和各个外设之间做数据透明传输。不得不说STM32确实很强大,当然也得亏姚同学用的出神入化了。一个软件支持几十款触屏,N版硬件,自己写的OS在上面跑得飞快。他用STM32把所有的外设都搞掂了,对主CPU就一个串口,数据流示意图如下。
    Android更新太快,RK3188没多久也过时了,后来改用MTK6735做主CPU。姚同学分分钟就把STM32程序移植到了新板子上。用老邓的话说,姚同学就是快!板子拿给我,开始移植Android驱动。原来在RK3188上是直接修改的串口驱动底层,从中断开始、缓存、打包分发等,触屏驱动也是基于原有GT9XX驱动修改的,看了半天,觉得这种方式平台依赖性太大,不便于移植。后来跟老邓和GYP讨论,准备修改软件架构,写一个虚拟设备驱动读取串口数据,并用成对的虚拟串口将数据分发到Bluetooth、CAN等设备驱动中。如此,所有设备驱动都是纯虚的,就无需修改MTK6735串口驱动了,以后再移植到其他平台也会很方便。想得很美,可是刚动手就发现有问题。虚拟设备驱动无法读取TTY设备,这跟WinCE完全不同,Linux不能在驱动里调用open,read。搜遍Linux的驱动代码,几乎就没有这样用的,仅有几处,也是做调试用,看着都别扭,网上也找不到相关的信息,而《Driving Me Nuts - Things You Never Should Do in the Kernel》里明确提到,禁止这样做,且文章还分析了为什么开发者会有此种不合理的想法,摘录如下:
  The most common question asked in this don't-do-that category is, "How do I read a file from within my kernel module?" Most new kernel developers are coming from user-space programming environments or other operating systems where reading a file is a natural and essential part of bringing configuration information into a program. From within the Linux kernel, however, reading data out of a file for configuration information is considered to be forbidden. This is due to a vast array of different problems that could result if a developer tries to do this.
    此路不通,再想别的办法。驱动里不能读取TTY设备,那么就写一个应用读取TTY设备,再将读取的数据分发到Bluetooth等设备驱动中。可仔细一琢磨,觉得这个方案很糟,数据流绕了很多弯,非常不好。还有没有别的法子?Linux下支持串口鼠标、串口蓝牙模块和串口的Modem,它们都是如何在驱动里获取TTY上的数据的呢,一定有妙法!虽然项目有点急,姚同学又太给力,但我还是打算再研究两天,不急于动手去改原生的串口驱动。我知道那是一个坑,掉进去一次就会有第二次第三次,宁可慢点也要绕过它去。
    功夫不负有心人,后来终于Google到一篇介绍TTY的好文,《The TTY demystified》。其中提到:
  Incidentally, the kernel provides several different line disciplines. Only one of them is attached to a given serial device at a time. The default discipline, which provides line editing, is called N_TTY (drivers/char/n_tty.c, if you're feeling adventurous). Other disciplines are used for other purposes, such as managing packet switched data (ppp, IrDA, serial mice), but that is outside the scope of this article. 
    这就是我想要的东东啊!虽然作者没有详述line discipline,但他明确指出Modem及串口鼠标等都使用了线路规程来处理数据,而TTY本身就是默认的线路规程。真是山穷水复疑无路,柳暗花明又一村!接下来重点研究线路规程是如何工作的,并找一个合适的驱动移植过来,最终选定kernel-3.10/drivers/tty/n_hdlc.c为驱动模版进行移植,它支持数据帧的打包和双向通信。Linux下驱动开发,尽可能找现成的移植,这样效率才会高。《Writing a Kernel Line Discipline》也是一片好文,在移植驱动时很有帮助。
    Linux下UART数据流如下图所示。
    简易图如下:
    原来在RK3188上是修改的Low level serial driver,平台相关性太大,如果原厂更新了串口驱动也需要手动同步代码。使用线路规程的方式,则避免了以上问题,且与平台无关,移植非常方便。在MT6735上移植好所有驱动后,后来项目改用MT8735,大概只花了半个小时就移植好了,只要拷贝线路规程驱动、虚拟触屏驱动、收音机驱动、蓝牙模块驱动和uartd应用,修改几个配置文件后编译即可,不用修改一行代码。其中uartd是一个用来切换线路规程的应用。后面如果采用高通的CPU,应该也可以分分钟搞定。
    使用线路规程,除了实现以上基本功能外,同时还增加了一个监测及抓取UART上所有数据流的功能,便于后期开发调试新的串口外设。不得不说,线路规程真是个好东西!Linux的驱动架构实在是牛!

Android(Linux)线路规程的使用的更多相关文章

  1. Android(Linux)实时监控串口数据

    之前在做WinCE车载方案时,曾做过一个小工具TraceMonitor,用于显示WinCE系统上应用程序的调试信息,特别是在实车调试时,用于监控和显示CAN盒与主机之间的串口数据.因为需要抢占市场先机 ...

  2. [tty与uart]理解线路规程的作用

    转自:http://biancheng.dnbcw.info/linux/336240.html Linux OS的设备驱动有相当经典的抽象思想以及分层思想.与通信世界里面的思想相一致. 一.在Lin ...

  3. [uart]理解线路规程的作用

    转自:http://biancheng.dnbcw.info/linux/336240.html Linux OS的设备驱动有相当经典的抽象思想以及分层思想.与通信世界里面的思想相一致. 一.在Lin ...

  4. Android(Linux)控制GPIO方法二

    前文<Android(Linux)控制GPIO的方法及实时性分析>主要使用Linux shell命令控制GPIO,该方法可在调试过程中快速确定GPIO硬件是否有问题,即对应的GPIO是否受 ...

  5. android linux shell 日期设置

    /************************************************************************ android linux shell 日期设置 * ...

  6. I.MX6 Android Linux shell MMPF0100 i2c 设置数据

    #!/system/bin/busybox ash # # I.MX6 Android Linux shell MMPF0100 i2c 设置数据 # 说明: # 本文主要记录通过shell脚本来设置 ...

  7. I.MX6 Android Linux shell MMPF0100 i2c 获取数据

    #!/system/bin/busybox ash # # I.MX6 Android Linux shell MMPF0100 i2c 获取数据 # 说明: # 本文主要记录通过shell脚本来获取 ...

  8. Android/Linux boot time优化

    基于analyze_boot.py分析Android/Linux的kernel boot时间 1.修改HiKey的BoardConfig.mk文件,使能initcall_debug,增加dmesg b ...

  9. Android/Linux Thermal框架分析及其Governor对比

    图表 1 Thermal框架 随着SoC性能的快速提升,功耗也极大提高,带来的负面影响是SoC的温度提高很快,甚至有可能造成物理损坏.同时功耗浪费也降低了电池寿命. 从上图可知,Thermal框架可以 ...

随机推荐

  1. Devexpress Gantt 应用

    甘特图属于甘特系列浏览次数(也称为时间或时间轴图表).此视图显示横条沿时间轴.每个条形代表一个单独的事件的开始和结束的值, 因此,这些图是用来跟踪各种活动的时间范围内(例如计划,利用各种资源,审查该项 ...

  2. 谈I/O模型

    一个IO操作涉及两个系统对象: 调用这个IO的用户Process/Thread 系统内核 - System Kernel 一个具体的Read操作包括两个阶段: 内核等待数据准备就绪:Waiting f ...

  3. Unity3D 5.x 交互功能 - 光线投射、碰撞设置

    1,光线投射碰撞:第一人称视线在预置范围内(如3米)和看到的物体发生碰撞 ① 检测光线投射碰撞的脚本添加在第一人称FPSController上 #pragma strict private var c ...

  4. java 中包的概念,常量,静态与继承

    一.包的概念:创建,使用. 1.新建包: 最上面一行,之前不能再有其它代码了. package 包名; 注意:包名一般都有命名的规范.例如:com.itnba.maya.zy(从大到小). 2.使用包 ...

  5. 为什么你不应该使用 MongoDB

    本文转载自: http://www.oschina.net/translate/why-you-should-never-use-mongodb (只作转载, 不代表本站和博主同意文中观点或证实文中信 ...

  6. Spring(一)

    一. spring是什么? 我们知道struts 是 web 框架 (jsp/action/actionfrom).hibernate 是 orm框架,处于持久层. spring 是容器框架,用于配置 ...

  7. [ASP.NET Core] Static File Middleware

    前言 本篇文章介绍ASP.NET Core里,用来处理静态档案的Middleware,为自己留个纪录也希望能帮助到有需要的开发人员. ASP.NET Core官网 结构 一个Web站台最基本的功能,就 ...

  8. 使用eclipse作为python开发工具安装旧版pydev

    在Eclipse中: Help->Install New Software add之后输入的链接地址 https://dl.bintray.com/fabioz/pydev/old/ 如果使用从 ...

  9. 如何使用grunt压缩js文件

    jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用! 1. 前言 各位web前端开发人员,如果你现在还不知道grunt或者听说过 ...

  10. va_start和va_end使用详解

    本文主要介绍va_start和va_end的使用及原理. 介绍这两个宏之前先看一下C中传递函数的参数时的用法和原理: 1.在C中,当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表 ...