210学习日记(16)
--移植一线触摸
经过前面十多章的不懈努力,开发板从无到有的开发Linux驱动的环境已经搭建好(如果你问我,怎么没有写怎么制作文件系统,怎么nfs启动的话,我只能回答,视频里面讲得很详细了!),接下来肯定就是将二期中的所有驱动在210中给通通实现了。
二期里面讲的方法非常实用,内核里面的框架都是固定的,而这些框架,韦东山已经详细分析过,所以大家照着框架做(分配,设置,硬件相关,注册),就没有问题,到210开发板的时候,也只是修改硬件相关的东西而已。
我已经将二期驱动移植到Tiny210了(大多数也适合QT210,我以后会单独为QT210移植一次,因为这才是真正能学习东西的开发板)
下载地址:
http://115.com/folder/fc007y81#
http://dl.dbank.com/c06bbt0sxp
文件名:万勇_移植二期驱动到Tiny210开发板.zip
移植好了的驱动已经上传到上述网盘,第一次传的网卡驱动有一个小问题(由于个人的疏忽),我再次道歉,请大家参考第二次上传的驱动,和阅读第13章的类容进行移植。
杂项设备:(由于在移植一线触摸屏驱动的时候,会用到杂项设备,下面分析下它的框架)
分析\drivers\char\misc.c的实现过程:
static const struct file_operations misc_fops = { //分配设置一个file_operations结构体
.owner = THIS_MODULE,
.open = misc_open,
};
static int __init misc_init(void) //入口函数
{
misc_class = class_create(THIS_MODULE, "misc"); //创建类
if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) //注册一个主设备号为10的字符设备
}
subsys_initcall(misc_init); //申明misc_init()函数到子系统初始化集
问:从上面的分析过程可以发现,该子系统初始化程序完全符号写一般的字符驱动程序的步骤,那么应用程序是怎么对通过misc_register()注册的设备进行相应的读,写等操作的呢?
答:过程如下:
app: open() 应用程序使用open函数
-----------------------------------------------------------------------------------------------------------------------------------------
kernel:(内核最终会调用到misc.c中的file_operations结构体中的open函数)
问:当看上面的file_operations结构体的时候,发现里面只有一个open函数?那是怎么来实现 一系列的其他的操作的呢(读,写...)?
答:可以猜测出,一定是在这个open函数里面做了一些设置,然后在新的设置里面来进行相关的操作。
static int misc_open(struct inode * inode, struct file * file)
{
int minor = iminor(inode); //获得次设备号
list_for_each_entry(c, &misc_list, list) { //从misc_list链表中取出每一项(即miscdevice结构体)
if (c->minor == minor) { //通过次设备号进行匹配
new_fops = fops_get(c->fops); //如果次设备号一样,则获得该项的file_operations结构体成员 }
}
if (!new_fops) { //如果上述操作,获得file_operations结构体没有成功,则再次获取
list_for_each_entry(c, &misc_list, list) {...}
}
file->f_op = new_fops; //重新初始化struct file结构中的成员f_op,让它指向新的file_operations!
if (file->f_op->open) { //如果新获得的file_operations结构体有open函数
err=file->f_op->open(inode,file); //则调用他的open函数
}
}
问:从分析以上open函数时,发现会从misc_list链表中取出某一项来获取一个miscdevice结构体,进而获取他的成员fops(即新的file_operations结构体),从而构建出了一个新的file_operations结构体,那么上述misc_list链表是由谁来设置的呢?即链表中的成员miscdevice结构体又由谁来传入呢?
答:收索最终发现,它在misc_register函数中被设置:
int misc_register(struct miscdevice * misc)
{
misc->this_device = device_create(misc_class, misc->parent, dev, misc, "%s", misc->name); //建设备节点
list_add(&misc->list, &misc_list); //将传入的参数miscdevice结构体放入misc_list链表
}
Tiny210的硬件原理:
问:Tiny210一线触摸屏到底是什么?
答:友善的人自以为傲的核心技术,设计了一个一线精准触摸电路,并集成到LCD 的驱动板上,它采用触摸屏控制芯片ADS7843(或者相类似),配合一个ATC的单片机(该单片机里面固话了程序),构成一个独立的四线电阻触摸屏采集电路,最后通过一个普通的GPIO口把处理过的数据发送出去,在开发板上与之相连的是GPH1_2,实现单总线通信,这就是一线的来源。
说白了,就是ATC单片机通过SPI和ADS7843通信,控制ADS7843去读写触摸屏的数据,然后将数据存在单片机里面的RAM中,然后再通过单片机的一个GPIO发给ARM。
问:能够自己写出一线触摸的驱动吗?
答:能使肯定的,但是有些烦躁:
(1).在开发板的原理图上面,与GPH1_2相连接的LCD管脚上面用的net为"PWM",让人误以为是用PWM来通信(当然不可能,PWM是输出,无法读入数据);
(2).上面说了,触摸屏的数据会经单片机处理后,然后通过一个IO管脚发个ARM,但是该IO发出的数据的格式是什么样子的呢(即时序,几秒代表1,几秒代表0),由于友善把其视为核心技术,他们不向外提供固话在单片机中的程序(这个我能理解),但是他们也不提供IO发出的数据的时序,这很是冒火。但是大家可以去阅读他们提供的内核里面的触摸屏驱动,然后反推出时序是怎么样的。但是,我没有去弄了,我只是移植了。
(3).我不去弄明白它的时序到底是什么,因为太好精力了,而且没有任何实际的意义(我和专搞触摸屏的交流过),因为大家都用IIC(如电容屏,这得强烈推荐QT210开发板了,他们就是用的电容屏),SPI等通用接口通信,即使用自己的协议,也会对客户提供时序图的,可是友善的什么都没有,所以它的一线触摸屏无任何可用的价值。
当然,我希望大家出于好奇和好胜,有空的时候,能够攻下这个时序来,让友善所谓的核心技术见鬼去吧。
最后说说,友善的一线触摸驱动是怎么写的,它在入口函数中注册了一个内核定时器,用于查询方式去读取IO上面的"一帧"数据,然后再启用一个定时器3去解码这些数据,具体怎么解码,请大家参考我移植好了的驱动,然后攻破它吧。写出文档,记得共享到群共享去,发扬互学互助的精神!!!
注:
如有问题,请到韦东山LINUX视频讨论群里面,我们一起讨论学习,或者加我QQ:317312379