收藏 分享(赏)

lcd驱动分析文档.doc

上传人:hwpkd79526 文档编号:9424604 上传时间:2019-08-06 格式:DOC 页数:27 大小:781KB
下载 相关 举报
lcd驱动分析文档.doc_第1页
第1页 / 共27页
lcd驱动分析文档.doc_第2页
第2页 / 共27页
lcd驱动分析文档.doc_第3页
第3页 / 共27页
lcd驱动分析文档.doc_第4页
第4页 / 共27页
lcd驱动分析文档.doc_第5页
第5页 / 共27页
点击查看更多>>
资源描述

1、嵌入式 linux 中 的 lcd 驅動分析作 者 : 傑洲 村的 木棉 學校 :廣 東工 業大 學 QQ: 568109894在 嵌 入式 linux 中, lcd 和觸控式螢幕驅 動 都是 字 元驅 動 , 採 用 “檔 層 -驅 動 層 ”的 介 面 方 式 ,本文檔中分 析 的 lcd 驅動是針 對linux2.6.13 內核的,本人用 的 開發 板 是 qq2440,lcd 是三星的 LTV3500V(帶觸控式螢幕的) ,具體分析 的文件:是 “include/linux/fb.h“,“drivers/video/s3c2410fb.h“,“drivers/video/s3c2410

2、fb.c“,“drivers/video/fbmem.c“,“/include/asm/arch- s3c2410.fb.h(些標頭檔是針對 s3c2440 或 s3c2410 晶片的) “,“/home/linux/5/kernel-2.6.13/arch/arm/mach-s3c2410/mach- smdk2410.c“(驅動移植主要就 是要修 改這個 檔, 配置一 些參數) 。 詳 細看一 下 LCD 的驅動 ,實 際 上 , 幾 乎 lcd 設備驅 動所要 做的所 有事情 就是填 充 fb_info 結構然後向系統註 冊或登 出它(1)fb.h 包含了 framebuffer 所用到

3、的結構(2)fbmem.c 處於 Framebuffer 設備驅動技術的 中 心位置. 它 為上層 應 用程式提 供系統 調用也 為下一 層的特 定硬體 驅動提 供介面;那些 底層 硬體驅 動 需要 用 到這 兒 的介 面 來向 系 統內 核 註冊 它 們自己 . fbmem.c 為所有 支 援 FrameBuffer 的設備驅動提供了 通用的 介面, 避免重 復工 作.(3)s3c2410fb.c 就是特定硬體驅動 (針 對 s3c2410 晶片的 ),fbmem.c 就是溝通 應 用 層 跟 s3c2410fb.c 的橋樑FrameBuffer 設備驅動基於如下 幾個檔 :1)includ

4、e/linux/fb.h2)drivers/video/fbmem.c3)drivers/video/s3c2410fb.c4)drivers/video/s3c2410fb.h5)include/asm/arch-s3c2410/fb.h現在先來 分析這 兩個檔 :1.fb.h 包 含 了 framebuffer 所 用 到 的 結 構1)fb_fix_screeninfo 描述顯示 卡的屬 性,並 且系統 運行時 不能被 修改 s truct fb_fix_screeninfo char id16;unsigned long smem_start;/* identification str

5、ing eg “TT Builtin“ */* Start of frame buffer mem */* (physical address) */_u32 smem_len; /* Length of frame buffer mem */_u32 type;_u32 type_aux;/* see FB_TYPE_* */* Interleave for interleaved Planes */_u32 visual; /* see FB_VISUAL_* */_u16 xpanstep; /* zero if no hardware panning */_u16 ypanstep;_

6、u16 ywrapstep;_u32 line_length;/* zero if no hardware panning */* zero if no hardware ywrap */* length of a line in bytes */unsigned long mmio_start; /* Start of Memory Mapped I/O */* (physical address) */_u32 mmio_len;_u32 accel;/* Length of Memory Mapped I/O */* Indicate to driver which */* specif

7、ic chip/card we have */;_u16 reserved3; /* Reserved for future compatibility */2)fb_var_screeninfo 這個結構 描述了 顯示卡 的特性 struct fb_var_screeninfo _u32 xres;_u32 yres;_u32 xres_virtual;/* visible resolution/* virtual resolution*/*/_u32 yres_virtual;_u32 xoffset; /* offset from virtual to visible */_u32 yo

