linux设备驱动归纳总结(十二):简单的数码相框【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-116926.html
linux设备驱动归纳总结(十二):简单的数码相框
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
其实代码很简单,实现lcd驱动,使lcd能够显示图片,当按下按键后切换图片。
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
先要说明一下几处地方:
1、代码中显示的图片都是*.bin文件(显示模式是使用16位数据来表示一个像素的颜色——5:6:5),将jpg文件转为*.bin文件的工具在我上传的mkimage目录中。转换图片的尺寸在fb.h中指定,我的图片是480*272,所以:
#define X 480
#define Y 272
转换的命令也很简单:
./mkimage src_file dis_file
源代码都上传了,自己摸索,源码面前没有秘密。
mkimage.rar
2、我的lcd是480*272,即使是同样的尺寸的lcd,因为接线的不一样,我也不能保证能够驱动成功。但是,显示器的不同也只需要修改lcd配置函数就可以了。
接下来介绍一下我编写时的顺序。
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
一、实现lcd的基本操作:12th_lcd/1st
代码具体做了以下几件事:
1、定义了一个结构体:struct _lcd_t
2、实现了lcd即基本操作,包括:
配置lcd:s3c_lcd_config(struct _lcd_t *lcd)
启动lcd:s3c_lcd_enabe(struct _lcd_t *lcd)
关闭lcd:s3c_lcd_disable(struct _lcd_t *lcd)
3、封装了lcd设备的初始化和注销函数:
init_lcd_device(struct _lcd_t *lcd)
destory_lcd_device(struct _lcd_t *lcd)
其中有一个我在之前的总结中没有介绍的知识点——DMA编程,简单的理解就会调用一个函数,函数给你返回两个地址,一个是虚拟地址,一个是对应的物理地址。只要你的程序往虚拟地址中读写数据,实际就会往物理地址写数据。主要的特点就是:数据的传输不需要经过处理器,而是2440中的DMA负责传输。具体的以后有机会再补充。
其实就是一个函数:
void *dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
注意:如果显示屏不一样的话,就要修改s3c_lcd_config里面的代码。
装载模块时,会调用test_lcd函数测试是否成功,该函数会让屏幕全红。
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
二、实现字符型设备:12th_lcd/2nd
第二个代码在原来的基础上注册了杂设备,并且实现了write操作,当在应用层将图片数据写到设备文件/dev/test_lcd中,就会将图片显示出来。
大致知识点:
·linux设备驱动归纳总结(三):2open.close.read.write
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
三、实现图片切换:12th_lcd/3rd
第三个代码要实现的功能是:当按键按下时,应用层切换新的图片传给lcd。
这里要添加两个东西:
1、添加中断,当按键按下时执行中断处理函数。
2、添加字符设备的异步通知机制,在中断处理函数发送信号到应用层,应用程序接到信号后更换图片。
大致知识点:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
四、实现按键去抖:12th_lcd/4th
在上面的程序,如果硬件本身不好的话,按下一次的按键可能产生多次的中断,所以按键去抖很有必要。实现很简单,就是添加一个定时器。
大致知识点:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
五、实现静态平台类驱动:12th_lcd/5th
其实就是在原来的程序上加上平台类驱动的注册,然后修改3处的内核代码:
1、arch/arm/mach-s3c2440/mach-mini2440.c
250 static struct platform_device *mini2440_devices[] __initdata = {
251 &s3c_device_usb,
252 &s3c_device_rtc,
253 &s3c_device_lcd,
254 &s3c_device_wdt,
255 &s3c_device_led,
256 &s3c_device_wdt_xb,
257 &s3c_device_lcd_xb, //这是新添加的
258 &s3c_device_i2c0,
259 &s3c_device_iis,
260 &s3c_device_dm9k,
261 &net_device_cs8900,
262 &s3c24xx_uda134x,
263 };
2、arch/arm/plat-s3c24xx/devs.c
405 static struct resource s3c_lcd_xb_resource[] = {
406 [0] = {
407 .start = 0x4d000000,
408 .end = 0x4d0000ff,
409 .flags = IORESOURCE_MEM,
410 },
411 [1] = {
412 .start = 0x56000000,
413 .end = 0x560000ff,
414 .flags = IORESOURCE_MEM,
415 },
416 [2] = {
417 .start = IRQ_EINT1,
418 .end = IRQ_EINT1,
419 .flags = IORESOURCE_IRQ,
420 }
421 };
422
423 struct platform_device s3c_device_lcd_xb = {
424 .name = "s3c_lcd_xb",
425 .id = -1,
426 .num_resources = ARRAY_SIZE(s3c_lcd_xb_resource),
427 .resource = s3c_lcd_xb_resource,
428 };
429
430 EXPORT_SYMBOL(s3c_device_lcd_xb);
3、arch/arm/plat-s3c/include/plat/devs.h
5 extern struct platform_device s3c_device_lcd_xb;
大致知识点:
·linux设备驱动归纳总结(九):1.platform设备驱动
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
六、实现字符设备操作mmap:12th_lcd/6th
这个知识点我还没总结,大体上就是在应用程序中调用mmap,驱动就会把一块实际的内存地址映射到应用层,并返回一个地址给用户操作。
具体就是在字符设备中添加mmap操作。详细请看代码,我就不详细介绍了,可以看《LDD3》P418。
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
七、为驱动添加信号量:12th_lcd/7th
其实这一步在这里可以说是多于的,在非抢占单处理器的情况下根本不需要添加防止并发和竞态的机制,我这里也只是仅仅加上,当是复习。
大致知识点:
·linux设备驱动归纳总结(四):5.SMP下的竞态和并发
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
八、完善代码:12th_lcd_8th
之前为了代码看起来短小一点,我没有在代码中添加错误操作,如申请中断号失败时的操作。这里稍稍修改了一下,添加了一下错误检查的代码。
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
linux设备驱动归纳总结(十二):简单的数码相框【转】的更多相关文章
- linux设备驱动归纳总结(二):模块的相关基础概念【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-59415.html linux设备驱动归纳总结(二):模块的相关基础概念 系统平台:Ubuntu 10 ...
- 【Linux开发】linux设备驱动归纳总结(二):模块的相关基础概念
linux设备驱动归纳总结(二):模块的相关基础概念 系统平台:Ubuntu 10.04 开发平台:S3C2440开发板 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- linux设备驱动归纳总结
前言: (总结已经基本写完,这段时间我会从新排版和修正.错误总会有的,望能指正!) 前段时间学习了嵌入式驱动,趁着没开始找工作,这段时间我会每天抽出时间来复习. 我的总结是根据学习时的笔记(李杨老师授 ...
- 【Linux】linux设备驱动归纳总结
前言: (总结已经基本写完,这段时间我会从新排版和修正.错误总会有的,望能指正!) 前段时间学习了嵌入式驱动,趁着没开始找工作,这段时间我会每天抽出时间来复习. 我的总结是根据学习时的笔记(李杨老师授 ...
- 【Linux开发】linux设备驱动归纳总结(十二):简单的数码相框
linux设备驱动归纳总结(十二):简单的数码相框 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- linux设备驱动归纳总结(十一):写个简单的看门狗驱动【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-112879.html linux设备驱动归纳总结(十一):写个简单的看门狗驱动 xxxxxxxxxxx ...
- linux设备驱动归纳总结(十):1.udev&misc【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-111839.html linux设备驱动归纳总结(十):1.udev&misc xxxxxxx ...
- 【Linux开发】linux设备驱动归纳总结(十):1.udev&misc
linux设备驱动归纳总结(十):1.udev&misc xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- 【Linux开发】linux设备驱动归纳总结(十一):写个简单的看门狗驱动
linux设备驱动归纳总结(十一):写个简单的看门狗驱动 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
随机推荐
- Ubuntu下面安装eclipse for c++
1.下载jdk,cdt,eclipse. 其中jdk是java运行环境,eclipse需要先装jre,才可能运行,cdt是在eclipse中运行c\c++程序的插件.jdk安装见上文. 2.eclip ...
- 好网站:字体转换器在线转换 http://www.diyiziti.com/
偶然间发现这个网站,它可以将文字设置字体并做成图片,也有很多好的字体下载如瘦金体. 下载下来的ttf文件在win7里可以右键点击install,在vista和xp里可以直接拷贝到window\font ...
- http://www.cnblogs.com/littlemonk/p/5705476.html
http://www.cnblogs.com/littlemonk/p/5705476.html
- github上所有大于800 star OC框架
https://github.com/XCGit/awesome-objc-frameworks#awesome-objc-frameworks awesome-objc-frameworks ID ...
- SpringMVC中的controller默认是单例的原因
http://lavasoft.blog.51cto.com/62575/1394669/ 1.性能 :单例不用每次new浪费资源时间. 2.不需要:一般controller中不会定义属性这样单例就不 ...
- storm安装
官方安装地址:http://storm.apache.org/releases/1.0.2/Setting-up-a-Storm-cluster.html storm集群的三个角色 Nimbus.Su ...
- 如何调试DLL组件
因为DLL组件不像EXE是程序的入口,所以DLL需要其他进程的调用才能调试. 1.首先在DLL项目中你想调试的位置打好断点. 2.如果已经有一个进程,比如foo.exe已经启动,那么就用:调试> ...
- 成员变量的隐藏,方法的覆盖,super关键字
成员变量的隐藏:当父类和子类有相同的成员变量时,即定义了与父类相同的成员变量时,就会发生子类对父类变量的隐藏.对于子类的对象来说,父类中的同名成员变量被隐藏起来,子类就会优先使用自己的成员变量,父类成 ...
- JAVA多线程与多进程
并发与并行是两个既相似而又不相同的概念,但往往容易混为一谈,这两者究竟有什么区别呢?本文通过一个例子让你更好地理解(本文由并发编程网翻译). 现代社会是并行的:多核.网络.云计算.用户负载,并发技术对 ...
- nyist 506 洗澡
http://acm.nyist.net/JudgeOnline/problem.php?pid=506 洗澡 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 Mos ...