mini2440驱动分析之LCD

2020-05-22来源: eefocus关键字:mini244  0驱动分析  LCD

mini2440集成了lcd控制器的接口,板子上接的lcd硬件是统宝240*320,TFT型lcd。lcd驱动对应的文件为s3c2410fb.c。要读懂这个驱动必须了解linux platform子系统的知识。因为这个驱动是以platform驱动的形式注册到内核。而且还需要frambuffer驱动的知识,因为这个驱动还是frambuffer接口的。lcd驱动在模块初始化的时候,调用platform注册函数将自己注册到内核,利用linux设备模型核心的机制调用platform_bus总线的match函数找到相应的设备,然后由linux设备模型核心调用s3c2410fb.c中的s3c2410fb_probe ,进行硬件相关初始化,并初始化frambuffer结构。然后注册到frambuffer核心。lcd的功能实现通过frambuffer核心来完成。s3c2410fb.c的功能实现都是配合frambuffer核心的。下面详细分析lcd驱动的实现。


程序基本结构

 1.模块初始化-->向platform核心注册自己

 2.实现linux设备模型必须的

probe函数-->向frambuffer核心注册自己(最重要)

resume函数-->系统在由挂起恢复的时候调用

suspand-->系统在挂起的时候调用 

 remove--> 驱动程序注销自己的时候调用                  

 3.frambuffer驱动模型fb_ops各函数的实现-->实现fb驱动的ioctl命令需要的函数

 4.其他函数-->由2.3.中的函数调用,帮助其实现功能。


一. 相关数据结构

  1. struct fb_info 结构

struct fb_info {

int node;

int flags;

struct mutex lock; /* Lock for open/release/ioctl funcs */

struct mutex mm_lock; /* Lock for fb_mmap and smem_* fields */

struct fb_var_screeninfo var; /* Current var */

struct fb_fix_screeninfo fix; /* Current fix */

struct fb_monspecs monspecs; /* Current Monitor specs */

struct work_struct queue; /* Framebuffer event queue */

struct fb_pixmap pixmap; /* Image hardware mapper */

struct fb_pixmap sprite; /* Cursor hardware mapper */

struct fb_cmap cmap; /* Current cmap */

struct list_head modelist;      /* mode list */

struct fb_videomode *mode; /* current mode */

 

#ifdef CONFIG_FB_BACKLIGHT

/* assigned backlight device */

/* set before framebuffer registration, 

   remove after unregister */

struct backlight_device *bl_dev;

 

/* Backlight level curve */

struct mutex bl_curve_mutex;

u8 bl_curve[FB_BACKLIGHT_LEVELS];

#endif

#ifdef CONFIG_FB_DEFERRED_IO

struct delayed_work deferred_work;

struct fb_deferred_io *fbdefio;

#endif

 

struct fb_ops *fbops;

struct device *device; /* This is the parent */

struct device *dev; /* This is this fb device */   

int class_flag;                    /* private sysfs flags */

#ifdef CONFIG_FB_TILEBLITTING

struct fb_tile_ops *tileops;    /* Tile Blitting */

#endif

char __iomem *screen_base; /* Virtual address */

unsigned long screen_size; /* Amount of ioremapped VRAM or 0 */ 

void *pseudo_palette; /* Fake palette of 16 colors */ 

#define FBINFO_STATE_RUNNING 0

#define FBINFO_STATE_SUSPENDED 1

u32 state; /* Hardware state i.e suspend */

void *fbcon_par;                /* fbcon use-only private area */

/* From here on everything is device dependent */

void *par;

/* we need the PCI or similiar aperture base/size not

   smem_start/size as smem_start may just be an object

   allocated inside the aperture so may not actually overlap */

resource_size_t aperture_base;

resource_size_t aperture_size;

};

    这个结构是frambuffer驱动的基本数据结构,里面包含了帧缓存设备的所有信息,每一个注册成frambuffer接口的设备都应该声明并初始化这样一个结构。register_framebuffer 函数的参数就是这样一个结构,fb_info在mini2440lcd驱动中是在s3c24xxfb_probe函数中分配并初始化的。其中struct fb_var_screeninfo结构包含了lcd显示中可以改变的信息,结构如下:

struct fb_var_screeninfo {

__u32 xres; /* 视口水平分辨率 */

__u32 yres;

__u32 xres_virtual; /* 虚拟屏幕水平分辨率 */

__u32 yres_virtual;

__u32 xoffset; /* 视口与虚拟屏幕水平分辨率偏移 */

__u32 yoffset;

 

 

__u32 bits_per_pixel; /* 像素的位数 */

__u32 grayscale; /* 灰度标志,如果为1代表是灰度 */

 

 

struct fb_bitfield red; /* 如果是真彩色,这个是颜色位,如果不是那么只有结构的大小重要,其他表示的信息无关紧要 */

struct fb_bitfield green;

struct fb_bitfield blue;

struct fb_bitfield transp; /* 透明度 */

 

 

__u32 nonstd; /* 非标准颜色表示标志位 */

__u32 activate; /* 参照 FB_ACTIVATE_* */

__u32 height; /* 在内存地址空间的长度    */

__u32 width; /* 在内存地址空间的宽度     */

 

 

__u32 accel_flags; /* (不用了) 参照 fb_info.flags */

 

 

/* 时序: 以下所有的值单位都是pixclock, 当然除了pixclock */

__u32 pixclock; /* 每秒像素值 */

__u32 left_margin; /* 从sync信号到显示真正的像素的时钟个数 */

__u32 right_margin; /* 从真正显示像素到sync信号的时钟个数 */

__u32 upper_margin; /* 上面两个是针对列像素的,这个针对行的 */

__u32 lower_margin;

__u32 hsync_len; /* 水平sync信号的长度 */

__u32 vsync_len; /* 垂直sync信号的长度 */

__u32 sync; /* 参照 FB_SYNC_* */

__u32 vmode; /* 参照 FB_VMODE_* */

__u32 rotate; /* angle we rotate counter clockwise */ 

__u32 reserved[5]; /* 保留 */

};

  fb_fix_screeninfo包含了lcd显示中不可改变的信息,结构如下:

struct fb_fix_screeninfo {

char id[16]; /* 身份表示符,例如 "TT Builtin" */

unsigned long smem_start; /* frame buffer内存的开始地址 */

/* (物理地址) */

__u32 smem_len; /* frame buffer内存地址的长度 */

__u32 type; /* 参照 FB_TYPE_* */

__u32 type_aux; /* Interleave for interleaved Planes */

__u32 visual; /* 参照 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; /* 每行的长度,单位字节    */

unsigned long mmio_start; /* I/O 内存的开始地址   */

/* (物理地址) */

__u32 mmio_len; /* I/O内存的长度  */

__u32 accel; /* 对驱动程序的标示:是哪个设备*/

__u16 reserved[3]; /* 保留 */

};

  其中倒数第三个成员par是设备自定义数据结构。在mini2440lcd驱动中为s3c2410fb_info,结构如下:

struct s3c2410fb_info {

struct device *dev;

struct clk *clk;

 

struct resource *mem; //io内存物理地址也就是寄存器的地址

void __iomem *io;  //用ioremap映射的io虚拟地址

void __iomem *irq_base; //中断控制器寄存器对应的虚拟地址

 

enum s3c_drv_type drv_type;

struct s3c2410fb_hw regs;

 

unsigned long clk_rate;

unsigned int palette_ready;

 

#ifdef CONFIG_CPU_FREQ

struct notifier_block freq_transition;

#endif

 

/* keep these registers in case we need to re-write palette */

u32 palette_buffer[256];

u32 pseudo_pal[16];

};

  这个结构是和硬件相关的,包括寄存器的物理地址,虚拟地址和调色板的一些信息。这个结构也是在s3c24xxfb_probe中分配并初始化。

  2. static struct fb_ops 结构

  在mini2440lcd驱动中,fb_ops的初始化代码如下:

