Writing Linux LCD drivers—深入分析framebuffer设备驱动的结构

【Linux驱动】framebuffer设备驱动 framebuffer驱动学了好久了,今天进行一下复盘。 关于framebuffer是什么,怎么用,网上都有很多的博客介绍。这里还是聚焦于分析framebuffer的驱动框架以及设备驱动代码。 framebuffer的驱动框架在kernel/drivers/video/fbmem.c文件中,该文件是以模块的形式写的,所以从后往前看。 #ifdef MODULE module_init(fbmem_init); static void __exit fbmem_exit(void) { remove_pro 阅读详情

来源:http://www.hzlitai.com.cn/article/yejin-article/system/1161.html

 

Writing Linux LCD drivers

——本文深入地分析了framebuffer设备驱动的结构

作者:JimSheng

Writing Linux LCD drivers
Abstract
1 LCD Module/Driver/Controller
2 Linux Frame Buffer Driver
2.1 Why Frame Buffer?
2.2 What is Frame Buffer Devices?
2.3 How to Write Frame Buffer Device Drivers?
3 Analysis of Linux Frame Buffer Driver Source Codes
3.1 fb.h
3.2 fbmem.c
4 Skeleton of LCD controller rivers
4.1 Allocate a system memory as video memory
4.2 Implement the fb_ops functions
Reference

Abstract
This material discusses how to write a Linux frame buffer LCD device driver.

1 LCD Module/Driver/Controller

Besides the datasheet of LCD devices, there are two quite good books (.pdf format) on LCD technology. Both of them are written in Chinese. One is “液晶显示技术”, and the other is “液晶显示器件”. The two books give almost all needed LCD knowledge, including introductions to hardware implementation of LCD devices and low level software programming used to operate LCD devices. This helps LCD circuits design and low level LCD programming.

2 Linux Frame Buffer Driver

2.1 Why Frame Buffer?
If GUIs (Graphic User Interface) such as MiniGUI, MicroWindows are used, LCD device drivers must be implemented as Linux frame buffer device drivers in addition to those low level operations which only deal with commands provided by LCD controllers.

2.2 What is Frame Buffer Devices?
The frame buffer device provides an abstraction for the graphics hardware. It represents the frame buffer of some video hardware and allows application software to access the graphics hardware through a well-defined interface, so the software doesn't need to know anything about the low-level (hardware register) stuff.
The device is accessed through special device nodes, usually located in the /dev directory, i.e. /dev/fb*.
More description about frame buffer device can be found in two txt files: linux /Documentation /fb /framebuffer.txt and linux /Documentation /fb /interal.txt

2.3 How to Write Frame Buffer Device Drivers?
There are few instructive materials about writing frame buffer device drivers. You may find “Linux Frame buffer Driver Writing HOWTO” at this web page http: /linux-fbdev.sourceforge.net /HOWTO /index.html, but the HOWTO is somewhat curt and not enough. So having a look into Linux source codes is necessary. The next section is an analysis of the related source codes.

3 Analysis of Linux Frame Buffer Driver Source Codes

Linux implements Frame Buffer Drivers mainly based on the groundwork of these two files:
1) linux/include/linux/fb.h
2) linux/drivers/video/fbmem.c
It’s time to have a close look at them.

3.1 fb.h
Almost all important structures are defined in this file. First let me describe what each means and how they are used one by one.


1) fb_var_screeninfo
It is used to describe the features of a video card you normally can set. With fb_var_screeninfo, you can define such things as depth and the resolution you want.

struct fb_var_screeninfo {
__u32 xres; /* visible resolution */
__u32 yres;
__u32 xres_virtual; /* virtual resolution */
__u32 yres_virtual;
__u32 xoffset; /* offset from virtual to visible */
__u32 yoffset; /* resolution */

__u32 bits_per_pixel; /* guess what */
__u32 grayscale; /* != 0 Graylevels instead of colors */

struct fb_bitfield red; /* bitfield in fb mem if true color, */
struct fb_bitfield green; /* else only length is significant */
struct fb_bitfield blue;
struct fb_bitfield transp; /* transparency */

__u32 nonstd; /* != 0 Non standard pixel format */

__u32 activate; /* see FB_ACTIVATE_* */

__u32 height; /* height of picture in mm */
__u32 width; /* width of picture in mm */

__u32 accel_flags; /* acceleration flags (hints) */

/* Timing: All values in pixclocks, except pixclock (of course) */
__u32 pixclock; /* pixel clock in ps (pico seconds) */
__u32 left_margin; /* time from sync to picture */
__u32 right_margin; /* time from picture to sync */
__u32 upper_margin; /* time from sync to picture */
__u32 lower_margin;
__u32 hsync_len; /* length of horizontal sync */
__u32 vsync_len; /* length of vertical sync */
__u32 sync; /* see FB_SYNC_* */
__u32 vmode; /* see FB_VMODE_* */
__u32 reserved[6]; /* Reserved for future compatibility */
};

