|
楼主 |
发表于 2012-5-5 10:37:15
|
显示全部楼层
3 驱动程序的设计
智能家居控制器要多个设备驱动程序,有的驱动程序可以采用标准的驱动程序,有的要专门设计。芯片SIM100-E是通过第三个串口与S3C2410相连的,所以可以直接使用标准的串口驱动程序。传感器接口和家电控制接口要设计专用的驱动程序。控制器的处理器通过外部中断来检测传感器,通过GPIO端口来控制家电,虽然它们的工作原理有所不同,但驱动程序设计的方法没有很大差别,因为在嵌入式Linux系统中设备驱动程序有一个标准的框架,设计驱动程序的大部分工作就是根据硬件结构来“填写”框架中的函数。主要的函数包括open()、read()、write()、ioctl()、release()、module_init()和module_exit()等等。
下面以传感器接口驱动程序设计为例,简介驱动程序的“填写”过程。
3.1 设备初始化模块和退出模块
设备初始化模块的主要功能是:设置和申请中断、向内核注册设备等。设备退出模块的主要功能是:释放设备所占
用的资源。具体函数如下:
int __init s3c2410_int_init(void)
{┅
set_external_irq(IRQ_EINT9, ┅);//设置外部中断
request_irq(IRQ_EINT9,demo_int_handler, ┅);//申请外部中断
ret = register_chrdev(0, DEVICE_NAME, &s3c2410_exio_fops); //申请主设备号
devfs_int_demo= devfs_register(NULL, “int_demo”, ┅); //注册设备文件
┅}
void __exit s3c2410_int_exit(void)
{┅
free_irq(IRQ_EINT9,NULL);//释放中断
devfs_unregister(devfs_int_demo); //删除设备文件
unregister_chrdev(exioMajor, DEVICE_NAME); //释放主设备号
┅}
3.2 打开模块和释放模块
打开模块的主要功能是:初始化一些变量。具体实现函数如下:
static int s3c2410_int_open(struct inode *inode, struct file *filp)
{ init_MUTEX(&demodev.lock);//初始化自旋锁
init_waitqueue_head(&(demodev.wait));初始化队列
MOD_INC_USE_COUNT;//使用计数加1
┅}
static int s3c2410_int_release(struct inode *inode, struct file *filp)
{ MOD_DEC_USE_COUNT; //使用计数减1
┅}
3.3 读数据模块
读数据模块的主要功能是:使线程休眼,然后等待中断来唤醒。具体实现函数如下:
static int s3c2410_int_read(struct file *filp,char *buffer,size_t count,loff_t *ppos)
{┅
copy_to_user(buffer,(char *)&bak,sizeof(bak)); //内核态到用户态
interruptible_sleep_on(&demodev.wait);//进入休眠
┅}
3.4 中断处理模块
中断处理模块的主要功能是:唤醒正在休眼的线程。具体实现函数如下:
static void s3c2410_int_handler(int irq, void *dev_id, struct pt_regs *reg)
{wake_up(&demodev.wait);//中断唤醒
┅}
驱动程序设计完成后,再编写Makefile文件,通过make命令生成目标文件,最后利用insmod命令向内核加载驱动程序。
4 应用程序的设计
为了提高应用程序的运行速度,以及程序运行的稳定性,所以将应用程序设计成多线程结构,如图2所示。应用程序由7个线程和一个共享数据结构组成。 如图2 应用程序结构框图
共享数据主要用于存放家电开启和关闭时间,发送短信的电话号和短信内容等信息。共享数据是通过2个设置线程来修改的。家电控制线程主要是根据控制数据、检测短信线程的内容和操作线程的内容来进行操作。发送短信线程主要是根据控制数据、检测传感器线程的内容和操作线程的内容来进行操作。应用程序的具体内容如下。
#include &nb
sp; //线程库头文件
┅
int main()
{┅
pthread_creat(&th_a,NULL,send_msg,0); //创建发送短信线程
pthread_creat(&th_b,NULL,control_driver,0); //创建家电控制线程
┅
pthread_join(th_b,&retval); //等待家电控制线程结束
pthread_join(th_a,&retval); //等待发送短信线程结束
┅}
/*发送短信线程*/
int send_msg()
{┅
tty_init(); //初始化串口
gprs_init(); //初始化GPRS模块
tty_writecmd(“at”,strlen(“at”)); //发送AT命令
tty_writecmd(“at+cmgf=1”,strlen(“at+cmgf=1”));//发送修改字符集命令
tty_write(“at+cmgs=”,strlen(“at+cmgs=”)); //发送短信命令
tty_writecmd(msg.send_tel,strlen(msg.send_tel)); //发送电话号码
tty_writecmd(msg.send_text,strlen(msg.send_text)); //发送短信内容
tty_end();
┅
return 0;
}
其它线程的设计方法有很多相似之处。应用程序设计完成之后,再经过交叉编译就可生成目标文件。
5 结束语
将移植好的系统、驱动程序和应用程序下载到智能家居控制器上。经过测试,系统具有操作方便、可靠性高和抗干扰能力强等优点。本文的创新点是:通过智能家居控制器将家电、传感器、手机等许多独立的设备连接成为一个系统,从而方便本地和远程控制。 |
|