static struct fb_ops s3c2410fb_ops = {

.owner = THIS_MODULE,

.fb_check_var = s3c2410fb_check_var,

.fb_set_par = s3c2410fb_set_par,

.fb_blank = s3c2410fb_blank,

.fb_setcolreg = s3c2410fb_setcolreg,

.fb_fillrect = cfb_fillrect,

.fb_copyarea = cfb_copyarea,

.fb_imageblit = cfb_imageblit,

};

  这些函数是驱动程序必须实现的,他们实现的功能对应frambuffer核心的Ioctl系统调用,当应用程序调用ioctl系统调用的时候,他们会被直接或间接的调用。其中:

s3c2410fb_check_var 和s3c2410fb_set_par会由fb_set_var调用,对应Ioctl的FBIOPUT_VSCREENINFO命令


s3c2410fb_blank ,对应ioctl的FBIOBLANK命令,其他几个函数也是类似。


  3. struct s3c2410fb_mach_info 结构

struct s3c2410fb_mach_info {

struct s3c2410fb_display *displays; /* attached diplays info */

unsigned num_displays; /* number of defined displays */

unsigned default_display;

/* GPIOs */

unsigned long gpcup;

unsigned long gpcup_mask;

unsigned long gpccon;

unsigned long gpccon_mask;

unsigned long gpdup;

unsigned long gpdup_mask;

unsigned long gpdcon;

unsigned long gpdcon_mask;

 

/* lpc3600 control register */

unsigned long lpcsel;

};

  这个结构包括一个s3c2410fb_display结构体,其他的域是GPIO寄存器的信息。mini2440lcd驱动中定义并初始化了这样一个结构体:

static struct s3c2410fb_mach_info mini2440_fb_info __initdata = {

.displays = &mini2440_lcd_cfg,

.num_displays = 1,

.default_display = 0,

 

.gpccon =       0xaa955699,

.gpccon_mask =  0xffc003cc,

.gpcup =        0x0000ffff,

.gpcup_mask =   0xffffffff,

 

.gpdcon =       0xaa95aaa1,

.gpdcon_mask =  0xffc0fff0,

.gpdup =        0x0000faff,

.gpdup_mask =   0xffffffff,

 

.lpcsel = 0xf82,

};

  这里初始化了结构中的所有成员,s3c2410fb_display结构初始化成mini2440_lcd_cfg,这个结构的初始化是在/arch/arm/mach-s3c2440/mach-mini2440.c这个文件中。这里设置了s3c2440 lcd控制器对应的GPIO寄存器的初始值,在s3c2410fb_init_registers函数中将这些值写到相应的寄存器中。

  4. s3c2410fb_display 结构

