嵌入式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");
相关推荐
孞㐑¥1 小时前
Linux之Socket 编程 UDP
linux·服务器·c++·经验分享·笔记·网络协议·udp
M4K05 小时前
Linux百度网盘优化三板斧
linux
好奇的菜鸟5 小时前
如何在 Ubuntu 24.04 (Noble) 上使用阿里源
linux·运维·ubuntu
bcbobo21cn5 小时前
初步了解Linux etc/profile文件
linux·运维·服务器·shell·profile
望获linux6 小时前
【实时Linux实战系列】CPU 隔离与屏蔽技术
java·linux·运维·服务器·操作系统·开源软件·嵌入式软件
0wioiw06 小时前
C#基础(项目结构和编译运行)
linux·运维·服务器
2401_873587827 小时前
Linux常见指令以及权限理解
linux·运维·服务器
Arthurmoo7 小时前
Linux系统之MySQL数据库基础
linux·数据库·mysql
李洋-蛟龙腾飞公司8 小时前
HarmonyOS NEXT应用元服务常见列表操作分组吸顶场景
linux·运维·windows
链上Sniper8 小时前
智能合约状态快照技术:实现 EVM 状态的快速同步与回滚
java·大数据·linux·运维·web3·区块链·智能合约