<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

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

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

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

  2. 幀緩沖相關(guān)的重要數據結構:

本文引用地址:http://dyxdggzs.com/article/201608/295508.htm

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

  struct fb_info {

  int node;

  int flags;

  struct fb_var_screeninfo var;/*LCD可變參數結構體*/

  struct fb_fix_screeninfo fix;/*LCD固定參數結構體*/

  struct fb_monspecs monspecs;/*LCD顯示器標準*/

  struct work_struct queue;/*幀緩沖事件隊列*/

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

  struct fb_pixmap sprite; /*光標硬件mapper*/

  struct fb_cmap cmap; /*當前的顏色表*/

  struct fb_videomode *mode;/*當前的顯示模式*/

  #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設備*/

  int class_flag;

  #ifdef CONFIG_FB_TILEBLITTING

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

  #endif

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

  unsigned long screen_size;/*LCD IO映射的虛擬內存大小*/

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

  #define FBINFO_STATE_RUNNING 0

  #define FBINFO_STATE_SUSPENDED 1

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

  void *fbcon_par;

  void *par;

  };

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

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

  struct fb_var_screeninfo {

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

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

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

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

  __u32 xoffset;/*虛擬到可見(jiàn)屏幕之間的行偏移*/

  __u32 yoffset;/*虛擬到可見(jiàn)屏幕之間的列偏移*/

  __u32 bits_per_pixel;/*每個(gè)像素的位數即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 非標準像素格式*/

  __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;/*水平同步的長(cháng)度*/

  __u32 vsync_len;/*垂直同步的長(cháng)度*/

  __u32 sync;

  __u32 vmode;

  __u32 rotate;

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

  };

  而fb_fix_screeninfo結構體又主要記錄用戶(hù)不可以修改的控制器的參數,比如屏幕緩沖區的物理地址和長(cháng)度等,該結構體的定義如下:

  struct fb_fix_screeninfo {

  char id[16];/*字符串形式的標示符 */

  unsigned long smem_start;/*fb緩存的開(kāi)始位置 */

  __u32 smem_len;/*fb緩存的長(cháng)度 */

  __u32 type;/*看FB_TYPE_* */

  __u32 type_aux;/*分界*/

  __u32 visual;/*看FB_VISUAL_* */

  __u16 xpanstep;/*如果沒(méi)有硬件panning就賦值為0 */

  __u16 ypanstep;/*如果沒(méi)有硬件panning就賦值為0 */

  __u16 ywrapstep;/*如果沒(méi)有硬件ywrap就賦值為0 */

  __u32 line_length;/*一行的字節數 */

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

  __u32 mmio_len;/*內存映射IO的長(cháng)度*/

  __u32 accel;

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

  };

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

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

  struct fb_var_screeninfo {

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

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

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

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

  __u32 xoffset;/*虛擬到可見(jiàn)屏幕之間的行偏移*/

  __u32 yoffset;/*虛擬到可見(jiàn)屏幕之間的列偏移*/

  __u32 bits_per_pixel;/*每個(gè)像素的位數即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 非標準像素格式*/

  __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;/*水平同步的長(cháng)度*/

  __u32 vsync_len;/*垂直同步的長(cháng)度*/

  __u32 sync;

  __u32 vmode;

  __u32 rotate;

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

  };

  而fb_fix_screeninfo結構體又主要記錄用戶(hù)不可以修改的控制器的參數,比如屏幕緩沖區的物理地址和長(cháng)度等,該結構體的定義如下:

  struct fb_fix_screeninfo {

  char id[16];/*字符串形式的標示符 */

  unsigned long smem_start;/*fb緩存的開(kāi)始位置 */

  __u32 smem_len;/*fb緩存的長(cháng)度 */

  __u32 type;/*看FB_TYPE_* */

  __u32 type_aux;/*分界*/

  __u32 visual;/*看FB_VISUAL_* */

  __u16 xpanstep;/*如果沒(méi)有硬件panning就賦值為0 */

  __u16 ypanstep;/*如果沒(méi)有硬件panning就賦值為0 */

  __u16 ywrapstep;/*如果沒(méi)有硬件ywrap就賦值為0 */

  __u32 line_length;/*一行的字節數 */

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

  __u32 mmio_len;/*內存映射IO的長(cháng)度*/

  __u32 accel;

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

  };

  fb_ops結構體是對底層硬件操作的函數指針,該結構體中定義了對硬件的操作有:(這里只列出了常用的操作)

  struct fb_ops {

  struct module *owner;

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

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

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

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

  //設置顏色寄存器

  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);

  //復制數據

  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. 幀緩沖設備作為平臺設備:

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

  /* 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(cháng)CD平臺設備定義了一個(gè)s3c2410fb_mach_info結構體,該結構體主要是記錄LCD的硬件參數信息(比如該結構體的s3c2410fb_display成員結構中就用于記錄LCD的屏幕尺寸、屏幕信息、可變的屏幕參數、LCD配置寄存器等),這樣在寫(xiě)驅動(dòng)的時(shí)候就直接使用這個(gè)結構體。下面,我們來(lái)看一下內核是如果使用這個(gè)結構體的。在/arch/arm/mach-s3c2440/mach-smdk2440.c中定義有:

  /* LCD driver info */

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

  static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {

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

  .lcdcon5 = S3C2410_LCDCON5_FRM565 |

  S3C2410_LCDCON5_INVVLINE |

  S3C2410_LCDCON5_INVVFRAME |

  S3C2410_LCDCON5_PWREN |

  S3C2410_LCDCON5_HWSWP,

  .type = S3C2410_LCDCON1_TFT

  //以下一些參數在上面的時(shí)序圖分析中講到過(guò),各參數的值請跟據具體的LCD屏數據手冊結合上面時(shí)序分析來(lái)設定

  };

  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í)它是跟你的開(kāi)發(fā)板LCD控制器密切相關(guān)的,看了下面兩幅圖相信就大概知道他們是干什么用的:

  

 

  

 

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

  從以上講述的內容來(lái)看,要使LCD控制器支持其他的LCD屏,重要的是根據LCD的數據手冊修改以上這些參數的值。下面,我們再看一下在驅動(dòng)中是如果引用到s3c2410fb_mach_info結構體的(注意上面講的是在內核中如何使用的)。在mach-smdk2440.c中有:

  //S3C2440初始化函數

  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));

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

  s3c_device_lcd.dev.platform_data = npd;

  } else {

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

  }

  }

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


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

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

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>