嵌入式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");
相关推荐
dujunqiu2 小时前
S32K328(Arm Cortex-M7)适配CmBacktrace错误追踪
arm开发·驱动开发·单片机
提笔惊蚂蚁5 小时前
终端VS命令解释器(Linux & Windows)
linux·运维·windows
Nimsolax5 小时前
Linux文件fd
linux
tb_first6 小时前
k8sday13数据存储(1.5/2)
linux·运维·服务器·云原生·容器·kubernetes
逢生博客8 小时前
Ubuntu 安装 gvm 管理 Go 语言开发环境
linux·ubuntu·golang·gvm
多吃蔬菜!!!9 小时前
vscode 搭建C/C++开发环境搭建(linux)
linux·c语言·c++
李李李li9 小时前
Ubuntu 22.04 安装tensorrt
linux·tensorrt
phoenix098111 小时前
Linux入门DAY29
linux·运维
入秋11 小时前
Linux服务器安装部署 Nginx、Redis、PostgreSQL、Docker
linux·前端
Mr. Cao code12 小时前
使用Tomcat Clustering和Redis Session Manager实现Session共享
java·linux·运维·redis·缓存·tomcat