| 首页 | AVR单片机 | 8051单片机 | PIC单片机 | msp430应用 | motorola单片机 | C166单片机 | 开关电源 | 电源设计 | 电源技术应用 | 电磁兼容 |
| ARM芯片开发 | DSP开发技术 | PowerPC处理器 | RABBIT单片机 | 嵌入式系统设计 | 工业控制 | 控制电路 | PLC编程 | 机器人技术 | 电机原理 |
| vhdl语言学习 | asic芯片技术 | fpga培训 | cpld编程 | verilog hdl | Vxworks开发 | wince开发教程 | 嵌入式linux | uclinux开发 | ucos入门 |
| 电路设计 | 数字电路设计 | 模拟电路设计 | 音频电路设计 | 模拟滤波器设计 | 电子技术基础 | 电子名词解析 |
嵌入式系统中LCD驱动的实现原理
作者: 来源:51mcu
|
合三星公司ARM9系列嵌入式处理器S3C2410,讲解如何进行LCD驱动程序模块化编程及如何将驱动程序静态加载进系统内核。
其成员函数都在linux/driver/video/fbmem.c中定义,其中的函数对具体的硬件进行操作,对寄存器进行设置,对显示缓冲进行映射。主要结构体还有以下几个。 ● Struct fb_fix_screeninfo:记录了帧缓冲设备和指定显示模式的不可修改信息。它包含了屏幕缓冲区的物理地址和长度。 ● Struct fb_var_screeninfo:记录了帧缓冲设备和指定显示模式的可修改信息。它包括显示屏幕的分辨率、每个像素的比特数和一些时序变量。其中变量 xres定义了屏幕一行所占的像素数,yres定义了屏幕一列所占的像素数,bits_per_pixel定义了每个像素用多少个位来表示。 ● Struct fb_info:Linux为帧缓冲设备定义的驱动层接口。它不仅包含了底层函数,而且还有记录设备状态的数据。每个帧缓冲设备都与一个fb_info结构相对应。其中成员变量modename为设备名称,fontname为显示字体,fbops为指向底层操作的函数的指针。 LCD驱动开发的主要工作 1 编写初始化函数 初始化函数首先初始化LCD 控制器,通过写寄存器设置显示模式和颜色数,然后分配LCD显示缓冲区。在Linux中可以用kmalloc()函数分配一段连续的空间。缓冲区大小为:点阵行数×点阵列数×用于表示一个像素的比特数/8。缓冲区通常分配在大容量的片外SDRAM中,起始地址保存在LCD控制寄存器中。本文采用的LCD显示方式为640×480,16位彩色,则需要分配的显示缓冲区为640×480×2=600kb。最后是初始化一个fb_info结构,填充其中的成员变量,并调用register_framebuffer(&fb_info),将fb_info登记入内核。 2 编写成员函数 编写结构fb_info中函数指针fb_ops对应的成员函数,对于嵌入式系统的简单实现,只需要下列三个函数就可以了。 struct fb_ops{ …… int (*fb_get_fix)(struct fb_fix_screeninfo *fix, int con, struct fb_info *info); int (*fb_get_var)(struct fb_var_screeninfo *var, int con, struct fb_info *info); int (*fb_set_var)(struct fb_var_screeninfo *var, int con, struct fb_info *info); …… } Struct fb_ops在include/linux/fb.h中定义。这些函数都是用来设置/获取fb_info结构中的成员变量的。当应用程序对设备文件进行 ioctl操作时候会调用它们。对于fb_get_fix(),应用程序传入的是fb_fix_screeninfo结构,在函数中对其成员变量赋值,主要是smem_start(缓冲区起始地址)和smem_len(缓冲区长度),最终返回给应用程序。而fb_set_var()函数的传入参数是 fb_var_screeninfo,函数中需要对xres、yres和bits_per_pixel赋值。 对于/dev/fb,对显示设备的操作主要有以下几种。 ● 读/写(read/write)/dev/fb:相当于读/写屏幕缓冲区。 ● 映射(map)操作:由于Linux工作在保护模式,每个应用程序都有自己的虚拟地址空间,在应用程序中是不能直接访问物理缓冲区地址的。为此,Linux在文件操作 file_operations结构中提供了mmap函数,可将文件的内容映射到用户空间。对于帧缓冲设备,则可通过映射操作,可将屏幕缓冲区的物理地址映射到用户空间的一段虚拟地址中,之后用户就可以通过读写这段虚拟地址访问屏幕缓冲区,在屏幕上绘图了。 ● I/O控制:对于帧缓冲设备,对设备文件的ioctl操作可读取/设置显示设备及屏幕的参数,如分辨率、显示颜色数和屏幕大小等。ioctl的操作是由底层的驱动程序来完成的。在应用程序中,操作/dev/fb的一般步骤如下:打开/dev/fb设备文件;用ioctrl操作取得当前显示屏幕的参数,如屏幕分辨率和每个像素的比特数,根据屏幕参数可计算屏幕缓冲区的大小;将屏幕缓冲区映射到用户空间;映射后即可直接读写屏幕缓冲区,进行绘图和图片显示了。 LCD模块化驱动 在对S3C2410 的LCD编写模块化驱动程序时,首先要从内核中去除LCD驱动。这里需要做一些改动,系统调用被加在以下文件中,需去除: /root/usr/src/arm/linux/kernel/sys.c;/root/usr/src/arm/linux/include/arm -arm下的unistd.h和lcd.h;/root/usr/src/arm/linux/arch/arm/kernel下的calls.s。 编写模块化驱动程序,有以下几个关键的函数。 ● lcd_kernel_init(void)//当模块被载入时执行 ● lcd_kernel_exit(void)//当模块被移出内核空间时被执行 ● lcd_kernel1_ioctl(struct*inode, struct*file, unsigned int cmd, unsigned longarg) //其他功能 每当装配设备驱动程序时,系统自动调用初始化模块lcd_kernel_init(void)。 另一个必须提供的函数是lcd_kernel_exit(void),它在模块被卸载时调用,负责进行设备驱动程序的工作。 执行insmod lcd.o命令即可将LCD驱动添加到内核中,执行rmmod lcd命令即可从内核中删除LCD驱动。 静态加载LCD驱动 将写好的lcd 驱动程序lcd.c放到arm/linux/drivers/char目录下,修改arm/linux/drivers/char/config.in文件,加上一行:Bool'LCD driver support'CONFIG_LCD;修改arm/linux/drivers/char/Makefile文件,加上一行:obj-$ (CONFIG_LCD)+=lcd.o。 这样,当再进行make xconfig时,就会选择是否将LCD驱动编译进内核。同样的办法也可用在其他设备上。 |
|
网站地图 | 联系我们 | 免责声明 | 招聘信息 | 友情链接 Copyright © 2005 - 2006 单片机设计网 |