3 驅(qū)動(dòng)程序的設(shè)計(jì)
智能家居控制器要多個(gè)設(shè)備驅(qū)動(dòng)程序,有的驅(qū)動(dòng)程序可以采用標(biāo)準(zhǔn)的驅(qū)動(dòng)程序,有的要專門設(shè)計(jì)。芯片SIM100-E是通過第三個(gè)串口與S3C2410相連的,所以可以直接使用標(biāo)準(zhǔn)的串口驅(qū)動(dòng)程序。傳感器接口和家電控制接口要設(shè)計(jì)專用的驅(qū)動(dòng)程序。控制器的處理器通過外部中斷來檢測傳感器,通過GPIO端口來控制家電,雖然它們的工作原理有所不同,但驅(qū)動(dòng)程序設(shè)計(jì)的方法沒有很大差別,因?yàn)樵谇度胧絃inux系統(tǒng)中設(shè)備驅(qū)動(dòng)程序有一個(gè)標(biāo)準(zhǔn)的框架,設(shè)計(jì)驅(qū)動(dòng)程序的大部分工作就是根據(jù)硬件結(jié)構(gòu)來“填寫”框架中的函數(shù)。主要的函數(shù)包括open()、read()、write()、ioctl()、release()、module_init()和module_exit()等等。
下面以傳感器接口驅(qū)動(dòng)程序設(shè)計(jì)為例,簡介驅(qū)動(dòng)程序的“填寫”過程。
3.1 設(shè)備初始化模塊和退出模塊
設(shè)備初始化模塊的主要功能是:設(shè)置和申請(qǐng)中斷、向內(nèi)核注冊設(shè)備等。設(shè)備退出模塊的主要功能是:釋放設(shè)備所占
用的資源。具體函數(shù)如下:
int __init s3c2410_int_init(void)
{┅
set_external_irq(IRQ_EINT9, ┅);//設(shè)置外部中斷
request_irq(IRQ_EINT9,demo_int_handler, ┅);//申請(qǐng)外部中斷
ret = register_chrdev(0, DEVICE_NAME, &s3c2410_exio_fops); //申請(qǐng)主設(shè)備號(hào)
devfs_int_demo= devfs_register(NULL, “int_demo”, ┅); //注冊設(shè)備文件
┅}
void __exit s3c2410_int_exit(void)
{┅
free_irq(IRQ_EINT9,NULL);//釋放中斷
devfs_unregister(devfs_int_demo); //刪除設(shè)備文件
unregister_chrdev(exioMajor, DEVICE_NAME); //釋放主設(shè)備號(hào)
┅}
3.2 打開模塊和釋放模塊
打開模塊的主要功能是:初始化一些變量。具體實(shí)現(xiàn)函數(shù)如下:
static int s3c2410_int_open(struct inode *inode, struct file *filp)
{ init_MUTEX(&demodev.lock);//初始化自旋鎖
init_waitqueue_head(&(demodev.wait));初始化隊(duì)列
MOD_INC_USE_COUNT;//使用計(jì)數(shù)加1
┅}
static int s3c2410_int_release(struct inode *inode, struct file *filp)
{ MOD_DEC_USE_COUNT; //使用計(jì)數(shù)減1
┅}
3.3 讀數(shù)據(jù)模塊
讀數(shù)據(jù)模塊的主要功能是:使線程休眼,然后等待中斷來喚醒。具體實(shí)現(xiàn)函數(shù)如下:
static int s3c2410_int_read(struct file *filp,char *buffer,size_t count,loff_t *ppos)
{┅
copy_to_user(buffer,(char *)&bak,sizeof(bak)); //內(nèi)核態(tài)到用戶態(tài)
interruptible_sleep_on(&demodev.wait);//進(jìn)入休眠
┅}
3.4 中斷處理模塊
中斷處理模塊的主要功能是:喚醒正在休眼的線程。具體實(shí)現(xiàn)函數(shù)如下:
static void s3c2410_int_handler(int irq, void *dev_id, struct pt_regs *reg)
{wake_up(&demodev.wait);//中斷喚醒
┅}
驅(qū)動(dòng)程序設(shè)計(jì)完成后,再編寫Makefile文件,通過make命令生成目標(biāo)文件,最后利用insmod命令向內(nèi)核加載驅(qū)動(dòng)程序。
4 應(yīng)用程序的設(shè)計(jì)
為了提高應(yīng)用程序的運(yùn)行速度,以及程序運(yùn)行的穩(wěn)定性,所以將應(yīng)用程序設(shè)計(jì)成多線程結(jié)構(gòu),如圖2所示。應(yīng)用程序由7個(gè)線程和一個(gè)共享數(shù)據(jù)結(jié)構(gòu)組成。
如圖2 應(yīng)用程序結(jié)構(gòu)框圖
共享數(shù)據(jù)主要用于存放家電開啟和關(guān)閉時(shí)間,發(fā)送短信的電話號(hào)和短信內(nèi)容等信息。共享數(shù)據(jù)是通過2個(gè)設(shè)置線程來修改的。家電控制線程主要是根據(jù)控制數(shù)據(jù)、檢測短信線程的內(nèi)容和操作線程的內(nèi)容來進(jìn)行操作。發(fā)送短信線程主要是根據(jù)控制數(shù)據(jù)、檢測傳感器線程的內(nèi)容和操作線程的內(nèi)容來進(jìn)行操作。應(yīng)用程序的具體內(nèi)容如下。
#include &nb
sp; //線程庫頭文件
┅
int main()
{┅
pthread_creat(&th_a,NULL,send_msg,0); //創(chuàng)建發(fā)送短信線程
pthread_creat(&th_b,NULL,control_driver,0); //創(chuàng)建家電控制線程
┅
pthread_join(th_b,&retval); //等待家電控制線程結(jié)束
pthread_join(th_a,&retval); //等待發(fā)送短信線程結(jié)束
┅}
/*發(fā)送短信線程*/
int send_msg()
{┅
tty_init(); //初始化串口
gprs_init(); //初始化GPRS模塊
tty_writecmd(“at”,strlen(“at”)); //發(fā)送AT命令
tty_writecmd(“at+cmgf=1”,strlen(“at+cmgf=1”));//發(fā)送修改字符集命令
tty_write(“at+cmgs=”,strlen(“at+cmgs=”)); //發(fā)送短信命令
tty_writecmd(msg.send_tel,strlen(msg.send_tel)); //發(fā)送電話號(hào)碼
tty_writecmd(msg.send_text,strlen(msg.send_text)); //發(fā)送短信內(nèi)容
tty_end();
┅
return 0;
}
其它線程的設(shè)計(jì)方法有很多相似之處。應(yīng)用程序設(shè)計(jì)完成之后,再經(jīng)過交叉編譯就可生成目標(biāo)文件。
5 結(jié)束語
將移植好的系統(tǒng)、驅(qū)動(dòng)程序和應(yīng)用程序下載到智能家居控制器上。經(jīng)過測試,系統(tǒng)具有操作方便、可靠性高和抗干擾能力強(qiáng)等優(yōu)點(diǎn)。本文的創(chuàng)新點(diǎn)是:通過智能家居控制器將家電、傳感器、手機(jī)等許多獨(dú)立的設(shè)備連接成為一個(gè)系統(tǒng),從而方便本地和遠(yuǎn)程控制。
評(píng)論
查看更多