struct s3c2410fb_display {

/* LCD type */

unsigned type;

 

/* Screen size */

unsigned short width;

unsigned short height;

 

/* Screen info */

unsig

[1] [2] [3]
关键字:mini244  0驱动分析  LCD 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic497982.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:友善之臂 MINI2440开发板与SecureCRT之间的通信
下一篇:最后一页

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

嵌入式arm学习总结(八)--存储知识-基于MINI244
MINI2440   ram:4k , rom:没有程序运行:sdram  ,norflash程序存放:nandflash,norflashnandflash和norflash最大区别:norflash可以片上运行程序(并行总线,引脚多),nandflash不能(串行总线,引脚少)通常linux操作系统存放在nandflash里面nandflash启动模式:开发板上电时,nandflash控制器把前4K代码复制到2440的内部4ksram中,然后通过硬件机制把2440内部4ksram地址映射到为0的地址开始,程序开始执行这4k代码这4k代码包含功能:初始化sdram,复制nandflash中的代码
发表于 2020-03-13
mini244-------keil for ARM系列之时钟的配置(附带LED代码)
;  }  }  //  void Led_Init(void)  {  //GPB5-8都配置为输出      GPBCON &=~(0x3FC00);      GPBCON |=(1<<10)|(1<<12)|(1<<14)|(1<<16);  }   
发表于 2017-11-27
mini244-------keil for ARM系列之时钟的配置(附带LED代码)
S3C2440 块设备驱动之框架详细分析
本节目的:通过分析2.6内核下的块设备驱动框架,知道如何来写驱动1、之前我们学的都是字符设备驱动,先来回忆一下字符设备驱动:当我们的应用层读写(read()/write())字符设备驱动时,是按字节/字符来读写数据的,期间没有任何缓存区,因为数据量小,不能随机读取数据,例如:按键、LED、鼠标、键盘等。2、接下来本届开始学习块设备驱动块设备:块设备是i/o设备中的一类,当我们的应用层对该设备读写时,是按扇区大小来读写数据,若读写的数据小于扇区的大小,就会需要缓存区,可以随机读写设备的任意位置处的数据,例如 普通文件(*txt,*.c等),硬盘,U盘,SD卡3、块设备结构:段(Segments):由若干个块组成。是Linux内存管理
发表于 2020-03-12
S3C2440 块设备驱动之框架详细分析
tiny4412内核自带led驱动分析
/38725619 http://blog.sina.com.cn/s/blog_a6559d9201015vx9.html三、驱动代码分析:流程:初始化(注册misc设备)—>定义fops结构体与misc结构体—>实现fops中相关函数—>把fops绑定到misc结构体—>注销misc设备。#include <linux/kernel.h>#include <linux/module.h>#include <linux/miscdevice.h>#include <linux/fs.h>#include <linux/types.h>#include
发表于 2020-03-10
tiny4412内核自带led驱动分析
MDA800 电机驱动分析仪对电机驱动和控制系统的测试挑战
电机在各个领域都得到了非常广泛的应用,如家电,电动汽车,电梯,传送带等等。为了提升效率和提高电机的控制精度,电机驱动系统和控制系统包括控制算法日益复杂,而电机驱动系统通常使用三相交流输入和三相交流输出以增加电机控制信号的灵活度和效率,所以整个电机系统的调试分析变得日益复杂。为了应对复杂电机系统的测试挑战,力科(Teledyne LeCroy)专门推出了电机驱动分析仪MDA800系列。本文将介绍力科的电机驱动分析仪 MDA800 如何帮助工程师应对日益复杂的电机驱动系统的测试挑战。一、典型的电机驱动和控制系统典型的电机驱动和控制系统包括功率转换、电机、嵌入式控制系统三大部分。功率转换部分包括三相输入,三相输出以控制电机的运行。电机
发表于 2020-03-05
MDA800 电机驱动分析仪对电机驱动和控制系统的测试挑战
基于STM8L152的TAB段式LCD液晶驱动的分析
基于STM8L152的TAB段式LCD液晶驱动的分析 - 单片机干货 - 中国电子技术论坛 - 最好最受欢迎电子论坛!.md 主控芯片为STM8L152C4T6自带LCD控制器,低功耗系列,最近公司用到这个芯片,第一次接触STM8,刚毕业第一次做产品,也算是满成功的,发个帖纪念一下, 顺便记录一下自己学习段式LCD的过程,在查找段式LCD工作资料的过程中,确实有几篇好的博客,给了很大的帮助,但是仍然觉得不够详细,希望这次分析能够帮助到大家。首先看STM8的LCD控制器的两个关键寄存器:一: Port mask registers (LCD_PM)这是映射LCD控制IO的寄存器,寄存器内容如下:由图可知,当你使用
发表于 2020-02-26
基于STM8L152的TAB段式LCD液晶驱动的分析
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved