《智能家居》培训第五天------2019-01-09
目錄:
一)視頻播放
二)內(nèi)存映射函數(shù)mmap()
三)線程
四)觸摸屏
五)所想
六)總結(jié)
?
?
一)視頻播放
1)要求:界面要求如下圖,菜單欄包含播放、暫停、繼續(xù)、停止以及返回功能
2)視頻功能的實(shí)現(xiàn)
播放視頻依然是用mplayer文件,各功能對(duì)應(yīng)指令如下:
1 system("mplayer -x 800 -y 400 -zoom name.avi &"); //播放name.avi這個(gè)視頻,視頻寬為800px,高為400px 2 system("killall -STOP mplayer &"); //暫停視頻 3 system("killall -CONT mplayer &"); //繼續(xù)視頻 4 system("killall mplayer"); //結(jié)束視頻3)菜單欄界面的實(shí)現(xiàn)
菜單欄其實(shí)就是一張界面圖,和顯示主界面顯示音樂(lè)界面是同一個(gè)道理,只不過(guò)它是在固定位置顯示界面圖,老師給了我們一個(gè)接口函數(shù)實(shí)現(xiàn)這個(gè)功能:
int show_shapebmp(int x,int y,int w,int h,char *bmpname);
這個(gè)函數(shù)可以把圖片以固定大小放在固定位置,使用到了linux的內(nèi)存映射函數(shù)mmap(),mmap()函數(shù)放在第二點(diǎn)進(jìn)行學(xué)習(xí)。
4)遇到的問(wèn)題
做法和做音樂(lè)功能差不多,框架基本相同,但是這樣拷到開發(fā)板運(yùn)行時(shí)會(huì)有一個(gè)問(wèn)題:播放視頻后菜單欄被覆蓋,即菜單欄界面無(wú)法顯示,不過(guò)菜單欄所在位置的暫停繼續(xù)等功能依然可以正常使用,解決這一問(wèn)題的方法就是使用線程,線程放在第三點(diǎn)講解。
二)內(nèi)存映射函數(shù)mmap()
1)同樣是顯示界面的功能,show_shapebmp()就比show_screen()高級(jí)了,可以調(diào)整顯示位置,不需要預(yù)先翻轉(zhuǎn)圖片,實(shí)現(xiàn)方法是將屏幕地址映射到用戶空間(mmap),show_screen()是使用的read和write函數(shù)來(lái)實(shí)現(xiàn)的界面顯示,就是文件讀寫可以使用read和write函數(shù),也可以使用mmap()實(shí)現(xiàn)對(duì)文件的讀寫。
2)mmap的學(xué)習(xí)
點(diǎn)擊這個(gè)鏈接學(xué)習(xí)mmap,這篇博客寫滴很棒我覺(jué)得
三)線程(看不懂的話沒(méi)關(guān)系,結(jié)合著例子看就懂了,例子在本點(diǎn)最后給出)
1)問(wèn)題描述
點(diǎn)擊視頻進(jìn)入視頻界面,當(dāng)播放視頻時(shí)菜單欄無(wú)法顯示,就是此時(shí)屏幕上只有一種操作,要么播放視頻,要么顯示菜單欄,二者不能夠同時(shí)發(fā)生,但是我們又希望它同時(shí)發(fā)生。
2)主線程與子線程
解決上述問(wèn)題的方法就是把用戶交互和視頻播放這兩個(gè)事情分離開來(lái),由此需要用到線程,主線程響應(yīng)用戶交互,子線程響應(yīng)視頻播放。
3)線程理解
目前對(duì)線程只是處于了解層面,培訓(xùn)時(shí)也只是講一點(diǎn)必要的,以下內(nèi)容只是目前的個(gè)人理解,正確與否希望大家不吝賜教啦。
①主線程就是程序正常運(yùn)行時(shí)的走的路,比如此刻正在執(zhí)行main函數(shù)的第n行,那么此時(shí)程序的運(yùn)行就是主線程,如果我們希望在執(zhí)行完這一行后就開始播放視頻,也就是增加一條路,讓它去播放視頻,這條路就叫做子線程,圖解如下,主線程和子線程的運(yùn)行不會(huì)互相干擾,就是兩者可以同時(shí)進(jìn)行。
②創(chuàng)建子線程的函數(shù)原型以及參數(shù)解釋
1 頭文件:2 #include <pthread.h>3 原型:4 int pthread_create(pthread_t *thread, const pthread_attr_t *attr,5 void *(*start_routine) (void *), void *arg);6 參數(shù)一:線程的id7 參數(shù)二:線程的屬性 ---- 設(shè)置成NULL就行8 參數(shù)三:線程要執(zhí)行的函數(shù)9 void *(*start_routine) (void *) ---- 函數(shù)指針 start_routine--函數(shù)指針變量 10 函數(shù)類型:void *start_routine (void *) 11 第三個(gè)參數(shù)應(yīng)該傳入的是函數(shù)的地址 --- 也就是函數(shù)名 12 參數(shù)四:該參數(shù)做為參數(shù)三的函數(shù)的傳參 --- 設(shè)置成NULL就行 13 14 返回值: 創(chuàng)建子線程是否成功 15 成功:0 16 出錯(cuò):錯(cuò)誤的數(shù)字4)使用實(shí)例
總結(jié)一下目前掌握的線程使用方法:
①寫好子線程函數(shù)
②在想要插入的地方插入,創(chuàng)建子線程
③末尾加上pthread_join()函數(shù)
四)觸摸屏
1)觸摸屏的原理
①“觸摸屏”是一種設(shè)備文件,意思就是說(shuō)有這么一個(gè)文件,這個(gè)文件上的內(nèi)容專門用于描述用戶對(duì)屏幕觸摸的操作。
②當(dāng)用戶點(diǎn)擊觸摸屏?xí)r,linux系統(tǒng)就會(huì)記錄下用戶的操作,比如記錄下所觸摸位置的xy坐標(biāo),然后把這個(gè)記錄下來(lái)的信息是保存到這個(gè)“觸摸屏”文件中。
③那么觸摸位置就確定了,這個(gè)時(shí)候我們就只需要讀取出這個(gè)文件中保存的位置坐標(biāo),就可以得到用戶觸摸的位置,根據(jù)此位置就可以實(shí)現(xiàn)自己想要實(shí)現(xiàn)的功能。
④舉個(gè)例子:我們希望當(dāng)用戶點(diǎn)擊某個(gè)區(qū)域時(shí),播放一首歌,那么相應(yīng)的邏輯就是→用戶觸摸屏幕→觸摸位置的坐標(biāo)被保存到“觸摸屏”文件中→從該文件中讀取用戶觸摸的位置→判斷該位置是不是播放音樂(lè)的位置→如果是就播放音樂(lè)
2)input.h
linux系統(tǒng)把觸摸屏當(dāng)做一種輸入設(shè)備,觸摸屏幕相當(dāng)于向linux系統(tǒng)輸入數(shù)據(jù),描述這整個(gè)功能的文件就是input.h文件
input.h文件保存在linux系統(tǒng)的linux目錄里,通過(guò)cd /usr/include/linux進(jìn)入到linux目錄,通過(guò)ls可以查看到input.h這個(gè)文件,可以在linux或者windows下查看input.h頭文件的內(nèi)容
①vi input.h-------在linux查看
②cp input.h /mnt/hgfs/smarthome--------把它拷貝到共享文件夾里在windows查看
3)input.h中對(duì)觸摸屏的描述(建議結(jié)合實(shí)例一起看,不然可能比較不懂)
1 /* 2 * The event structure itself 3 */ 4 struct input_event { 5 struct timeval time; //事件發(fā)生的時(shí)間 6 __u16 type; //事件發(fā)生的類型:觸摸屏 7 __u16 code; //x軸 或者 Y軸 8 __s32 value; //x的坐標(biāo)或者y的坐標(biāo) 9 }; 10 為了使用該結(jié)構(gòu)體,必須包含其頭文件 : 11 #include<linux/input.h> 12 #include <unistd.h> 13 定義該結(jié)構(gòu)體變量時(shí) 14 struct input_event* ts_event; //error 15 struct input_event ts_event; //ok 16 宏定義一些值 17 #define EV_ABS 0x03 ---- 觸摸屏 18 #define ABS_X 0x00 ----- x軸 19 #define ABS_Y 0x01 ----- y軸 input.h4)實(shí)例
1 /****************************************2 *功能:獲取觸摸屏的坐標(biāo)3 *參數(shù):x----x坐標(biāo)4 * y----y坐標(biāo)5 *****************************************/6 #include <linux/input.h> 7 #include <unistd.h>8 int fd_ts = open("/dev/event0",O_RDWR); //打開開發(fā)板的觸摸屏9 void get_xy(int* x,int* y) 10 { 11 struct input_event ts_event; 12 //兩個(gè)標(biāo)志位 13 int get_x=0; 14 int get_y=0; 15 //觸摸屏幕引發(fā)檢測(cè),進(jìn)入while循環(huán),一次點(diǎn)擊掃描兩次,第一次掃描x軸,第二次掃描y軸 16 while(1) 17 { 18 /*點(diǎn)擊屏幕,會(huì)產(chǎn)生觸摸信息,該信息被保存到fd_ts文件里, 19 然后通過(guò)read把這個(gè)信息保存到結(jié)構(gòu)體變量ts_event里*/ 20 read(fd_ts,&ts_event,sizeof(struct input_event)); 21 //判斷ts_event里的各種值 22 if(ts_event.type == EV_ABS) //觸摸屏發(fā)生 23 { 24 //第一次掃描x軸,只要點(diǎn)擊屏幕,x軸就有值,get_x就改變標(biāo)志 25 if(ts_event.code == ABS_X) 26 { 27 *x = ts_event.value;//把x坐標(biāo)保存到變量x里 28 get_x++; 29 } 30 //第二次掃描y軸,只要點(diǎn)擊屏幕,y軸就有值,get_y就改變標(biāo)志 31 if(ts_event.code == ABS_Y) 32 { 33 *y = ts_event.value;//把y坐標(biāo)保存到變量y里 34 get_y++; 35 } 36 } 37 //兩次掃描過(guò)后得到x和y的坐標(biāo),就說(shuō)明已經(jīng)得到了xy的坐標(biāo),于是退出循環(huán)結(jié)束該函數(shù) 38 if(get_x == 1 && get_y==1) 39 { 40 break; 41 } 42 } 43 } sample五)所想
1)如果老師可以詳細(xì)講一下mmap就好了,聽老師講的話感覺(jué)會(huì)更好理解
2)感覺(jué)線程挺有意思的
3)視頻界面圖
六)總結(jié)
? 1)完成了視頻這塊功能
2)學(xué)習(xí)了mmap內(nèi)存映射文件的方法
3)學(xué)習(xí)了使用線程實(shí)現(xiàn)兩個(gè)模塊同時(shí)進(jìn)行
4)總結(jié)了觸摸屏獲取觸摸坐標(biāo)的方法
轉(zhuǎn)載于:https://www.cnblogs.com/lzemian-n/p/10253250.html
總結(jié)
以上是生活随笔為你收集整理的《智能家居》培训第五天------2019-01-09的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 根据时间格式字符串取出时分秒各自的数值
- 下一篇: Python使用LDAP做用户认证