當(dāng)前位置:首頁 > 芯聞號(hào) > 充電吧
[導(dǎo)讀]一、框架分析: 我們先來分析一下核心層的代碼fbmem.c: ① 入口函數(shù)fbmem_init: fbmem_init(void) { create_proc_r

一、框架分析:

我們先來分析一下核心層的代碼fbmem.c: ① 入口函數(shù)fbmem_init:
fbmem_init(void)  
{  
    create_proc_read_entry("fb", 0, NULL, fbmem_read_proc, NULL);  

    if (register_chrdev(FB_MAJOR,"fb",&fb_fops))  
        printk("unable to get major %d for fb devsn", FB_MAJOR);  

    fb_class = class_create(THIS_MODULE, "graphics");  
    if (IS_ERR(fb_class)) {  
        printk(KERN_WARNING "Unable to create fb class; errno = %ldn", PTR_ERR(fb_class));  
        fb_class = NULL;  
    }  
    return 0;  
}  

fbmem_init里面注冊字符設(shè)備fb,其主設(shè)備號(hào)為29.并且創(chuàng)建了類class_create,注意在此沒有創(chuàng)建設(shè)備節(jié)點(diǎn)

② file_operations fb_fops
static const 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,
    .open =     fb_open,
    .release =  fb_release,
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
    .get_unmapped_area = get_fb_unmapped_area,
#endif
#ifdef CONFIG_FB_DEFERRED_IO
    .fsync =    fb_deferred_io_fsync,
#endif
};

Ⅰ、 我們假設(shè) app: open(“/dev/fb0”, …) 主設(shè)備號(hào): 29, 次設(shè)備號(hào): 0 //應(yīng)用程序打開 /dev/fb0,主設(shè)備號(hào)29 次設(shè)備號(hào)0;那么就會(huì)調(diào)用內(nèi)核中的 fb_open:

fb_open(struct inode *inode, struct file *file)
{
 int fbidx = iminor(inode);     // 得到次設(shè)備號(hào) 0 
 struct fb_info *info = registered_fb[fbidx(0)];         //fb_info 這個(gè)結(jié)構(gòu)體等于registered_fb數(shù)組里面的次設(shè)備號(hào)檢索出來。
}

Ⅱ、 我們假設(shè) app: read() //應(yīng)用程序read的時(shí)候;那么就會(huì)調(diào)用內(nèi)核中的 fb_read:

fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
            int fbidx = iminor(inode);//得到次設(shè)備號(hào)0
            struct fb_info *info = registered_fb[fbidx];//在registered_fb數(shù)組里得到一個(gè)fb_info 結(jié)構(gòu)體
}

由I、Ⅱ可知open read都依賴fb_info結(jié)構(gòu)體,從registered_fb數(shù)組中得到fb_info結(jié)構(gòu)體。
也就是說內(nèi)核中主設(shè)備號(hào)為29的設(shè)備可能有很多,open的時(shí)候根據(jù)次設(shè)備號(hào)從registered_fb數(shù)組得到一個(gè)fb_info。
registered_fb數(shù)組在register_framebuffer被設(shè)置

register_framebuffer(struct fb_info*fb_info)
{
    fb_info->dev = device_create(fb_class, fb_info->device,MKDEV(FB_MAJOR, i), "fb%d", i); //創(chuàng)建設(shè)備節(jié)點(diǎn)
       registered_fb[i]= fb_info;
}
小結(jié):到此已經(jīng)可以很清晰看出LCD的框架。

首先內(nèi)核幫助我們實(shí)現(xiàn)了一個(gè)主設(shè)備號(hào)為29的設(shè)備,此時(shí)只創(chuàng)建了類,并沒有在類下創(chuàng)建設(shè)備節(jié)點(diǎn)。
當(dāng)我們的下層硬件驅(qū)動(dòng)調(diào)用注冊函數(shù)的時(shí)候,會(huì)初始化registered_fb結(jié)構(gòu)體,并創(chuàng)建設(shè)備節(jié)點(diǎn)。
此時(shí)應(yīng)用程序可以來打開一個(gè)設(shè)備節(jié)點(diǎn)了,比如open(“/dev/fb0”, …),最終會(huì)調(diào)用到fbmem核心層提供的open函數(shù),這個(gè)open函數(shù)中根據(jù)次設(shè)備號(hào),registered_fb數(shù)組中取出硬件注冊進(jìn)來的結(jié)構(gòu)體,調(diào)用里面的open函數(shù),或者使用一些屬性。這樣內(nèi)核可以方便管理類似的設(shè)備了。

