新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 基于Linux/Qtopia的车载温度网络采集

基于Linux/Qtopia的车载温度网络采集

作者:中国海洋大学 刘滨 王永才 张冰,青岛农业大学 赵艳华 时间:2008-08-29 来源:单片机与嵌入式系统应用 收藏

3.2.2  读接口函数

本文引用地址:https://www.eepw.com.cn/article/87552.htm

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

_read( ) {
  DECLARE_WAITQUEUE(wait,current);//声明等待队列……
Next_try:
  if(dev.head != dev.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;
    }//如果缓冲区为空,内核调度,等待通知
  current>state = TASK_RUNNING;//得到有数据的通知,声明任务状态为运行
  remove_wait_queue(&queue,&wait);//删除等待队列
  goto Next_try;//返回到读取数据
  }
}

3.2.3  fasync异步通知函数

  异步通知函数向进程发送SIGIO信号,通知访问设备的进程,表示设备已经准备好I/O读写了,避免主动查询,提高程序效率。使用异步通知需增加一个struct fasync_struct的结构指针,然后实现fasync接口函数。

static struct fasync_struct *fasync;//定义一个结构体
static int DS18B20_fasync(int fd,struct file *filp,int on) {//实现接口函数
  retval = fasync_helper(fd,filp,on,&fasync);
  if ( retval<0) return retval;return 0;
}

  最后在需要向用户空间通知的地方调用内核的kill_fasync函数。在打开设备函数中提到的DS18B20Event()功能是:将数据放入循环缓冲区,唤醒等待队列并启动异步通知,其后两项功能是这样实现的:
  wake_up_interruptible(&queue);//唤醒等待队列
  if (fasync) {
  kill_fasync(&fasync,SIGIO,POLL_IN);//发送异步通知信号
  }

3.2.4  poll系统调用操作接口函数

  当程序需要进行对多个文件读写时,如果某个文件没有准备好,则系统就会处于读写阻塞的状态,影响其他文件的读写。为了避免读写阻塞,使用poll函数。如果设备无阻塞地读,就返回POLLIN; 通常的数据已经准备好,可以读了,就返回POLLRDNORM。

static unsigned int DS18B20_poll(struct file *flip, poll_table *wait) {
  poll_wait(flip,&queue,wait);
  if(DS18B20dev.head != DS18B20dev.tail) {
    return POLLIN|POLLRDNORM;
  }
  return 0;
}

3.2.5  release释放设备函数

static intDS18B20_release(struct inode *inode,struct file *filp) {
  ReleaseFlag=0//内核停止读取温度标志
  DS18B20_fasync(1,filp,0);//关闭异步通知
  module_put(THIS_MODULE);//设备计数器减1
  return 0;
}

  写接口函数用来通知驱动。例如通知驱动读取通道2的数据,在应用程序中执行写接口函数write(fileno,&SLOT2,1),驱动设置当前读通道号为2。

  至此完成驱动接口函数。此驱动属于字符设备驱动,将源程序放在driver/char 目录下。同时需要修改该目录下的Kconfig配置文件并添加 Config 18B20_S3C2410选项,修改driver/char/Makefile,添加obj$(CONFIG_18B20_S3C2410) +=S3C2410_18B20.O。最后重新配置内核,将驱动以模块形式添加到内核,这样就可以编译驱动了。

应用程序设计

(1) 创建工程

  首先利用QT Designer设计器创建一个窗体应用程序ThermometerFigure.ui。窗体程序创建好后根据需要添加窗体控件、槽函数、信号等。图3为ThermometerFigure类的实现框图。

(2) ThermometerFigure类实现

  利用uic工具产生相应的*.cpp和*.h文件(窗体类的实现文件和头文件)。编辑*.cpp和*.h文件实现各成员函数、信号槽的连接。具体实现如图3所示。

(3) 创建main及初始化

  首先创建main.cpp文件,并在main.cpp 中创建QApplication 对象。QApplication 类负责图像用户界面应用程序的控制流和主设置,对所有来自系统和其他源文件的事件进行处理和调度;还包括应用程序的初始化和结束。

int main( int argc, char **argv ) {
  QApplication app(argc,argv);
  ThemometerFigure wyc;//创建对象
  app.setMainWidget( &wyc );//选为主窗体
  wyc.show(); return app.exec();
}

(4) 编辑*.pro文件并生成Makefile

  利用progen工具创建Thermometer.pro,具体实现如下:

TEMPLATE=app
CONFIG=qt warn_on release
HEADERS=ThermometerFigure.h
SOURCES=ThermometerFigure.cpp \ main.cpp
INTERFACES=

  执行qmake命令生成Makefile文件,执行之前要设置相关的环境变量,编译器路径等。

  qmakeo Makefile Thermometer.pro

(5)  编译链接工程

  执行make命令,将生成目标二进制文件Thermometer,此文件即可在设备上运行。



图3  ThermometerFigure类的实现框图



图4  ThermometerFigure类实现界面

(6)  将可执行文件发布到系统

  将可执行文件添加到的根文件系统中,将生成的新的根文件系统烧写到设备的Flash根文件系统区,这样就可以在桌面运行程序了。图4为 ThermometerFigure类实现界面。

结语

  本文介绍了车载信息系统开发的部分实现方法。通过实例讲述了的开发过程,包括驱动开发和应用程序开发流程。创新点在于将一线制传感器网络引入系统,大大简化了线路结构,有很高的实用价值。

参考文献

[1]  郑灵翔,等.系统设计与应用开发[M].北京:北京航空航天大学出版社,2006.
[2]  南金瑞,等.车载信息系统开发与应用[M].北京:电子工业出版社,2006.
[3]  朱青,等.及其在机车定置试验台温度采集系统中的应用[J].电气应用,2006,25(9).

刘滨(教授),主要研究方向为系统、网络化智能仪器仪表;
王永才、张冰(硕士研究生),
赵艳华(讲师),研究方向为嵌入式系统。

linux操作系统文章专题:linux操作系统详解(linux不再难懂)

上一页 1 2 下一页

评论


相关推荐

技术专区

关闭