fb : framebuffer 帧缓冲区,存放一帧图像的地址
LCD驱动程序
Fbmem.c (抽象出来的框架驱动程序,并不支持具体的驱动,需要依赖于底层的驱动程序 给他注册一个fb_info结构体才行)
假设
app: open("/dev/fb0", ...) 主设备号: 29, 次设备号: 0
--------------------------------------------------------------
kernel:
fb_open
int fbidx = iminor(inode);
struct fb_info *info = = registered_fb[0];
app: read()
---------------------------------------------------------------
kernel:
fb_read
int fbidx = iminor(inode);
struct fb_info *info = registered_fb[fbidx];
if (info->fbops->fb_read)
return info->fbops->fb_read(info, buf, count, ppos);
src = (u32 __iomem *) (info->screen_base + p);
dst = buffer;
*dst++ = fb_readl(src++);
copy_to_user(buf, buffer, c)
问1. registered_fb在哪里被设置?
答1. register_framebuffer
s3c2410fb.c (硬件相关 设置,平台驱动)
怎么写LCD驱动程序?
1. 分配一个fb_info结构体: framebuffer_alloc(size_t size,struct device *dev)
static struct fb_info *s3c_lcd;
s3c_lcd = framebuffer_alloc(0,NULL); //这个结构体s3c_lcd的大小已经定死了,为什么还要提供一个大小?
//这个大小是除了fb_info之外的额外大小,用于存放私有数据;而且fb_info结构体还有个指针指向这个额外的空间
2. 设置 :fb_info结构体
/* 2.1 设置固定的参数 */
/* 2.2 设置可变的参数 */
/* 2.3 设置操作函数 */
/* 2.4 其他的设置 */
3. 硬件相关的操作
(1)、根据lcd手册设置lcd控制器
(2)、分配显存(喷嘴从数据线上得到颜色,而颜色就是从显存上得到的),并把显存地址告诉lcd控制器
(3)、配置引脚用于lcd
4. 注册: register_framebuffer
测试:
1. make menuconfig去掉原来的驱动程序
-> Device Drivers
-> Graphics support
<M> S3C2410 LCD framebuffer support //编译成模块,不编译进内核
2. make uImage
//编译成镜像文件 .bin
make modules
//编译成模块 .ko
3. 使用新的uImage启动开发板:
4.
insmod cfbcopyarea.ko
insmod cfbfillrect.ko
insmod cfbimgblt.ko
insmod lcd.ko
//为什么要加载cfbcopyarea.ko 、cfbfillrect.ko 、cfbimgblt.ko ?
因为cfbcopyarea.ko 、cfbfillrect.ko 、cfbimgblt.ko 对应于3个 .c文件,这3个操作函数cfb_fillrect、cfb_copyarea、cfb_imageblit 是在这 3个 .c文件里定义的。
static struct fb_ops s3c_lcdfb_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = s3c_lcdfb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
};
echo hello > /dev/tty1 // 可以在LCD上看见hello
cat lcd.ko > /dev/fb0 // 花屏 (fb : frame buffer)把lcd.ko里面的内容放在显存里面去
5. 修改 /etc/inittab
tty1::askfirst:-/bin/sh //dev/tty1就对应于我们的键盘 ,输出的时候就对应于我们的lcd
用新内核重启开发板
s3c2410_serial0::askfirst:-/bin/sh // 启动的sh程序从串口0上得到数据,把这数据,输出到串口0上
insmod cfbcopyarea.ko
insmod cfbfillrect.ko
insmod cfbimgblt.ko
insmod lcd.ko
insmod buttons.ko //输入子系统的按键驱动