2) fb_fix_screeninfon
It defines the properties of a card that are created when you set a mode and can't be changed otherwise. A good example is the start address of the framebuffer memory. This can depend on what mode is set. Now while using that mode, you don't want to have the memory position change on you. In this case, the video hardware tells you the memory location and you have no say about it.

struct fb_fix_screeninfo {
char id[16]; /* identification string eg "TT Builtin" */
unsigned long smem_start; /* Start of frame buffer mem */
/* (physical address) */
__u32 smem_len; /* Length of frame buffer mem */
__u32 type; /* see FB_TYPE_* */
__u32 type_aux; /* Interleave for interleaved Planes */
__u32 visual; /* see FB_VISUAL_* */
__u16 xpanstep; /* zero if no hardware panning */
__u16 ypanstep; /* zero if no hardware panning */
__u16 ywrapstep; /* zero if no hardware ywrap */
__u32 line_length; /* length of a line in bytes */
unsigned long mmio_start; /* Start of Memory Mapped I/O */
/* (physical address) */
__u32 mmio_len; /* Length of Memory Mapped I/O */
__u32 accel; /* Type of acceleration available */
__u16 reserved[3]; /* Reserved for future compatibility */
};

3) fb_cmap
Device independent colormap information. You can get and set the colormap using the FBIOGETCMAP and FBIOPUTCMAP ioctls.

struct fb_cmap {
__u32 start; /* First entry */
__u32 len; /* Number of entries */
__u16 *red; /* Red values */
__u16 *green;
__u16 *blue;
__u16 *transp; /* transparency, can be NULL */
};

4) fb_info
It defines the current state of the video card. fb_info is only visible from the kernel. Inside of fb_info, there exist a fb_ops which is a collection of needed functions to make driver work.

struct fb_info {
char modename[40]; /* default video mode */
kdev_t node;
int flags;
int open; /* Has this been open already ? */
#define FBINFO_FLAG_MODULE 1 /* Low-level driver is a module */
struct fb_var_screeninfo var; /* Current var */
struct fb_fix_screeninfo fix; /* Current fix */
struct fb_monspecs monspecs; /* Current Monitor specs */
struct fb_cmap cmap; /* Current cmap */
struct fb_ops *fbops;
char *screen_base; /* Virtual address */
struct display *disp; /* initial display variable */
struct vc_data *display_fg; /* Console visible on this display */
char fontname[40]; /* default font name */
devfs_handle_t devfs_handle; /* Devfs handle for new name */
devfs_handle_t devfs_lhandle; /* Devfs handle for compat. symlink */
int (*changevar)(int); /* tell console var has changed */
int (*switch_con)(int, struct fb_info*);
/* tell fb to switch consoles */
int (*updatevar)(int, struct fb_info*);
/* tell fb to update the vars */
void (*blank)(int, struct fb_info*); /* tell fb to (un)blank the screen */
/* arg = 0: unblank */
/* arg > 0: VESA level (arg-1) */
void *pseudo_palette; /* Fake palette of 16 colors and
the cursor's color for non
palette mode */
/* From here on everything is device dependent */
void *par;
};

5) struct fb_ops
User application program can use ioctl() system call to operate low LCD hardware. Methods defined in fb_ops structure are used to support these operations.

