<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > S3C2440上LCD驅(qū)動(dòng)(FramBuffer)實(shí)例開發(fā)詳解(一)

          S3C2440上LCD驅(qū)動(dòng)(FramBuffer)實(shí)例開發(fā)詳解(一)

          作者: 時(shí)間:2016-08-15 來源:網(wǎng)絡(luò) 收藏

            2. 幀緩沖相關(guān)的重要數(shù)據(jù)結(jié)構(gòu):

          本文引用地址:http://www.ex-cimer.com/article/201608/295508.htm

            從幀緩沖設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)看,該驅(qū)動(dòng)主要跟fb_info結(jié)構(gòu)體有關(guān),該結(jié)構(gòu)體記錄了幀緩沖設(shè)備的全部信息,包括設(shè)備的設(shè)置參數(shù)、狀態(tài)以及對(duì)底層硬件操作的函數(shù)指針。在Linux中,每一個(gè)幀緩沖設(shè)備都必須對(duì)應(yīng)一個(gè)fb_info,fb_info在/linux/fb.h中的定義如下:(只列出重要的一些)

            struct fb_info {

            int node;

            int flags;

            struct fb_var_screeninfo var;/*LCD可變參數(shù)結(jié)構(gòu)體*/

            struct fb_fix_screeninfo fix;/*LCD固定參數(shù)結(jié)構(gòu)體*/

            struct fb_monspecs monspecs;/*LCD顯示器標(biāo)準(zhǔn)*/

            struct work_struct queue;/*幀緩沖事件隊(duì)列*/

            struct fb_pixmap pixmap; /*圖像硬件mapper*/

            struct fb_pixmap sprite; /*光標(biāo)硬件mapper*/

            struct fb_cmap cmap; /*當(dāng)前的顏色表*/

            struct fb_videomode *mode;/*當(dāng)前的顯示模式*/

            #ifdef CONFIG_FB_BACKLIGHT

            struct backlight_device *bl_dev

            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;

            struct device *dev;/*fb設(shè)備*/

            int class_flag;

            #ifdef CONFIG_FB_TILEBLITTING

            struct fb_tile_ops *tileops; /*圖塊Blitting*/

            #endif

            char __iomem *screen_base;/*虛擬基地址*/

            unsigned long screen_size;/*LCD IO映射的虛擬內(nèi)存大小*/

            void *pseudo_palette;/*偽16色顏色表*/

            #define FBINFO_STATE_RUNNING 0

            #define FBINFO_STATE_SUSPENDED 1

            u32 state;/*LCD的掛起或恢復(fù)狀態(tài)*/

            void *fbcon_par;

            void *par;

            };

            其中,比較重要的成員有struct fb_var_screeninfo var、struct fb_fix_screeninfo fix和struct fb_ops *fbops,他們也都是結(jié)構(gòu)體。下面我們一個(gè)一個(gè)的來看。

            fb_var_screeninfo結(jié)構(gòu)體主要記錄用戶可以修改的控制器的參數(shù),比如屏幕的分辨率和每個(gè)像素的比特?cái)?shù)等,該結(jié)構(gòu)體定義如下:

            struct fb_var_screeninfo {

            __u32 xres;/*可見屏幕一行有多少個(gè)像素點(diǎn)*/

            __u32 yres;/*可見屏幕一列有多少個(gè)像素點(diǎn)*/

            __u32 xres_virtual;/*虛擬屏幕一行有多少個(gè)像素點(diǎn)*/

            __u32 yres_virtual;/*虛擬屏幕一列有多少個(gè)像素點(diǎn)*/

            __u32 xoffset;/*虛擬到可見屏幕之間的行偏移*/

            __u32 yoffset;/*虛擬到可見屏幕之間的列偏移*/

            __u32 bits_per_pixel;/*每個(gè)像素的位數(shù)即BPP*/

            __u32 grayscale;/*非0時(shí),指的是灰度*/

            struct fb_bitfield red;/*fb緩存的R位域*/

            struct fb_bitfield green;/*fb緩存的G位域*/

            struct fb_bitfield blue;/*fb緩存的B位域*/

            struct fb_bitfield transp;/*透明度*/

            __u32 nonstd;/* != 0 非標(biāo)準(zhǔn)像素格式*/

            __u32 activate;

            __u32 height;/*高度*/

            __u32 width;/*寬度*/

            __u32 accel_flags;

            /*定時(shí):除了pixclock本身外,其他的都以像素時(shí)鐘為單位*/

            __u32 pixclock;/*像素時(shí)鐘(皮秒)*/

            __u32 left_margin;/*行切換,從同步到繪圖之間的延遲*/

            __u32 right_margin;/*行切換,從繪圖到同步之間的延遲*/

            __u32 upper_margin;/*幀切換,從同步到繪圖之間的延遲*/

            __u32 lower_margin;/*幀切換,從繪圖到同步之間的延遲*/

            __u32 hsync_len;/*水平同步的長(zhǎng)度*/

            __u32 vsync_len;/*垂直同步的長(zhǎng)度*/

            __u32 sync;

            __u32 vmode;

            __u32 rotate;

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

            };

            而fb_fix_screeninfo結(jié)構(gòu)體又主要記錄用戶不可以修改的控制器的參數(shù),比如屏幕緩沖區(qū)的物理地址和長(zhǎng)度等,該結(jié)構(gòu)體的定義如下:

            struct fb_fix_screeninfo {

            char id[16];/*字符串形式的標(biāo)示符 */

            unsigned long smem_start;/*fb緩存的開始位置 */

            __u32 smem_len;/*fb緩存的長(zhǎng)度 */

            __u32 type;/*看FB_TYPE_* */

            __u32 type_aux;/*分界*/

            __u32 visual;/*看FB_VISUAL_* */

            __u16 xpanstep;/*如果沒有硬件panning就賦值為0 */

            __u16 ypanstep;/*如果沒有硬件panning就賦值為0 */

            __u16 ywrapstep;/*如果沒有硬件ywrap就賦值為0 */

            __u32 line_length;/*一行的字節(jié)數(shù) */

            unsigned long mmio_start;/*內(nèi)存映射IO的開始位置*/

            __u32 mmio_len;/*內(nèi)存映射IO的長(zhǎng)度*/

            __u32 accel;

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

            };

            其中,比較重要的成員有struct fb_var_screeninfo var、struct fb_fix_screeninfo fix和struct fb_ops *fbops,他們也都是結(jié)構(gòu)體。下面我們一個(gè)一個(gè)的來看。

            fb_var_screeninfo結(jié)構(gòu)體主要記錄用戶可以修改的控制器的參數(shù),比如屏幕的分辨率和每個(gè)像素的比特?cái)?shù)等,該結(jié)構(gòu)體定義如下:

            struct fb_var_screeninfo {

            __u32 xres;/*可見屏幕一行有多少個(gè)像素點(diǎn)*/

            __u32 yres;/*可見屏幕一列有多少個(gè)像素點(diǎn)*/

            __u32 xres_virtual;/*虛擬屏幕一行有多少個(gè)像素點(diǎn)*/

            __u32 yres_virtual;/*虛擬屏幕一列有多少個(gè)像素點(diǎn)*/

            __u32 xoffset;/*虛擬到可見屏幕之間的行偏移*/

            __u32 yoffset;/*虛擬到可見屏幕之間的列偏移*/

            __u32 bits_per_pixel;/*每個(gè)像素的位數(shù)即BPP*/

            __u32 grayscale;/*非0時(shí),指的是灰度*/

            struct fb_bitfield red;/*fb緩存的R位域*/

            struct fb_bitfield green;/*fb緩存的G位域*/

            struct fb_bitfield blue;/*fb緩存的B位域*/

            struct fb_bitfield transp;/*透明度*/

            __u32 nonstd;/* != 0 非標(biāo)準(zhǔn)像素格式*/

            __u32 activate;

            __u32 height;/*高度*/

            __u32 width;/*寬度*/

            __u32 accel_flags;

            /*定時(shí):除了pixclock本身外,其他的都以像素時(shí)鐘為單位*/

            __u32 pixclock;/*像素時(shí)鐘(皮秒)*/

            __u32 left_margin;/*行切換,從同步到繪圖之間的延遲*/

            __u32 right_margin;/*行切換,從繪圖到同步之間的延遲*/

            __u32 upper_margin;/*幀切換,從同步到繪圖之間的延遲*/

            __u32 lower_margin;/*幀切換,從繪圖到同步之間的延遲*/

            __u32 hsync_len;/*水平同步的長(zhǎng)度*/

            __u32 vsync_len;/*垂直同步的長(zhǎng)度*/

            __u32 sync;

            __u32 vmode;

            __u32 rotate;

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

            };

            而fb_fix_screeninfo結(jié)構(gòu)體又主要記錄用戶不可以修改的控制器的參數(shù),比如屏幕緩沖區(qū)的物理地址和長(zhǎng)度等,該結(jié)構(gòu)體的定義如下:

            struct fb_fix_screeninfo {

            char id[16];/*字符串形式的標(biāo)示符 */

            unsigned long smem_start;/*fb緩存的開始位置 */

            __u32 smem_len;/*fb緩存的長(zhǎng)度 */

            __u32 type;/*看FB_TYPE_* */

            __u32 type_aux;/*分界*/

            __u32 visual;/*看FB_VISUAL_* */

            __u16 xpanstep;/*如果沒有硬件panning就賦值為0 */

            __u16 ypanstep;/*如果沒有硬件panning就賦值為0 */

            __u16 ywrapstep;/*如果沒有硬件ywrap就賦值為0 */

            __u32 line_length;/*一行的字節(jié)數(shù) */

            unsigned long mmio_start;/*內(nèi)存映射IO的開始位置*/

            __u32 mmio_len;/*內(nèi)存映射IO的長(zhǎng)度*/

            __u32 accel;

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

            };

            fb_ops結(jié)構(gòu)體是對(duì)底層硬件操作的函數(shù)指針,該結(jié)構(gòu)體中定義了對(duì)硬件的操作有:(這里只列出了常用的操作)

            struct fb_ops {

            struct module *owner;

            //檢查可變參數(shù)并進(jìn)行設(shè)置

            int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);

            //根據(jù)設(shè)置的值進(jìn)行更新,使之有效

            int (*fb_set_par)(struct fb_info *info);

            //設(shè)置顏色寄存器

            int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,

            unsigned blue, unsigned transp, struct fb_info *info);

            //顯示空白

            int (*fb_blank)(int blank, struct fb_info *info);

            //矩形填充

            void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);

            //復(fù)制數(shù)據(jù)

            void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);

            //圖形填充

            void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);

            };

            3. 幀緩沖設(shè)備作為平臺(tái)設(shè)備:

            在S3C2440中,LCD控制器被集成在芯片的內(nèi)部作為一個(gè)相對(duì)獨(dú)立的單元,所以Linux把它看做是一個(gè)平臺(tái)設(shè)備,故在內(nèi)核代碼/arch/arm/plat-s3c24xx/devs.c中定義有LCD相關(guān)的平臺(tái)設(shè)備及資源,代碼如下:

            /* LCD Controller */

            //LCD控制器的資源信息

            static struct resource s3c_lcd_resource[] = {

            [0] = {

            .start = S3C24XX_PA_LCD

            }

            };

            static u64 s3c_device_lcd_dmamask = 0xffffffffUL;

            struct platform_device s3c_device_lcd = {

            .name = "s3c2410-lcd"

            .id = -1,

            .num_resources = ARRAY_SIZE(s3c_lcd_resource)

            .dev = {

            .dma_mask = &s3c_device_lcd_dmamask,

            .coherent_dma_mask = 0xffffffffUL

            }

            };

            EXPORT_SYMBOL(s3c_device_lcd)

            除此之外,Linux還在/arch/arm/mach-s3c2410/include/mach/fb.h中為L(zhǎng)CD平臺(tái)設(shè)備定義了一個(gè)s3c2410fb_mach_info結(jié)構(gòu)體,該結(jié)構(gòu)體主要是記錄LCD的硬件參數(shù)信息(比如該結(jié)構(gòu)體的s3c2410fb_display成員結(jié)構(gòu)中就用于記錄LCD的屏幕尺寸、屏幕信息、可變的屏幕參數(shù)、LCD配置寄存器等),這樣在寫驅(qū)動(dòng)的時(shí)候就直接使用這個(gè)結(jié)構(gòu)體。下面,我們來看一下內(nèi)核是如果使用這個(gè)結(jié)構(gòu)體的。在/arch/arm/mach-s3c2440/mach-smdk2440.c中定義有:

            /* LCD driver info */

            //LCD硬件的配置信息,注意這里我使用的LCD是NEC 3.5寸TFT屏,這些參數(shù)要根據(jù)具體的LCD屏進(jìn)行設(shè)置

            static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {

            //這個(gè)地方的設(shè)置是配置LCD寄存器5,這些宏定義在regs-lcd.h中,計(jì)算后二進(jìn)制為:111111111111,然后對(duì)照數(shù)據(jù)手冊(cè)上LCDCON5的各位來看,注意是從右邊開始

            .lcdcon5 = S3C2410_LCDCON5_FRM565 |

            S3C2410_LCDCON5_INVVLINE |

            S3C2410_LCDCON5_INVVFRAME |

            S3C2410_LCDCON5_PWREN |

            S3C2410_LCDCON5_HWSWP,

            .type = S3C2410_LCDCON1_TFT

            //以下一些參數(shù)在上面的時(shí)序圖分析中講到過,各參數(shù)的值請(qǐng)跟據(jù)具體的LCD屏數(shù)據(jù)手冊(cè)結(jié)合上面時(shí)序分析來設(shè)定

            };

            static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = {

            .displays = &smdk2440_lcd_cfg

            .num_displays = 1,

            .default_display = 0,

            .gpccon = 0xaaaa555a

            .gpccon_mask = 0xffffffff,

            .gpcup = 0x0000ffff

            .gpcup_mask = 0xffffffff,

            .gpdcon = 0xaaaaaaaa

            .gpdcon_mask = 0xffffffff,

            .gpdup = 0x0000ffff

            .gpdup_mask = 0xffffffff,

            .lpcsel = 0x0

            };

            注意:可能有很多朋友不知道上面紅色部分的參數(shù)是做什么的,其值又是怎么設(shè)置的?其實(shí)它是跟你的開發(fā)板LCD控制器密切相關(guān)的,看了下面兩幅圖相信就大概知道他們是干什么用的:

            

           

            

           

            上面第一幅圖是開發(fā)板原理圖的LCD控制器部分,第二幅圖是S3c2440數(shù)據(jù)手冊(cè)中IO端口C和IO端口D控制器部分。原理圖中使用了GPC8-15和GPD0-15來用做LCD控制器VD0-VD23的數(shù)據(jù)端口,又分別使用GPC0、GPC1端口用做LCD控制器的LEND和VCLK信號(hào),對(duì)于GPC2-7則是用做STN屏或者三星專業(yè)TFT屏的相關(guān)信號(hào)。然而,S3C2440的各個(gè)IO口并不是單一的功能,都是復(fù)用端口,要使用他們首先要對(duì)他們進(jìn)行配置。所以上面紅色部分的參數(shù)就是把GPC和GPD的部分端口配置成LCD控制功能模式。

            從以上講述的內(nèi)容來看,要使LCD控制器支持其他的LCD屏,重要的是根據(jù)LCD的數(shù)據(jù)手冊(cè)修改以上這些參數(shù)的值。下面,我們?cè)倏匆幌略隍?qū)動(dòng)中是如果引用到s3c2410fb_mach_info結(jié)構(gòu)體的(注意上面講的是在內(nèi)核中如何使用的)。在mach-smdk2440.c中有:

            //S3C2440初始化函數(shù)

            static void __init smdk2440_machine_init(void)

            {

            s3c24xx_fb_set_platdata(&smdk2440_fb_info);

            s3c_i2c0_set_platdata(NULL);

            platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));

            smdk_machine_init();

            }

            s3c24xx_fb_set_platdata定義在plat-s3c24xx/devs.c中:

            void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)

            {

            struct s3c2410fb_mach_info *npd;

            npd = kmalloc(sizeof(*npd), GFP_KERNEL);

            if (npd) {

            memcpy(npd, pd, sizeof(*npd));

            //這里就是將內(nèi)核中定義的s3c2410fb_mach_info結(jié)構(gòu)體數(shù)據(jù)保存到LCD平臺(tái)數(shù)據(jù)中,所以在寫驅(qū)動(dòng)的時(shí)候就可以直接在平臺(tái)數(shù)據(jù)中獲取s3c2410fb_mach_info結(jié)構(gòu)體的數(shù)據(jù)(即LCD各種參數(shù)信息)進(jìn)行操作

            s3c_device_lcd.dev.platform_data = npd;

            } else {

            printk(KERN_ERR "no memory for LCD platform datan");

            }

            }

            這里再講一個(gè)小知識(shí):不知大家有沒有留意,在平臺(tái)設(shè)備驅(qū)動(dòng)中,platform_data可以保存各自平臺(tái)設(shè)備實(shí)例的數(shù)據(jù),但這些數(shù)據(jù)的類型都是不同的,為什么都可以保存?這就要看看platform_data的定義,定義在/linux/device.h中,void *platform_data是一個(gè)void類型的指針,在Linux中void可保存任何數(shù)據(jù)類型。


          上一頁(yè) 1 2 下一頁(yè)

          關(guān)鍵詞: 嵌入式linux

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();