8、ffset; /* resolution */_u32 bits_per_pixel;_u32 grayscale;/* guess what/* != 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; /* transpar

9、ency */_u32 nonstd; /* != 0 Non standard pixel format */_u32 activate; /* see FB_ACTIVATE_* */_u32 height;_u32 width;/* height of picture in mm/* width of picture in mm*/*/_u32 accel_flags; /* (OBSOLETE) see fb_info.flags */* Timing: All values in pixclocks, except pixclock (of course) */_u32 pixclo

10、ck; /* 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 *

11、/_u32 sync; /* see FB_SYNC_* */_u32 vmode; /* see FB_VMODE_* */_u32 rotate; /* angle we rotate counter clockwise */_u32 reserved5; /* Reserved for future compatibility */;3)fb_cmap描述設 備 無關 的 顏色 映 射資訊。可 以 通過 FBIOGETCMAP 和 F BIOPUTCMAP 對應的 ioctl 操作設定或獲取 顏色映 射資訊struct fb_cmap _u32 start; /* First entry

12、 */_u32 len; /* Number of entries */_u16 *red; /* Red values */_u16 *green;_u16 *blue;_u16 *transp; /* transparency, can be NULL */;4)fb_info(1)定義當顯卡的 當 前狀 態 ; fb_info 結構僅在內核中 可 見 , 在 這個 結 構中有 一 個 fb_ops 指標, 指向驅動 設備工 作所需 的函數 集。struct fb_info int node; int flags;struct fb_var_screeninfo var; /* Curre

13、nt 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; /* Curr

14、ent cmap */struct list_head modelist; /* mode list */ struct fb_videomode *mode; /* current mode */ struct fb_ops *fbops; /(注意這個結 構) struct device *device;struct class_device *class_device; /* sysfs per device attrs */#ifdef CONFIG_FB_TILEBLITTINGstruct fb_tile_ops *tileops; /* Tile Blitting */#endi

15、fchar _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 1u32 state; /* Hardware state i.e suspend */void *fbcon_par; /* fbcon use-o

16、nly private area */* From here on everything is device dependent */void *par;(2)fb_info 中 紀 錄 了 幀 緩 衝 設 備 的 全 部 資 訊 , 包 括 設 備 的 設 置 參 數 , 狀 態 以 及 操 作 函 數 指 標 。 每 一 個 幀 緩 衝 設 備 都 必 須對應一個 fb_info 結構 。其 中成 員 變數 Modename 為 設 備名 稱 ,f ontname 為顯示 字 體 ,fb ops 為 指 向 底 層 操 作 的 函 數 的 指 標 , 這些 函數 是需 要驅 動程 式開 發

17、人 員編 寫的 。成 員 fb_var_screeninfo 和 fb_fix_screeninfo 也是 結 構體 。 其中 fb_var_screeninfo 記錄 使用 者 可修 改的 顯示 控制 器參 數 , 包括 螢幕 解析 度和 每個 圖 元 點 的 比特 數 。fb _var_screeninfo 中的 xres 定 義 螢 幕 一 行 有 多少 個點 , yres 定義 螢 幕 一列 有 多 少個 點 , bits_per_pixel 定義 每 個點 用 多 少個 位 元 組 表示 。 而 fb_fix_screeninfo 中記 錄 使 用 者不能 修改 的顯 示控 制器 的

18、參 數, 如螢 幕緩 衝區 的 物 理 位 址 , 長 度 。 當 對 幀 緩 衝 設 備 進 行 映 射 操 作 的 時 候 , 就 是 從 fb_fix_screeninfo 中取 得 緩衝 區 物理 位址 的 。 重要 : : (上面 所說 的資 料成 員都 是需 要在 驅 動 程 式 中 設 置 的 )。5)fb_fops(1)結構包含在 fb_info 結構中 ,指向驅動 設 備工 作 所需 的 函數 集 。 fb_ops 結構中包含 了 很多 涵 數指針 (在 drivers/video/fbmem.c 文件中定義)(2)使用者應用程式 通 過 ioctl()系統調用操作硬體 ,f