struct fb_ops {
/* open/release and usage marking */
struct module *owner;
int (*fb_open)(struct fb_info *info, int user);
int (*fb_release)(struct fb_info *info, int user);
/* get non settable parameters */
int (*fb_get_fix)(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
/* get settable parameters */
int (*fb_get_var)(struct fb_var_screeninfo *var, int con,
struct fb_info *info);
/* set settable parameters */
int (*fb_set_var)(struct fb_var_screeninfo *var, int con,
struct fb_info *info);
/* get colormap */
int (*fb_get_cmap)(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
/* set colormap */
int (*fb_set_cmap)(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
/* pan display (optional) */
int (*fb_pan_display)(struct fb_var_screeninfo *var, int con,
struct fb_info *info);
/* perform fb specific ioctl (optional) */
int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg, int con, struct fb_info *info);
/* perform fb specific mmap */
int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
/* switch to/from raster image mode */
int (*fb_rasterimg)(struct fb_info *info, int start);
};

6) structure map
struct fb_info_gen | struct fb_info | fb_var_screeninfo
| | fb_fix_screeninfo
| | fb_cmap
| | modename[40]
| | fb_ops ---|--->ops on var
| | ... | fb_open
| | | fb_release
| | | fb_ioctl
| | | fb_mmap
| struct fbgen_hwswitch -|-> detect
| | encode_fix
| | encode_var
| | decode_fix
| | decode_var
| | get_var
| | set_var
| | getcolreg
| | setcolreg
| | pan_display
| | blank
| | set_disp

[编排有点困难,第一行的第一条竖线和下面的第一列竖线对齐,第一行的第二条竖线和下面的第二列竖线对齐就可以了]
struct fbgen_hwswitch is an abstraction of hardware operations. It is not necessary, but sometimes useful.

3.2 fbmem.c
fbmem.c is at the middle place of frame buffer driver architecture. It provides system calls to support upper user application programs. It also provides an interface to low level drivers for specific hardware. Those low level frame buffer drivers can register themselves into the kernel by this interface. fbmem.c implements the common codes used by all drivers, thus avoids repeated work.

1) Global Varibles

struct fb_info *registered_fb[FB_MAX];
int num_registered_fb;

The two are used to record on-using instance of fb_info structure. fb_info represents the current state of video card. All fb_info structures are globally placed in an array. When a frame buffer registers itself to kernel, a new fb_info is added to this array and num_registered_fb increases 1.

static struct {
const char *name;
int (*init)(void);
int (*setup)(void);
} fb_drivers[] __initdata= { ....};

If frame buffer driver is static linked into kernel, a new entry must be added to this table. If use insmod/rmmod, don’t care this.

static struct file_operations fb_ops ={
owner: THIS_MODULE,
read: fb_read,
write: fb_write,
ioctl: fb_ioctl,
mmap: fb_mmap,
open: fb_open,
release: fb_release
};

This is the interface to user application programs. fbmem.c implements these functions here.

2) register_framebuffer(struct fb_info *fb_info)
unregister_framebuffer(struct fb_info *fb_info)

This is the interface to low level frame buffer device driver. The drivers use this pair of functions to register or unregister themselves.
Almost all the work those low level drivers needed to do is to fill in an fb_info structure and then to (un)register it.

4 Skeleton of LCD controller rivers
LCD drivers operate LCD device hardwares, while fbmem.c records and administrates these drivers. There is a skeleton frame buffer driver in linux /drivers /fb /skeleton.c. It shows how to implement a frame buffer driver with very few codes. Because it is too simple, it does nothing but filling an fb_info and then (un)registering it.
In order to implement a usable LCD controller driver, something else must be added into it. But what should be added? As we all know, device drivers abstract hardware and provide system call interface to user programs. So we can implements the low level hardware operations according to the need of the system call interface, namely the file_operations structure which is discussed in section 3.2.

4.1 Allocate a system memory as video memory
After a careful lookup in fbmem.c, we know that open() and release() method of file_operations structure do not need low level support, while read(), write() and mmap() need a common support function fb_get_fix(). So fb_get_fix() must be provided by driver writers.
Additionally the writer should allocate a system memory as video memory, for most LCD controllers have no their own video memory. The allocated memory start address and length are later placed in smem_start and smem_len fields of fb_fix_screeninfo structure. The allocated memory should be physically consecutive.

4.2 Implement the fb_ops functions
The only method of file_operations still not discussed is ioctl(). User application programs use ioctl() system call to operate LCD hardware. Methods defined in fb_ops structure(section 3.1) are used to support these operations. NOTE: fb_ops structure is NOT file_operations structure. fb_ops is for abstraction of low level operations, while file_operations is for upper level system call interface
Again we’d better first decide which methods should be implemented. ioctl() system call is implemented in fbmem.c, so we turn to it and quickly we can find out such relationship between ioctl() commands and fb_ops’s methods:
FBIOGET_VSCREENINFO fb_get_var
FBIOPUT_VSCREENINFO fb_set_var
FBIOGET_FSCREENINFO fb_get_fix
FBIOPUTCMAP fb_set_cmap
FBIOGETCMAP fb_get_cmap
FBIOPAN_DISPLAY fb_pan_display
Now we know that if we implement these fb_XXX_XXX functions, then user application writers can use FBIOXXXX micros to operate LCD hardwares. But how can we implement them?
It is fine to have a reference to linux/drivers/video/fbgen.c or other drivers under the linux/drivers/video directory.
Among these functions, fb_set_var() is the most important. It is used to set video mode and more. The following is the common steps performed by a fb_set_var() function:
1) Check if mode setting is necessary
2) Set the mode
3) Set colormap
4) Reconfigure the registers of LCD controller according former settings
The fourth step shows where low level operations are placed. Curious men may have such a question: how image data of user application are put onto the screen. Driver writer allocates a system memory as video memory, and later he sets the start address and length of the memory to LCD controller’s registers(often in fb_set_var() function). The content of the memory will be sent to screen automatically by LCD controller(for details, see specific LCD controller). On the other hand, the allocated system memory is mapped to user space by mmap(). Thereby, when a user sends data to the mapped memory, the data will be shown on LCD screen.

