Android(Linux)线路规程的使用-阿里云开发者社区

开发者社区> helpful> 正文

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的驱动架构实在是牛!

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
怎么设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程
7005 0
Linux下使用两个线程协作完成一个任务的简易实现
刚解决了之前的那个Linux下Pthread库的问题,这次就来使用两个线程来协作,共同完成一个求和的任务。 打一下基础吧 本次需要使用到的知识点有: lpthread,编译的时候用到,相当于一个声明的效果 pthread_mutex_t 作为一个锁对象而存在 pth...
856 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
7830 0
Visual c++例子,可不使用常规的对话框资源模板的情况下,动态创建对话框的方法
详细说明:Visual c++例子,可不使用常规的对话框资源模板的情况下,动态创建对话框的方法。该方法可以在运行时在内存中直接建立对话框资源,使用起来更为灵活。适用于多个开发项目共享有界面的公用程序模块的情况,也适用于编写需要显示大量对话框或对话框风格随着用户输入不断变化的应用程序。
753 0
面试题:使用递归的方法计算1到100的累加。
今天去面试,遇到这道题目,有段时间没写程序了,温习一下: 题目是使用递归的方法计算1到100的累加,也就是计算1+2+3+4+........+100。大家想必已经听说过高斯如何计算这道题的故事,也知道答案是5050。
936 0
+关注
helpful
长期从事嵌入式软件开发,包括µC/OS 、WinCE、Linux和Android等。
216
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载