6/25/2011 9:30:09 PM

本文深入探讨了Linux内核中用于管理硬件设备的平台设备结构及其驱动机制,包括平台设备的组成、如何通过驱动探测硬件、描述机器信息的pxafb_mach_info结构、以及初始化fb_info结构的过程,特别是对fb_var_screeninfo结构中关键字段的解释,展示了如何配置显示设备的基本原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

6/25/2011 9:30:09 PM

struct platform_device {
 const char * name;
 u32  id;
 struct device dev;
 u32  num_resources;
 struct resource * resource;
};

平台设备包含了名字 ID 设备 资源等

驱动来探测设备

struct pxafb_mach_info

描述机器信息

也就是所谓的设备的平台数据

首先检测各寄存器的值,看这些值是否有效

struct pxafb_info {
 struct fb_info  fb;
 
封装了fb_info等

 fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL);
 
 注意后面还预留了16个int
 
  接着对结构体 pxafb_info 进行赋值
 
  struct fb_ops 描述了fb的操作方法
 
  static struct fb_ops pxafb_ops = {
 .owner  = THIS_MODULE,
 .fb_check_var = pxafb_check_var,
 .fb_set_par = pxafb_set_par,
 .fb_setcolreg = pxafb_setcolreg,
 .fb_fillrect = cfb_fillrect,
 .fb_copyarea = cfb_copyarea,
 .fb_imageblit = cfb_imageblit,
 .fb_blank = pxafb_blank,
 .fb_mmap = pxafb_mmap,
#ifdef CONFIG_FB_PXA_MINILCD
 .fb_ioctl = pxafb_minilcd_ioctl,
#elif defined(CONFIG_FB_PXA_LCD_TPO)
 .fb_ioctl = pxafb_lcd_ioctl,
#endif
};

 pxafb_check_var 检查可变参数
 
看看上层是怎么设置的?

     ov2_info->fd = open("/dev/fb2", O_RDWR);

首先打开设备

接着设置了可变参数

    struct fb_var_screeninfo var;
   
    err = ioctl(fd, FBIOPUT_VSCREENINFO, &var);
   
   
   
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 */
};


 if (var->xres < MIN_XRES)
  var->xres = MIN_XRES;
 if (var->yres < MIN_YRES)
  var->yres = MIN_YRES;
  
也就是说最小打开的也是16*16的

 if (var->xres > fbi->max_xres)
  var->xres = fbi->max_xres;
 if (var->yres > fbi->max_yres)
  var->yres = fbi->max_yres;
 var->xres_virtual =
  max(var->xres_virtual, var->xres);
 var->yres_virtual =
  max(var->yres_virtual, var->yres);

也不能超过实际最大值

x y 的虚拟坐标也取最大值

接着设置RGB的位数


初试化等待队列

static void pxafb_task(struct work_struct *work)
{
 struct pxafb_info *fbi =
  container_of(work, struct pxafb_info, task);
 u_int state = xchg(&fbi->task_state, -1);

 set_ctrlr_state(fbi, state);
}

注意这个work_struct


pxafb_disable_controller disable掉控制器


typedef struct __wait_queue wait_queue_t;
typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int sync, void *key);
int default_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);

struct __wait_queue {
 unsigned int flags;
#define WQ_FLAG_EXCLUSIVE 0x01
 void *private;
 wait_queue_func_t func;
 struct list_head task_list;
};

声明了一个等待队列

 down(&fcs_lcd_sem);
 add_wait_queue(&fbi->ctrlr_wait, &wait);
 
 将到fbi的等待队列中
 
 #define LCSR  __REG_2(0x44000038) /* LCD Controller Status Register */
 
 LCD 的状态寄存器
 
 
 /*
 * 0x42000000 - 0x421fffff <--> 0xf8000000 - 0xf81fffff  MMC2 & USIM2
 * 0x43000000 - 0x430fffff <--> 0xf8200000 - 0xf82fffff  Caddo
 * 0x43100000 - 0x431fffff <--> 0xf8300000 - 0xf83fffff  NAND
 * 0x44000000 - 0x440fffff <--> 0xf8400000 - 0xf84fffff  LCD
 * 0x46000000 - 0x460fffff <--> 0xf8800000 - 0xf88fffff  Mini LCD
 * 0x48100000 - 0x481fffff <--> 0xf8d00000 - 0xf8dfffff  Dynamic Mem Ctl
 * 0x4a000000 - 0x4a0fffff <--> 0xf9000000 - 0xf90fffff  Static Mem Ctl
 * 0x4c000000 - 0x4c0fffff <--> 0xf9400000 - 0xf94fffff  USB Host
 */

#define io_p2v_2(x) (((((x) - 0x42000000) & 0xff000000) >> 3) + 0xf8000000/
    + ((x) & 0x001fffff))
#define io_v2p_2(x) (((((x) & 0xffe00000) - 0xf8000000) << 3) + 0x42000000/
    + (x & 0x001fffff))
    

LCD的地址映射关系

系统给LCD 预留有1M的地址空间

schedule_timeout 调用超时

如果输入参数为 MAX_SCHEDULE_TIMEOUT

就表示是一个完整的调用,不需要中间进行截断

否则还需要使用一个定时器

建立了一个定时器 定时唤醒本进程的

 setup_timer(&timer, process_timeout, (unsigned long)current);
 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值