Android(Linux)线路规程的使用

简介: 一般来说,车载导航主机都需要外接若干个UART的外设,如支持HFP的蓝牙模块、与原车通信的CAN解码盒模块、u-blox的GPS模块和DVD机芯等。早年使用Telechips TCC8902+WinCE6.0的方案,该芯片串口比较多,基本够用。
    一般来说,车载导航主机都需要外接若干个UART的外设,如支持HFP的蓝牙模块、与原车通信的CAN解码盒模块、u-bloxGPS模块和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的驱动架构实在是牛!
目录
相关文章
|
5天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
24 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
3月前
|
Linux 调度 Android开发
【系统启动】Kernel怎么跳转到Android:linux与安卓的交界
【系统启动】Kernel怎么跳转到Android:linux与安卓的交界
49 0
|
3月前
|
Linux Android开发
Android 正常运行所需的一系列 Linux 内核接口
Android 正常运行所需的一系列 Linux 内核接口
53 0
|
4月前
|
Linux 测试技术 Android开发
Linux下Android Studio 3.6以及最新版安装图文详解
Linux下Android Studio 3.6以及最新版安装图文详解
236 0
|
3天前
|
存储 Linux Android开发
RK3568 Android/Linux 系统动态更换 U-Boot/Kernel Logo
RK3568 Android/Linux 系统动态更换 U-Boot/Kernel Logo
18 0
|
3天前
|
Linux 开发工具 Android开发
Docker系列(1)安装Linux系统编译Android源码
Docker系列(1)安装Linux系统编译Android源码
6 0
|
4天前
|
Linux Shell Android开发
自动化脚本之GPIO/LED相关适用于Android/Linux
自动化脚本之GPIO/LED相关适用于Android/Linux
13 0
|
2月前
|
Ubuntu 网络协议 Linux
【Linux】Android平板上远程连接Ubuntu服务器code-server进行代码开发
【Linux】Android平板上远程连接Ubuntu服务器code-server进行代码开发
57 0
|
3月前
|
Linux 调度 Android开发
Kernel怎么跳转到Android:linux与安卓的交界
Kernel怎么跳转到Android:linux与安卓的交界
36 0
|
7月前
|
存储 Linux Android开发
会C/C++就可以开发Linux/Android应用程序?替代传统串口屏的Yoxios了解一下!
会C/C++就可以开发Linux/Android应用程序?替代传统串口屏的Yoxios了解一下!
144 0