19、 b_ops 中的函數 就用於支 援這些 操作。 (注: fb_ops 結構與 file_operations 結構不同, fb_ops 是底層操作 的 抽象 ,而 file_operations 是提供給上層 系統調用 的介 面 ,可以 直接調 用. ioctl()系統調用在檔 fbmem.c 中實現,通 過 觀察 可 以 發 現 ioctl()命令與 fb_opss 中函數的關係:FBIOGET_VSCREENINFO fb_get_varFBIOPUT_VSCREENINFO fb_set_var FBIOGET_FSCREENINFO fb_get_fix FBIOPUTCMAP fb

20、_set_cmap FBIOGETCMAP fb_get_cmapFBIOPAN_DISPLAY fb_pan_display如果我 們 定 義 了 fb_XXX_XXX 方法,使用者程 式 就可 以 使用 FBIOXXXX 巨 集 的 ioctl()操作來操作硬 體。當應 用程 式對 設備 檔進行 ioctl 操作 時 候 會調 用 它 們 。 對於 fb_get_fix(), 應 用 程式 傳 入 的是 fb_fix_screeninfo 結 構 ,在函數 中對 其成 員變 數賦 值 , 主要是 smem_start(緩 衝區 起始 地址 )和 smem_len( 緩 衝 區 長 度 )

21、, 最 終 返 回 給 應 用 程 式 。static struct file_operations fb_fops = .owner = THIS_MODULE,.read = fb_read,.write = fb_write,.ioctl = fb_ioctl,#ifdef CONFIG_COMPAT.compat_ioctl = fb_compat_ioctl,#endif.mmap = fb_mmap, /這個在哪定義呢 ?(在 fbmem.c 中定義,這個函 數 比 較 重 要 , 是 framebuffer 的映射函數).open = fb_open,.release = fb_

22、release,#ifdef HAVE_ARCH_FB_UNMAPPED_AREA.get_unmapped_area = get_fb_unmapped_area,#endif;*/* Frame buffer operations* LOCKING NOTE: those functions must _ALL_ be called with the console* semaphore held, this is the only suitable locking mecanism we have* in 2.6. Some may be called at interrupt time

23、 at this point though.*/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);/* For framebuffers with strange non linear layouts or that do not* work with normal memory mapped access*/s

24、size_t (*fb_read)(struct file *file, char _user *buf, size_t count, loff_t *ppos);ssize_t (*fb_write)(struct file *file, const char _user *buf, size_t count, loff_t *ppos);/* checks var and eventually tweaks it to something supported,* DO NOT MODIFY PAR */int (*fb_check_var)(struct fb_var_screeninfo

25、 *var, struct fb_info *info);/* set the video mode according to info-var */int (*fb_set_par)(struct fb_info *info);/* set color register */int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,unsigned blue, unsigned transp, struct fb_info *info);/* set color registers in batch */int (*fb

26、_setcmap)(struct fb_cmap *cmap, struct fb_info *info);/* blank display */int (*fb_blank)(int blank, struct fb_info *info);/* pan display */int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);/* Draws a rectangle */void (*fb_fillrect) (struct fb_info *info, const struct fb_fill

27、rect *rect);/* Copy data from area to another */void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);/* Draws a image to the display */void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);/* Draws cursor */int (*fb_cursor) (struct fb_info *info, struct fb

28、_cursor *cursor);/* Rotates the display */void (*fb_rotate)(struct fb_info *info, int angle);/* wait for blit idle, optional */int (*fb_sync)(struct fb_info *info);/* perform fb specific ioctl (optional) */int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg, s

29、truct fb_info *info);/* Handle 32bit compat ioctl (optional) */long (*fb_compat_ioctl)(struct file *f, unsigned cmd, unsigned long arg, struct fb_info *info);/* perform fb specific mmap */int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);3)我們來研究一下 fb_ioctl 介面函 數 :當應

30、 用程 式對 設備 檔進行 ioctl 操作 時 候 會調 用 它 們 。 對於 fb_get_fix(), 應 用 程式 傳 入 的是 fb_fix_screeninfo 結 構 ,在函數 中對 其成 員變 數賦 值 , 主要是 smem_start(緩 衝區 起始 地址 )和 smem_len( 緩 衝 區 長 度 ) , 最 終 返 回 給 應 用 程 式 。static intfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)int fbidx = iminor(in

31、ode);struct fb_info *info = registered_fbfbidx;struct fb_ops *fb = info-fbops; struct fb_var_screeninfo var; struct fb_fix_screeninfo fix; struct fb_con2fbmap con2fb; struct fb_cmap_user cmap;struct fb_event event;void _user *argp = (void _user *)arg;int i;if (!fb)return -ENODEV;switch (cmd) case FB

