首 页文档资料下载资料维修视频包年699元
请登录  |  免费注册
当前位置:精通维修下载 > 文档资料 > 家电技术 > 单元电路介绍 > 其它电路
采用Linux/Qtopia的车载温度网络采集
来源:本站整理  作者:佚名  2011-08-03 06:16:40



3  驱动实现

  本节将实现一线制温度传感器网络的驱动模块。驱动从总体上看分为两部分:驱动与内核接口层、硬件设备接口层。

3.1  驱动与内核接口层

  驱动与内核接口层主要完成驱动模块在Linux内核的注册加载、卸载清除工作。这部分工作分别由初始化和退出函数完成。

  ① 初始化函数完成驱动模块加载:

statIC int __init DS18B20_init(void){
  ……
  register_chrdev(DS18B20_MAJOR,DEVICE_NAME, &DS18B20_fops);//完成设备注册
  #ifdefCONFIG_DEVFS_FS//创建设备文件系统
    devfs_mk_cdev(MKDEV(DS18B20_MAJOR,0),S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,DEVICE_NAME);
  #endif
  ……
}

  ② 退出函数完成驱动模块卸载:

static void __exit DS18B20_exit(void) {
  #ifdef CONFIG_DEVFS_FS
    devfs_remove(DEVICE_NAME);//移除设备文件
  #endif
  unregister_chrdev(DS18B20_MAJOR,DEVICE_NAME); //完成设备注销
  ……
}

3.2  硬件设备接口层

  硬件设备接口层用来描述驱动程序与设备的交互。这些工作通过虚拟文件系统与设备驱动程序的接口实现。这个接口由file_operation结构定义,其结构如下:

static struct file_operations DS18B20_fops ={
  .owner=THIS_MODULE, //指向拥有该结构的模块,内核使用该结构维护模块使用计数
  .open=DS18B20_open, //打开设备函数
  .read=DS18B20_read, //读接口函数
  .write=DS18B20_write,//写接口函数
  .fasync=DS18B20_fasync, //异步通知函数
  .poll=DS18B20_poll,//poll函数
  .release=DS18B20_release, //释放设备函数
};

3.2.1  打开设备函数

  打开设备函数主要完成设备的初始化。

DS18B20_open(struct inode *inode,struct file *filp) {
  Initial_Timer( );//初始化定时器,使内核模块按一定周期读温度
  Initial_Device_DS18B20();//初始化硬件
  readtemperature();//开始读取……
}
void readtemperature(void) {
  ……Temperature=DS18B20read();//读取2个8位数据,此函数完成的硬件操作时序,由当前读通道号变量指定当前通道
  DS_SLOT_NO();//将本次读通道号放入缓冲区
  DS18B20Event();//数据放入缓冲区,唤醒等待队列并启动异步通知
  if(ReleaseFlag)
  CycleTimer_Delay_SOFt(hdelay);//如果没有读停止信号,通过内核定时器延时,进行下一次读,在中断服务程序中再次启动读
  ……
}

  在使用内核定时器之前需定义一个定时器结构体 static struct timer_list CycleTimer。下面是定时器的具体操作:

static void Initial_Timer(void) {
  init_timer(&CycleTimer); );//初始化定时器结构
  CycleTimer.function=DS18B20_timer; //挂接定时中断服务程序
}

3.2.2  读接口函数

  用户程序执行读操作的时候可能没有可以读取的数据,此时需要让read操作等待直到有数据可以读取。在此采用等待队列使进程在无数据读取时进入等待,数据到达时唤醒。等待队列设置成一个循环缓冲区,每放入一个新数据作为缓冲区的头,存放时间最久还未被取走的数据为缓冲区的尾。

DS18B20_read( ) {
  DECLARE_WAITQUEUE(wait,current);//声明等待队列……
Next_try:
  if(DS18B20dev.head != DS18B20dev.tail) {//等待队列不为空,即有数据
  DS18B20_ret=Read_Buffer_DS18B20(); //取走缓冲区的尾
  copy_to_user( ); //读取的数据送到用户空间
}
  else { ……//等待队列为空,即没有数据
  add_wait_queue(&queue,&wait);
  current>state=TASK_INTERRUPTIBLE;//添加等待队列,声明状态为任务可中断
  while((DS18B20dev.head==DS18B20dev.tail)&&!signal_pending(current) {//进入等待
  schedule();
  current>state=TASK_INTERRUPTIBLE;
    }//如果缓冲区为空,Linux内核调度,等待通知
  current>state = TASK_RUNNING;//得到有数据的通知,声明任务状态为运行
  remove_wait_queue(&queue,&wait);//删除等待队列
  goto Next_try;//返回到读取数据
  }
}

上一页  [1] [2] [3] [4]  下一页

关键词:

文章评论评论内容只代表网友观点,与本站立场无关!

   评论摘要(共 0 条,得分 0 分,平均 0 分)
Copyright © 2007-2017 down.gzweix.Com. All Rights Reserved .
页面执行时间:110,890.60000 毫秒