LCD驱动程序:

假设打开的文件主设备号为:29,次设备号为:0

应用程序: open("/dev/fb0" ...) 主设备号: 29, 次设备号: 0

------------------------------------------------------------

kernel:

fb_open

int fbidx = iminor(inode); // 得到设备节点的次设备号。

//struct fb_info *info == registered_fb[fbidx];

struct fb_info *info == registered_fb[0]; // 假设次设备号为0

应用程序: read()

-------------------------------------------------------------

kernel:

fb_read

//int fbidx = iminor(inode);

int 0 = iminor(inode);

struct fb_info *info = registered_fb[fbidx];

//src = (u32 __iomem *) (info->screen_base + p);   // screen_base显存基地址

if (info->fbops->fb_read)                   // 如果有读函数

return info->fbops->fb_read(info, buf, count, ppos);

src = (u32 __iomem *) (info->screen_base + p); // 如果没有读函数

dst = buffer;

*dst++ = fb_readl(src++);

copy_to_user(buf, buffer, c)

---------------------------------------------------------------

综上,read和open都依赖于fb_info结构体,而fb_info结构体又依赖于regiseted_fb以次设备号为下标得到。

registered_fb[fbidx]数组在哪里被设置?

register_framebuffer (向核心层注册硬件设备的信息如,s3c2410fb.c、Atmel_fb.c等)

怎么写LCD驱动程序?

1,分配一个fb_info结构体    fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev)

2,设置

3,注册  register_framebuffer

4,硬件相关的操作  ioctrl  FBIOGET_VSCREENINFO(可变的屏幕信息)其中的V即为Var

if (!fb)

return -ENODEV;

switch (cmd) {

case FBIOGET_VSCREENINFO:

return copy_to_user(argp, &info->var,

sizeof(var)) ? -EFAULT : 0;

struct fb_info {

int node;

int flags;

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 */

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_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 */

};

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 */

};

测试:

1,make menuconfig去掉原来的驱动程序,以避免对新的驱动程序有影响,去掉的是S3C2410 LCD framebuffer support编译成模块,因为还要调用里面的cfbcopyarea.ko,cfbfillrect.ko,cfbimgblt.ko。

2,make uImage

make modules

3,使用新的uImage启动开发板。

4,insmod cfbcopyarea.ko

insmod cfbfillrect.ko

insmod cfbimgblt.ko

insmod lcd.ko

echo hello > /dev/tty1 //可以在LCD上显示hello

cat lcd.ko > /dev/fb0  // 花屏

5,另一种测试方法:修改/etc/inittab增加一行

tty1::askfirst:-/bin/sh

用新内核重启

insmod cfbcopyarea.ko

insmod cfbfillrect.ko

insmod cfbimgblt.ko

insmod lcd.ko

insmod buttons.ko

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