32、IOGET_VSCREENINFO:/獲取屏的可變參數 (fb_get_var)return copy_to_user(argp, case FBIOPUT_VSCREENINFO:/設置屏的可變參數 (fb_set_var)if (copy_from_user(acquire_console_sem();info-flags |= FBINFO_MISC_USEREVENT;i = fb_set_var(info, info-flags release_console_sem();if (i) return i;if (copy_to_user(argp, return 0;case FBI

33、OGET_FSCREENINFO:/獲取屏的固定參數 (fb_get_fix)return copy_to_user(argp, case FBIOPUTCMAP:/設置調色板 (fb_get_cmap)if (copy_from_user(return (fb_set_user_cmap(case FBIOGETCMAP:/獲取調色板資訊 (fb_get_cmap)if (copy_from_user(return fb_cmap_to_user(case FBIOPAN_DISPLAY:(fb_pan_display)if (copy_from_user(acquire_console_s

34、em();i = fb_pan_display(info, release_console_sem();if (i)return i;if (copy_to_user(argp, return 0;case FBIO_CURSOR:return -EINVAL;case FBIOGET_CON2FBMAP:if (copy_from_user(if (con2fb.console MAX_NR_CONSOLES)return -EINVAL;con2fb.framebuffer = -1;event.info = info;event.data = notifier_call_chain(re

35、turn copy_to_user(argp, case FBIOPUT_CON2FBMAP:if (copy_from_user(if (con2fb.console MAX_NR_CONSOLES)return -EINVAL;if (con2fb.framebuffer = FB_MAX)return -EINVAL;#ifdef CONFIG_KMODif (!registered_fbcon2fb.framebuffer)try_to_load(con2fb.framebuffer);#endif /* CONFIG_KMOD */if (!registered_fbcon2fb.f

36、ramebuffer)return -EINVAL;event.info = info;event.data = return notifier_call_chain(case FBIOBLANK:acquire_console_sem();info-flags |= FBINFO_MISC_USEREVENT;i = fb_blank(info, arg); /開關顯示用 info-flags release_console_sem();return i;default:if (fb-fb_ioctl = NULL)return -EINVAL;return fb-fb_ioctl(inod

37、e, file, cmd, arg, info);2.fbmem.c(.mmap =fb_mmap 函 數比較重要,是 framebuffer 的映射函 數 ,如我的程式就用到vd-map = ( unsigned char * )mmap( 0, vd-mbuf.size, PROT_READ | PROT_WRITE, MAP_SHARED, vd-fd, 0 ),請自己 閱 讀我的一分 關 於視頻採集 系 統的文檔 (已經付上 源 程 序 )linux 內核啟動時 將自動載入 定義在 linux/drivers/video/fbmem.c 文 件中的 framebuffer1)全 域變數

38、struct fb_info *registered_fbFB_MAX;int num_registered_fb;這兩變 數 記錄 了 所有 fb_info 結構的實例,f b_info 結構描述顯卡 的 當前狀態,所 有 設備 對 應的 fb_info 結構都保存在這個 陣列中 ,當一個 FrameBuffer 設備驅動向系統 註 冊自 己 時 , 其 對 應 的 fb_info 結 構就會 添 加到 這 個結 構 中 , 同 時 num_registered_fb 為自動加 1.2)fbmem.c 實現了 如下 函數.register_framebuffer(struct fb_info

39、 *fb_info);unregister_framebuffer(struct fb_info *fb_info);這兩個 是 提供 給 下層 FrameBuffer 設備驅動的介 面 ,設 備 驅動 通 過 這 兩函數 向 系統 註 冊或 登 出自 己 。幾 乎 底層 設 備驅 動 所要 做 的所 有 事情 就是 填 充 fb_info 結構然後向系統註 冊或登 出它。3)fb_set_var()在所有 的 這些 函 數中 fb_set_var()是最重要的 , 它用 於 設定 顯 示卡 的 模式和 其 它屬性,下 面 是 函 數 fb_set_var()的執行步驟:(1)檢測 是否 必須

40、 設定 模式(2)設定 模式(3)設定 顏色 映射(4) 根據 以 前 的 設 定 重 新 設 置 LCD 控制 器的 各寄存 器。第四步 表 明了 底 層操 作 到底 放 置在 何 處。 在 系統 記 憶體中 分 配顯 存 後 , 顯存的 起 始位 址 及長 度 將被 設 定到 LCD 控制 器的各 寄存器 中 (一 般通 過 fb_set_var()函數),顯存 中 的內 容 將自 動 被 LCD 控制 器 輸出 到 螢 幕上。 另 一方面,使 用 者 程式 通 過 函 數 mmap()將顯存映射到使用者 進程 位址空間 中,然 後使用 者 進程向 映射空 間發送 的所有 資料都 將會被

41、顯示 到 LCD 顯示器上 。流程圖:s3c2410fb.c 中 var-activate 設置為 FB_ACTIVATE_NOW,所以這裡 只 考慮 條 件 2。/*這是 linux2.6.13 的 f b_set_varint fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)int err, flags = info-flags;1:if (var-activate int ret = 0;fb_var_to_videomode(fb_var_to_videomode(/* make sure we dont d

42、elete the videomode of current var */ret = fb_mode_is_equal(if (!ret) struct fb_event event;event.info = info;event.data = ret = notifier_call_chain(if (!ret)fb_delete_videomode(return ret;2:if (var-activate return 0;if (err = info-fbops-fb_check_var(var, info)/先檢 查 一下設置是否符合要求return err;if (var-acti

43、vate int err = 0;info-var = *var;if (info-fbops-fb_set_par)info-fbops-fb_set_par(info);/設置可變參數上沒有實現該介面/*什麼功能都沒 有實現fb_pan_display(info, /s3c2410 不支援硬體 虛擬顯示,在 s3c2410fb.cstatic int s3c2410fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)gprintk(“pan_display(var=%p, info=%p)n“, var, i

44、nfo);gprintk(“pan_display: xoffset=%dn“, var-xoffset);gprintk(“pan_display: yoffset=%dn“, var-yoffset);return 0;*/fb_set_cmap(/調色板設置fb_var_to_videomode(if (info-modelist.prev if (!err info-flags event.info = info; notifier_call_chain(return 0;*/*這是網上的一 個參考 函數:static int s3c2440fb_set_var(struct fb_v

45、ar_screeninfo *var,int con,struct fb_info *info)struct s3c2440fb_info *fbi= (struct s3c2440fb_info *)info; /* 將顯示模 式 讀入 結 構體 s3c2440fb_info*/struct fb_var_screeninfo *dvar= get_con_var(int err;err= s3c2440fb_validate_var(var,fbi); /* 顯示模式是否 有效 */if(err) /* 無效返回 */return err;dvar-red=fbi-rgbrgbidx-re

46、d; /* 將顯示參數寫 入 結 構 體 fb_var_screeninfo */dvar-green=fbi-rgbrgbidx-green;dvar-blue=fbi-rgbrgbidx-bIue;dvar-transp=fbi-rgbrgbidx-transp;display-var= *dvar;s3c2440fb_hw_set_var (dvar,fbi); /* 設置RGB 顏色資訊 ,設置 S3C2440A 的 LCD 控制寄存器 */return 0;*/3.s3c2410fb.cqq2440 開 發 板的 framdbuffer 驅 動 程 式 在 linux/drivers

47、/video/s3c2410fb.c 中實 現 , 由 內 核 調用 int _devinit s3c2410fb_init(void)開始1)驅動初始化int _devinit s3c2410fb_init(void)return platform_driver_register( /*註冊 LCD 驅動進系 統* /很簡單就 是把這 個驅動 註冊進 系統, 系 統會 找 到 LCD 設備 並 調用 這 個 驅動的 probe 函數。2)初始化 lcd 控制器的 地 址指標 (LCDSADDR1:高位幀緩存位址 寄 存器 1;LCDSADDR2:高 位 幀緩存 位 址寄 存 器 2;LCDS

48、ADDR3:虛擬屏位址寄存器 )/* s3c2410fb_set_lcdaddr* initialise lcd controller address pointers*/static void s3c2410fb_set_lcdaddr(struct s3c2410fb_info *fbi)struct fb_var_screeninfo *var = unsigned long saddr1, saddr2, saddr3;saddr1 = fbi-fb.fix.smem_start 1;saddr2 = fbi-fb.fix.smem_start;saddr2 += (var-xres

49、* var-yres * var-bits_per_pixel)/8;saddr2= 1;saddr3 = S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH(var-xres);gprintk(“LCDSADDR1 = 0x%08lxn“, saddr1); gprintk(“LCDSADDR2 = 0x%08lxn“, saddr2); gprintk(“LCDSADDR3 = 0x%08lxn“, saddr3);writel(saddr1, S3C2410_LCDSADDR1); writel(saddr2, S3C2410_LCDSADDR2); writel(saddr3, S3C2410_LCDSADDR3);3)static inline struct s3c2410fb_info *fb_to_s3cfb(struct fb_info *info)return container_of(info, struct s3c2410fb_in

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报