1.层次分析-分析fbmem.c文件
1.1分析入口函数
(1)主设备号:FB_MAJOR;
(2)file_operations结构体:fb_fops;
(3)register_chrdev:
与之前分析的驱动程序完全一致!
static int __init
fbmem_init(void)
{
create_proc_read_entry("fb", 0, NULL, fbmem_read_proc, NULL);
if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
printk("unable to get major %d for fb devs\n", FB_MAJOR);
fb_class = class_create(THIS_MODULE, "graphics");
if (IS_ERR(fb_class)) {
printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));
fb_class = NULL;
}
return 0;
}
1.2分析open函数
1.假设app: open("/dev/fb0", …) 主设备号: 29, 次设备号: 0
kernel:根据以上主设备号和此设备号可以找到本驱动程序的open函数
fb_open(struct inode *inode, struct file *file)函数
int fbidx = iminor(inode);//找到设备节点的次设备号,这里fbidx=0
struct fb_info *info = = registered_fb[fbidx];//依据次设备号
static int fb_open(struct inode *inode, struct file *file)
{
int fbidx = iminor(inode);//找到设备节点的次设备号,这里fbidx=0
struct fb_info *info;
info = registered_fb[fbidx];//依据次设备号找到
if (info->fbops->fb_open) {
res = info->fbops->fb_open(info,1);
}
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
怎么写LCD驱动程序?
- 分配一个fb_info结构体: framebuffer_alloc
- 设置
- 注册: register_framebuffer
- 硬件相关的操作
2.LCD硬件相关操作
LCD硬件原理参见如下链接ARM–LCD控制原理笔记
- 配置引脚用于LCD
- 根据LCD手册设置LCD控制器;
- cpu初始化一块显存显存(FrameBuffer) ,建立 显存(FrameBuffer)和LCD控制器的关系
LCD控制器向LCD驱动器发出控制信号和显示的数据
LCD驱动器给显示面板发送模拟信号控制面板在何处显示什么颜色的点
3.编译调试
- 把内核中的LCD驱动修改为M
为了使得内核中的LCD驱动与自己编写的驱动不冲突,需要首先重新配置内核:
make menuconfig
make uImage
make modules #由于驱动程序中有三个函数需要ko文件支持
- 使用uboot通过网口重新加载内核
确认开发板uboot配置ip和主机ip是否处于同一网段
使用nfs命令下载uImage到nand指定地址0x30000000