4243|1

1098

帖子

0

TA的资源

至上芯片

楼主
 

uClinux设备驱动程序的设计与编写 [复制链接]

uClinux设备驱动程序的设计与编写
转载:

uClinux设备驱动程序的设计与编写
1设备驱动程序的一般编写步骤
(1) 确定设备的主设备号
(2) 填充static struct file_operation这样的结构
(3) 定义一个类似__init mydriver_init(void)这样的注册函数,大体如下:
int __init mydriver_init(void)
{
        int     rc;
        rc = register_chrdev(mydevice_Major, "mydev", &mydriver_fops);
        if (rc < 0) {
                printk(KERN_WARNING "mydevice: can't get Major %d\n",
                        mydevice_Major);
                return rc;
        }
        printk("mydevice Driver Support.\n");

        return 0;
}
其中mydev表示的设备文件为/dev/mydev X X,即习惯上起名为mydev mydev01 mydev02……如had hda1 hda2 hda3。不过名字是可以随意的。如果成功就返回0,否则返回-1

2 填充驱动程序子函数集struct file_operation结构
(1)驱动程序子函数集struct file_operation结构
struct file_operation结构共有11个成员,分别表示一函数指针,内容及作用说明如下:
struct file_operations {
  /*需要改变文件位置时调用*/
        loff_t (*llseek) (struct file *, loff_t, int);
  /*执行read(2)系统调用时调用*/
        ssize_t (*read) (struct file *, char *, size_t, loff_t *);
  /*执行write(2)系统调用时调用*/
        ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
  /*读目录内容时调用*/
        int (*readdir) (struct file *, void *, filldir_t);
  /*执行poll 系统调用时调用*/
        unsigned int (*poll) (struct file *, struct poll_table_struct *);
  /*执行ioctl(2) 系统调用时调用*/
        int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
  /*执行mmap(2) 系统调用时调用*/
        int (*mmap) (struct file *, struct vm_area_struct *);
  /*打开设备时调用*/
        int (*open) (struct inode *, struct file *);
  /*只在file的使用计数为0时调用,它用来释放file结构*/
        int (*release) (struct inode *, struct file *);
  /*执行fsync(2)系统调用时调用*/
        int (*fsync) (struct file *, struct dentry *);
  /*执行fcntl(2)系统调用时调用*/
        int (*fasync) (int, struct file *, int);
};
(2)根据需要,按以下方法构造上述函数,如:
static int ReadPower(struct inode * inode, struct file * file, char * buffer, int count)
{
if (!Ready)
  return -EAGAIN;
if (count != sizeof(int))
  return -EINVAL;
   copy_to_user(buffer, &myvar, sizeof(int));
         return sizeof(int);
}
这里定义成static是因为该驱动程序子函数在文件外是通过上述的间接方法被调用的,文件外不需要该符号。
(3)把相关操作对应的函数名填入mydevice_operations中
填充static struct file_operations mydevice_operations时,用以上构造的函数名填充相应成员,例如:
struct file_operations TouchPanel_fops = {
        read:  ReadTouchPanel,
        poll:  TouchPanelSelect,
        ioctl:  TouchPanelIoctl,
        open:  OpenTouchPanel,
        release:  CloseTouchPanel,
};

3 中断处理
首先,中断不是必须的。如果设备要用中断模式,就要构造中断处理函数,并注册中断处理函数。
Linux中断处理过程由中断子系统完成;而中断处理函数只是处理具体操作,即读写数据等。成功注册该中断处理函数,就挂接到中断子系统上了。
中断处理一般由两个主要部分组成:
(1)构造中断处理函数void MyDriverInterrupt(int irq, void *dev_id, struct pt_regs *regs),
一般说来,Linux中断处理函数完成工作一方面把设备来的数据读出并保存起来,另一方面把内核中的数据写入设备。这样,驱动程序只需从内核读出数据,把用户提交的数据写入内核;这里可以使用一个简单的数组。
中断处理函数时要防止其他中断的干扰,可用"save_flags(flags); cli();"来关闭中断,相关处理完毕,用"restore_flags(flags)"来恢复。
(2) 注册中断可在mydriver_init()中,也 可在 mydriver_open()中,例如:
  if (request_irq(
               MYDEVICE_IRQ_NUM,
                MyDeviceInterrupt,
                IRQ_FLG_STD,
                "mydevice",
                NULL
            )
  ) {
                printk("TouchPanel: Cannot register interrupt.\n");
                return -EBUSY;
  }
其中:
   MYDEVICE_IRQ_NUM:  注册中断号码
   MyDeviceInterrupt:    中断处理程序
   mydevice:      中断说明(可随便写)
如果返回0,表示成功,否则失败。

4 时间处理
在驱动程序中可以使用定时器来调度函数在未来某个特定时间执行。定时器包括它的超时值(timeout, 单位是jiffies)和超时时调用的函数。定时器列表的数据结构如下:
struct timer_list {
struct list_head list;
unsigned long expires;   /*timeout超时值,以jiffies值为单位*/
unsigned long data;    /*传递给定时器处理程序的参数*/
void (*function)(unsigned long); /*超时调用的定时器处理程序*/
};
定时器的timeout是个"jiffy"值,当jiffies值大于等于timer->expires时,timer->function函数就会执行,timeout值是个绝对数值,它与当前时间无关,不需要更新。
操作定时器有下面几个函数:
void init_timer(struct timer_list *timer);
该函数初始化新分配的定时器队列。
void add_timer(struct timer_list *timer);
该函数将定时器插入挂起的定时器的全局队列。
void del_timer(struct timer_list *timer);
如果需要在定时器超时前将它从列表中删除,应调用del_timer函数。但当定时器超时时,系统会自动地将它从列表中删除。

最新回复

UPG956D.rar  详情 回复 发表于 2009-7-5 18:38
点赞 关注

回复
举报

265

帖子

0

TA的资源

五彩晶圆(初级)

沙发
 
UPG956D.rar

UPG956D.rar

708.98 KB, 下载次数: 5

 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表