Reference

1 液晶显示技术
2 液晶显示器件
3 linux/Documentation/fb/framebuffer.txt
4 linux/Documentation/fb/interal.txt
5 Linux Framebuffer Driver Writing HOWTO
http:/linux-fbdev.sourceforge.net/HOWTO /index.html
6 linux/include/linux/fb.h
7 linux/drivers/video/fbmem.c
8 linux/drivers/video/skeletonfb.c
9 linux/drivers/video/fbgen.c
10 linux/drivers/video/tgafb.c
11 s3c2410 microprocessor user manual
s3c2410fb.h, s3c2410fb.c, s3c2410fb.c-pre, s3c2410fb.c-mono
A kind of arm-based widely used MCU, with integrated LCD controller.
12 sed1335 datasheet
A kind of widely used LCD controller

Gem5模拟器,详解官网教程Event-driven programming(五) Gem5模拟器,详解官网教程Event-driven programming、时间调度、如何自定义SimObject 阅读详情

相关推荐

SAP Ariba Procurement_Catalogs

SAP Ariba Procurement_Catalogs Search Functionality PunchOut Catalogs Spot Buy catalog

CZxx1的博客 1010

frame buffer device驱动程序

framebufferdevice在内核里面作为显卡驱动模型,许多函数和数据结构都是特定,正是这些特定的东西为我们的编程提供了方便。要开发frame bufferdevice驱动,你应该阅读Source/Source/Documentation/fb下面的说明文件,三个重要文件00-INDEX,framebuffer.txt,internals.txt,其他文件都是针对具体显卡芯片的说

小鲍的专栏 1072

读取rosbag中的IMU信息并转为tum格式的csv和txt

rostopic -b xx.bag -p /xx > xxx.txt #for euroc structvio import os, sys,re,csv name="street_07" # basedir="/media/yinjie/2498AF1F98AEEF0C/adataset/15results/imu_bagtxt/"+name+'.txt' # txtdir="/media/yinjie/2498AF1F98AEEF0C//adataset/15results/imu_o

qq_42928559的博客 1919

framebuffer驱动全篇

在后续的几篇里面会详细介绍如何编写一个显卡的驱动程序。 framebuffer device在内核里面作为显卡驱动模型,许多函数和数据结构都是特定,正是这些特定的东西为我们的编程提供了方便。 要开发frame bufferdevice驱动,你应该阅读Source\Source\Documentation\fb下面的说明文件,三个重要文件00-INDEX,framebuffer.txt,inte

zangcf的专栏 1964

Ubuntu20.04安装NVIDIA显卡驱动避坑指南:从.run文件到完美运行

本文详细介绍了在Ubuntu20.04系统上通过.run文件安装NVIDIA显卡驱动的完整流程和避坑技巧。从禁用Nouveau驱动、选择合适显示管理器到处理常见安装问题,提供了一套经过验证的解决方案,帮助用户顺利完成驱动安装并优化性能。

weixin_30776273的博客 602

Fluent新手必看:如何正确解读scaled residuals曲线(附常见问题排查)

本文详细解析了Fluent中scaled residuals曲线的解读方法及常见问题排查技巧。针对continuity残差居高不下、湍流模型收敛困难等典型问题,提供了网格质量检查、边界条件验证和求解策略调整的实用解决方案,帮助CFD新手快速掌握计算收敛性的关键判断标准。

weixin_28698059的博客 372

Linux 驱动—LCD学习二:驱动框架(帧缓冲)篇

Linux 驱动—LCD学习二:驱动框架篇

u013686019的专栏 2677

超实用!用 Ollama + DeepSeek + Dify 搭建本地知识库,提升企业效率

本文介绍了如何使用 Ollama + DeepSeek + Dify 搭建本地知识库,帮助企业高效管理信息。通过简单配置,可实现智能问答、文档检索等功能,提升效率并保障数据安全。

Happiness is everywhere 4292

framebuffer Device 技术

随着高性能嵌入式处理器的普及和硬件成本的不断降低,尤其是ARM 系列处理器的推出,嵌入式系统的功能越来越强。单色LCD也因为色彩单调,存储信息小,处理速度慢而不能符合人们的需求。在多媒体应用的推动下,彩色 LCD越来越多地应用到了嵌入式系统中 如新一代手机和掌上电脑多采用TFT显

yuyin86的专栏 1309

支付域——账户系统设计

本文详细介绍了支付域中的账户系统设计,包括账户的定义、核心特征、常见类型以及在支付系统中的作用。账户是支付平台为用户、商户等主体建立的资金记录单元,具有资金归属、余额管理、交易流水、资金安全等核心特征。常见账户类型包括用户账户、商户账户、平台账户、保证金账户等。此外,还探讨了账户与银行账户的区别、账户的结构设计、如何设计账户类型以及账户系统设计等内容。

庄小焱 1186

国科大作业考试资料《人工智能原理与算法》2024新编-第二次作业整理

1、对于下列活动,分别给出任务环境的PEAS描述, 并按2.3.2节列出的性质进行分析: 3、为图2.2中描述的吸尘器世界实现一个可以进行性能度量的环境模拟器。你的实现是必须是模块化的,以使传感器、执行器和环境特征(大小、形状、灰尘放置等)便于修改。 4、实现上述题目真空吸尘器环境中的简单反射Agent。用所有可能的初始灰尘分布和Agent位置,运行环境模拟器和Agent。记录Agent在每种情况下的性能评分和总体平均评分。

MatsumotoChrikk 1187

Writing Linux LCD drivers—深入分…

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> Writing Linux LCD drivers—深入分析framebuffer设备驱动的结构 Writing Linux LCD drivers ——本

dieqms的专栏 543

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Linux驱动修炼之道-framebuffer

帧缓冲(frame buffer)是Linux视频系统的核心概念,因此先了解一下他的功能。 因为视频适配器可能基于不同的硬件体系架构,较高内核层和应用程序的实现可能会因视频卡的不同而不同,这会导致在使用不同视频卡的时需要采用不同的方案。随之而来的低可移植性和冗余的代码需要大量的投入和维护开销。帧缓冲的概念解决了这个问题,它进行了一般化的抽象并规定编程接口,从而开发人员可以以与平台无关的方式编

yaofengyaofeng的专栏 1858

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Fedora Framebuffer 配置

http://www.linuxsir.org/bbs/showthread.php?t=211427&highlight=framebuffer       写在前面的话:关于这方面的文章太多了,但还是写一个,主要是把大家的写的东西系统一下。为了照顾初学的弟兄。       提要:通过用   framebuffer   驱动,让console模式看上去更舒服一些;        

lesky的专栏 5166

移植Qt5.6

交叉编译工具:arm-linux-gcc-4.4.3内核:linux-4.12.0(使用移植linux-4.12到JZ2440里的linux-4.12,按照2.4 制作补丁内容获取内核,补丁下载地址:https://pan.baidu.com/s/1_uyLxOIgwVGCJPip5RcFNQ)制作好的网络文件系统目录:/work/tools/fs_mini/(使用制作文件系统里制作的文件系统)开...

墨、白的博客 1504

一个简单的framebuffer的显示使用例子

本例子中,显示设备是一个oled的显示屏; 没有过多的关于分辨率,刷新频率的设置; 只是演示一个framebuffer的例子。 一, kernel层的驱动代码如下:     1. 注册,这是一个使用i2c通讯的显示设备,因此注册成一个i2c设备。           定义: struct ssd1307fb_par { struct i2c_client *client; u32

蓝精灵的专栏 9029

高及驱动——四、framebuffer子系统(帧缓冲):lcd屏

============================================= 一、framebuffer子系统(帧缓冲):lcd屏 1,了解lcd屏的基础知识 2,framebuffer子系统框架 3,lcd驱动移植 4,linux启动logo的制作 5,framebuffer框架代码跟读 6,应用程序如何向lcd上显示数据 ================================================== 一,了解lcd屏的基础知识 //参考:E:\peter\2010\

weixin_49551849的博客 865

frame buffer device驱动程序 --zt

frame buffer device驱动程序第一篇在后续的几篇里面会详细介绍如何编写一个显卡的驱动程序。framebuffer device在内核里面作为显卡驱动模型,许多函数和数据结构都是特定,正是这些特定的东西为我们的编程提供了方便。要开发frame buffer device驱动,你应该阅读Source/Source/Documentation/fb下面的说明文件,三个重要文件00-I

koko1998的专栏 1331
上一篇: Android核心分析(23)-----Andoird GDI之基本原理及其总体框架
下一篇: Android2.2添加Ethernet 框架支持(一)
文心叼虫
博客等级 码龄16年 116粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值