③ fbmem.c系統(tǒng)實(shí)現(xiàn)并抽象出來的,使用的時(shí)候依賴于底層框架實(shí)現(xiàn),那么我們來寫底層框架實(shí)現(xiàn)函數(shù)xxxfb.c

上層fbmem.c內(nèi)核已經(jīng)寫好,并完成上層驅(qū)動(dòng)注冊。我們要做的是寫出硬件部分的函數(shù),來初始化registered_fb:
1. 分配一個(gè)fb_info結(jié)構(gòu)體: 怎么分配:framebuffer_alloc
2. 設(shè)置fb_info里面的相關(guān)參數(shù)
3. 注冊:register_framebuffer
4. 硬件相關(guān)的設(shè)置

來列舉一下寫底層框架函數(shù)將用到的結(jié)構(gòu)體: fb_info 結(jié)構(gòu)體:
struct fb_info {  
    int node;/*  序號(hào)索引值,/dev/fb0,/dev/fb1  其中0,1 就是從這里獲得的*/  
    int flags;  
    struct fb_var_screeninfo var;   /* Current var  可變參數(shù),很重要 */  
    struct fb_fix_screeninfo fix;   /* Current fix  固定參數(shù),很重要 */  
    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;/* fb_ops,各種幀緩沖操作函數(shù),很重要 */  
    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 */ /* 16位假的調(diào)色板,重要 */   
#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;   /* 這個(gè)用來存放私有數(shù)據(jù) */  
};  

將用到下面6個(gè)內(nèi)容:
struct fb_var_screeninfo var; /* Current var 可變參數(shù),很重要 */
struct fb_fix_screeninfo fix; /* Current fix 固定參數(shù),很重要 */
struct fb_ops fbops;/ fb_ops,各種幀緩沖操作函數(shù),很重要 */
char __iomem screen_base; / Virtual address “顯存“的基地址 */
unsigned long screen_size; /* Amount of ioremapped VRAM or 0 ”顯存“的大小,重要 */
void pseudo_palette; / Fake palette of 16 colors / / 16位假的調(diào)色板,重要 */

Ⅰ、 fb_var_screeninfo 結(jié)構(gòu)體:
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;      /* (OBSOLETE) see fb_info.flags */  

    /* 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 rotate;           /* angle we rotate counter clockwise */  
    __u32 reserved[5];      /* Reserved for future compatibility */  
};  
Ⅱ、fb_fix_screeninfo fix結(jié)構(gòu)體:
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;            /* Indicate to driver which */  
                    /*  specific chip/card we have  */  
    __u16 reserved[3];      /* Reserved for future compatibility */  
};
Ⅲ、fb_ops 結(jié)構(gòu)體:
struct fb_ops {
    struct module *owner;
    /* 打開/釋放 */
    int (*fb_open)(struct fb_info *info, int user);
    int (*fb_release)(struct fb_info *info, int user);

/* 對于非線性布局的/常規(guī)內(nèi)存映射無法工作的幀緩沖設(shè)備需要 */
    ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
               size_t count, loff_t *ppos);
    ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
                size_t count, loff_t *ppos);

    /* 檢測可變參數(shù),并調(diào)整到支持的值*/
    int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);

    /* 根據(jù) info->var 設(shè)置 video 模式 */
    int (*fb_set_par)(struct fb_info *info);

    /* 設(shè)置 color 寄存器 */
    int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
                unsigned blue, unsigned transp, struct fb_info *info);

    /* 批量設(shè)置 color 寄存器,設(shè)置顏色表 */
    int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);

    /*顯示空白 */
    int (*fb_blank)(int blank, struct fb_info *info);

    /* pan 顯示 */
    int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);

    /* 矩形填充 */
    void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
    /* 數(shù)據(jù)復(fù)制 */
    void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
    /* 圖形填充 */
    void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);

    /* 繪制光標(biāo) */
    int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);

    /* 旋轉(zhuǎn)顯示 */
    void (*fb_rotate)(struct fb_info *info, int angle);

    /* 等待 blit 空閑 (可選) */
    int (*fb_sync)(struct fb_info *info);

    /* fb 特定的 ioctl (可選) */
    int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
            unsigned long arg);

    /* 處理 32 位的 compat ioctl (可選) */
    int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
            unsigned long arg);

     /* fb 特定的 mmap */
    int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);

    /* 保存目前的硬件狀態(tài) */
    void (*fb_save_state)(struct fb_info *info);

    /* 恢復(fù)被保存的硬件狀態(tài) */
    void (*fb_restore_state)(struct fb_info *info);

    /* get capability given var */
    void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
                struct fb_var_screeninfo *var);
};
二、代碼:

底層驅(qū)動(dòng)lcd.c:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

// 設(shè)置lcd的控制寄存器
struct lcd_regs {  
    unsigned long   lcdcon1;  
    unsigned long   lcdcon2;  
    unsigned long   lcdcon3;  
    unsigned long   lcdcon4;  
    unsigned long   lcdcon5;  
    unsigned long   lcdsaddr1;  
    unsigned long   lcdsaddr2;  
    unsigned long   lcdsaddr3;  
    unsigned long   redlut;  
    unsigned long   greenlut;  
    unsigned long   bluelut;  
    unsigned long   reserved[9];  
    unsigned long   dithmode;  
    unsigned long   tpal;  
    unsigned long   lcdintpnd;  
    unsigned long   lcdsrcpnd;  
    unsigned long   lcdintmsk;  
    unsigned long   lpcsel;  
};  

//設(shè)置fb_ops 結(jié)構(gòu)體
static int s3c_lcdfb_setcolreg(unsigned int regno, unsigned int red,
                 unsigned int green, unsigned int blue,
                 unsigned int transp, struct fb_info *info);
static struct fb_ops s3c_lcdfb_ops = {
    .owner      = THIS_MODULE,
    .fb_setcolreg   = s3c_lcdfb_setcolreg, // 設(shè)置 color 寄存器
    .fb_fillrect    = cfb_fillrect,        // 矩形填充
    .fb_copyarea    = cfb_copyarea,        // 數(shù)據(jù)復(fù)制
    .fb_imageblit   = cfb_imageblit,       // 圖形填充
};

/* 定義LCD的操作寄存器 */
static volatile unsigned long *GPBCON;
static volatile unsigned long *GPBDAT;
static volatile unsigned long *GPCCON;
static volatile unsigned long *GPDCON;
static volatile unsigned long *GPGCON;
static volatile struct lcd_regs *lcd_regs;

//定義fb_info結(jié)構(gòu)體
static struct fb_info *s3c_lcd;
static u32 pseudo_palette[16];

/* from pxafb.c */
static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
{
    chan &= 0xffff;
    chan >>= 16 - bf->length;
    return chan << bf->offset;
}


static int s3c_lcdfb_setcolreg(unsigned int regno, unsigned int red,
                 unsigned int green, unsigned int blue,
                 unsigned int transp, struct fb_info *info)
{
    unsigned int val;

    if (regno > 16)
        return 1;

    /* 用red,green,blue三原色構(gòu)造出val */
    val  = chan_to_field(red,   &info->var.red);
    val |= chan_to_field(green, &info->var.green);
    val |= chan_to_field(blue,  &info->var.blue);

    //((u32 *)(info->pseudo_palette))[regno] = val;
    pseudo_palette[regno] = val;
    return 0;
}




static int lcd_init(void)
{   
    /* 1.分配一個(gè)fb_info */
    s3c_lcd = framebuffer_alloc(0,NULL);

    /* 2.設(shè)置 */
    /* 2.1 設(shè)置固定參數(shù)fix */
    strcpy(s3c_lcd->fix.id,"czg_led");
    s3c_lcd->fix.smem_len = 480*272*16/8;
    s3c_lcd->fix.type = FB_TYPE_PACKED_PIXELS;
    s3c_lcd->fix.visual = FB_VISUAL_TRUECOLOR;/* TFT */
    s3c_lcd->fix.line_length = 480*2;

    /* 2.2 設(shè)置可變參數(shù)var */
    s3c_lcd->var.xres           = 480;
    s3c_lcd->var.yres           = 272;
    s3c_lcd->var.xres_virtual   = 480;
    s3c_lcd->var.yres_virtual   = 272;
    s3c_lcd->var.bits_per_pixel = 16;

    /* RGB:565 */
    s3c_lcd->var.red.offset   = 11;
    s3c_lcd->var.red.length   = 5;
    s3c_lcd->var.green.offset = 5;
    s3c_lcd->var.green.length = 6;
    s3c_lcd->var.blue.offset  = 0;
    s3c_lcd->var.blue.length  = 5;

    s3c_lcd->var.activate     = FB_ACTIVATE_NOW;



    /* 2.3 設(shè)置幀緩沖操作函數(shù)fobps */
    s3c_lcd->fbops = &s3c_lcdfb_ops;

    /* 2.4 設(shè)置“顯存“的基地址 */
    //s3c_lcd->screen_base; /* 顯存的虛擬地址 */ //在3.3設(shè)置

    /* 2.5 設(shè)置”顯存“的大小 */
    s3c_lcd->screen_size = 480*272*16/8;    /* 顯存的大小 */ 

    /* 2.6 設(shè)置6位偽調(diào)色板  */
    s3c_lcd->pseudo_palette = pseudo_palette;


    /* 3.硬件相關(guān)的操作 */
    /* 3.1 配置GPIO用于LCD */
    GPBCON = ioremap(0x56000010,8);
    GPBDAT = GPBCON + 1;
    GPCCON = ioremap(0x56000020,4);
    GPDCON = ioremap(0x56000030,4);
    GPGCON = ioremap(0x56000060,4);

    *GPCCON  = 0xaaaaaaaa;   // GPIO管腳用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND 
    *GPDCON  = 0xaaaaaaaa;  // GPIO管腳用于VD[23:8]

    *GPBCON &= ~(3<<0);// KEYBOARD output pin
    *GPBCON |= 1;
    *GPBDAT &= ~(1<<0);            // KEYBOARD off

    *GPGCON |=  (3<<(2*4));


    /* 3.2 根據(jù)LCD手冊設(shè)置LCD控制器,比如VCLK的頻率等等 */
    lcd_regs = ioremap(0X4D000000,sizeof(struct lcd_regs));

    /* bit[17:8] : TFT: VCLK = HCLK / [(CLKVAL+1) x 2] ( CLKVAL >= 0 ) */
    /*             HCLK通過dmesg命令查看為100MHZ*/
    /*             VCLK在LCD芯片手冊P11頁中取典型值9MHZ     */
    /*            CLKVAL = 100/9/2 -1 = 4.5 = 4 */
    /* bit[6:5] = 0b11  TFT LCD panel */
    /* bit[4:1] = 0b1100    16 bpp for TFT */
    /* bit[0]   = 0 Disable the video output and the LCD control signal */
    lcd_regs->lcdcon1 = (4<<8) | (3<<5) | (0x0c<<1);

    /* 垂直方向時(shí)間參數(shù) */
    /* bit[31:24] : LCD芯片手冊P11頁和2440數(shù)據(jù)手冊時(shí)序圖對比 */
    /*              VBPD = tvb - 1 = 2-1 = 1  */
    /* bit[23:14] : LINEVAL = tvd - 1 = 272-1 = 271 */
    /* bit[13:6]  : VFPD = tvf - 1 = 2-1 = 1  */
    /* bit[5:0]   : VSPW = tvp - 1 = 10-1 = 9*/
    lcd_regs->lcdcon2 = (1<<24) | (271<<14) | (1<<6)| (9<<0);

    /* 水平方向時(shí)間參數(shù) */
    /* bit[[25:19] : LCD芯片手冊P11頁和2440數(shù)據(jù)手冊時(shí)序圖對比 */
    /*               HBPD (TFT) = thb - 1 = 2-1 = 1  */
    /* bit[18:8]   : HOZVAL = thd - 1 = 480-1 = 479 */
    /* bit[7:0]    : HFPD (TFT) = thf - 1 = 2-1 = 1  */
    lcd_regs->lcdcon3 = (1<<19) | (479<<8) | (1<<0);

    /* 水平方向的同步信號(hào) */
    /* bit[7:0]    : HSPW(TFT) = thp - 1 = 41-1 = 40  */
    lcd_regs->lcdcon4 = (40<<0);

    /* bit[11]    : FRM565 = 1      5:6:5 Format */
    /* bit[10]     : INVVCLK = 0 The video data is fetched at VCLK falling edge  */
    /* bit[9]     : INVVLINE  = 1 Inverted VLINE/HSYNC 低電平有效 */
    /* bit[8]      : INVVFRAME = 1 Inverted VFRAME/VSYNC 低電平有效 */
    /* bit[7]      : INVVD = 0  Normal VD (video data) */
    /* bit[6]      : INVVDEN = 0  normal VDEN數(shù)據(jù)信號(hào) 高電平有效不需要反轉(zhuǎn) */
    /* bit[5]      : INVPWREN = 0  normal PWREN 電源信號(hào) 高電平有效不需要反轉(zhuǎn) */
    /* bit[3]      : LCD_PWREN output = 0  Disable PWREN signal 設(shè)置完再使能 */
    /* bit[1:0]    : BSWP-HWSWP:0b01 = 0x01,數(shù)據(jù)手冊P413 像素排列P1-P2-P3-P4 */

    lcd_regs->lcdcon5 = (1<<11) | (1<<9) | (1<<8) | (1<<0);


    /* 3.3 分配顯存(framebuffer),并把地址告訴L CD控制器 */
    //s3c_lcd->fix.smem_start /* 顯存的物理地址 */
    s3c_lcd->screen_base = dma_alloc_writecombine(NULL,s3c_lcd->fix.smem_len,(u32 *)&s3c_lcd->fix.smem_start,GFP_KERNEL);
    lcd_regs->lcdsaddr1 = (s3c_lcd->fix.smem_start >> 1) & ~(3<<30);
    lcd_regs->lcdsaddr2 = ((s3c_lcd->fix.smem_start + s3c_lcd->fix.smem_len) >> 1) & (0x1fffff);
    lcd_regs->lcdsaddr3 = (480*16/16);

    /* 3.4 啟動(dòng)LCD */
    *GPBDAT |= (1<<0);  /* 輸出高電平,使能背光 */
    lcd_regs->lcdcon1 |= (1<<0); /* 使能LCD控制器 */
    lcd_regs->lcdcon5 |= (1<<3); /* 使能LCD本身電源 */

    /* 4.注冊 */
    register_framebuffer(s3c_lcd);
    return 0;
}

static void lcd_exit(void)
{
    iounmap(lcd_regs);
    iounmap(GPBCON);
    iounmap(GPCCON);
    iounmap(GPDCON);
    iounmap(GPGCON);
    *GPBDAT &= ~(1<<0);    /* 輸出低電平,關(guān)閉背光 */
    lcd_regs->lcdcon1 &= ~(1<<0); /* 關(guān)閉LCD控制器 */
    lcd_regs->lcdcon5 &= ~(1<<3); /* 關(guān)閉LCD本身電源 */
    framebuffer_release(s3c_lcd); // 釋放fb_info
    dma_free_writecombine(NULL,s3c_lcd->fix.smem_len,s3c_lcd->screen_base,s3c_lcd->fix.smem_start); // 釋放顯存
    unregister_framebuffer(s3c_lcd); // 卸載
}

module_init(lcd_init);
module_exit(lcd_exit);
MODULE_LICENSE("GPL");

Makefile:

KERN_DIR = /work/system/linux-2.6.22.6

all:
    make -C $(KERN_DIR) M=`pwd` modules 

clean:
    make -C $(KERN_DIR) M=`pwd` modules clean
    rm -rf modules.order

obj-m += lcd.o
三、編譯測試: ① 需要重新編譯內(nèi)核, make menuconfig去掉原來的驅(qū)動(dòng)程序 -> Device Drivers   -> Graphics support      S3C2410 LCD framebuffer support

② make uImage 使用新的內(nèi)核啟動(dòng)開發(fā)板
cp arch/arm/boot/uImage /work/nfs_root/czg/uImage_nolcd
nfs 30000000 192.168.2.3:/work/nfs_root/czg/uImage_nolcd
bootm 30000000


③ 加載三個(gè)附加模塊,make modules
cp drivers/video/cfb*.ko /work/nfs_root/czg
insmod cfbcopyarea.ko 
insmod cfbfillrect.ko 
insmod cfbimgblt.ko 
insmod lcd.ko

④ 測試: 第一種方式:
ls /dev/fb*
echo hello_czg > /dev/tty1   //顯示屏上顯示
cat lcd.ko > /dev/fb0
第二種方式:
① echo tty1::askfirst:-/bin/sh >> /etc/inittab
② 用新內(nèi)核重啟開發(fā)板-重復(fù)上面②
③  insmod cfbcopyarea.ko 
    insmod cfbfillrect.ko 
    insmod cfbimgblt.ko 
    insmod lcd.ko
    insmod buttons_drv.ko
④ 通過按鍵在LCD顯示屏上看到ls指令

buttons_drv.ko模塊點(diǎn)我跳轉(zhuǎn)

⑤ 查看進(jìn)程
ps
ls /proc/*/fd -l



本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