嵌入式Linux驱动开发(LCD屏幕专题)(一)

一、LCD简介

总的分辨率是 yres*xres。

1.1、像素颜色的表示

以下三种方式表示颜色

1.2、如何将颜色数据发送给屏幕

每个屏幕都有一个内存(framebuffer)如下图,内存中每块数据对用屏幕上的一个像素点,设置好LCD后,只需把颜色数据写入framebuffer即可。

二、Framebuffer驱动框架

Framebuffer驱动属于字符设备驱动,我们先说字符设备驱动框架如下图:

  • 驱动主设备号
  • 构造file_operations结构体,填充open/read/write等成员函数
  • 注册驱动:register_chrdev(major, name, &fops)
  • 入口函数
  • 出口函数

2.1、Framebuffer驱动程序框架

分为上下两层:

  • fbmem.c:承上启下
    • 实现、注册file_operations结构体
    • 把APP的调用向下转发到具体的硬件驱动程序
    • 应用程序调用到open、read等函数时转到xxx_fb.c
  • xxx_fb.c:硬件相关的驱动程序
    • 实现、注册fb_info结构体
    • 实现硬件操作

2.2、编写Framebuffer驱动

核心就是fb_info结构体

  • 分配fb_info

    • framebuffer_alloc
  • 设置fb_info

    • var
    • fbops
    • 硬件相关操作
  • 注册fb_info

    • register_framebuffer

三、编写LCD驱动框架

参考内核代码

powershell 复制代码
drivers\video\fbdev\s3c2410fb.c

注:工作中LCD驱动我们不用从头写,会改就行。

步骤如下:

1、分配fb_info

2、设置fb_info

要设置哪些内容?根据APP的需求来。

3、注册fb_info

c 复制代码
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/io.h>
#include <asm/div64.h>
#include <asm/mach/map.h>
#include <mach/regs-lcd.h>
#include <mach/regs-gpio.h>
#include <mach/fb.h>

static struct fb_info *myfb_info;

static struct fb_ops myfb_ops = {
	.owner		= THIS_MODULE,
	.fb_fillrect	= cfb_fillrect,
	.fb_copyarea	= cfb_copyarea,
	.fb_imageblit	= cfb_imageblit,
};

/* 1. 入口 */
int __init lcd_drv_init(void)
{
	dma_addr_t phy_addr;
	/* 1.1 分配fb_info */
	myfb_info = framebuffer_alloc(0, NULL);
	/* 1.2 设置fb_info */
	/* a. var : LCD分辨率、颜色格式 */
	myfb_info->var.xres = 1024;			//屏幕x像素点个数
	myfb_info->var.yres = 600;			//y像素点个数
	myfb_info->var.bits_per_pixel = 16;  /* rgb565 */
	myfb_info->var.red.offset = 11;		
	myfb_info->var.red.length = 5;
	myfb_info->var.green.offset = 5;
	myfb_info->var.green.length = 6;
	myfb_info->var.blue.offset = 0;
	myfb_info->var.blue.length = 5;
	
	/* b. fix */
	myfb_info->fix.smem_len = myfb_info->var.xres * myfb_info->var.yres * myfb_info->var.bits_per_pixel / 8;	
	if (myfb_info->var.bits_per_pixel == 24)		//如果采用3个字节为颜色像素需要乘4,
		myfb_info->fix.smem_len = myfb_info->var.xres * myfb_info->var.yres * 4;


	/* fb的虚拟地址 */
	myfb_info->screen_base = dma_alloc_wc(NULL, myfb_info->fix.smem_len, &phy_addr,GFP_KERNEL);
	myfb_info->fix.smem_start = phy_addr;  /* fb的物理地址 */
	myfb_info->fix.type = FB_TYPE_PACKED_PIXELS;
	myfb_info->fix.visual = FB_VISUAL_TRUECOLOR;
	
	/* c. fbops */
	myfb_info->fbops = &myfb_ops;

	/* 1.3 注册fb_info */
	register_framebuffer(myfb_info);

	/* 1.4 硬件操作 */
	
	return 0;
}

/* 2. 出口 */
static void __exit lcd_drv_exit(void)
{
	/* 反过来操作 */
	/* 2.1 反注册fb_info */
	unregister_framebuffer(myfb_info);
	
	/* 2.2 释放fb_info */
	framebuffer_release(myfb_info);
}

module_init(lcd_drv_init);
module_exit(lcd_drv_exit);
MODULE_LICENSE("GPL");
相关推荐
Murphy_lx15 分钟前
Linux系统--信号(4--信号捕捉、信号递达)陌生概念篇
linux·运维·服务器
焱焱枫1 小时前
Linux疑难杂症诊断利器:深入解析 fuser 命令
linux·运维·服务器
博语小屋1 小时前
Linux进程信号(壹)_产生信号
linux·运维·服务器
轻松Ai享生活1 小时前
【Linux】VFS 虚拟文件系统 详解
linux
LCG元1 小时前
Linux环境Python生态速建指南:包管理+虚拟隔离+深度调优
linux
大白的编程日记.2 小时前
【Linux学习笔记】线程同步与互斥之生产者消费者模型
linux·笔记·学习
Knight_AL2 小时前
Spring Boot 中使用自定义注解和 AOP 实现微服务日志记录(包含 URL、状态码和耗时信息)
linux·spring boot·微服务
养海绵宝宝的小蜗2 小时前
Linux 例行性工作任务(定时任务)知识点总结
linux·运维·服务器
乌萨奇也要立志学C++2 小时前
【Linux】基础IO(二)深入理解“一切皆文件” 与缓冲区机制:从原理到简易 libc 实现
linux·运维·服务器
Ronin3052 小时前
【Linux网络】封装Socket
linux·网络·socket·网络通信