《智能家居》培训第五天------2019-01-09

目录:

  一)视频播放

  二)内存映射函数mmap()

  三)线程

  四)触摸屏

  五)所想

  六)总结

 

 

一)视频播放

  1)要求:界面要求如下图,菜单栏包含播放、暂停、继续、停止以及返回功能

  2)视频功能的实现

  播放视频依然是用mplayer文件,各功能对应指令如下:

1 system("mplayer -x 800 -y 400 -zoom name.avi &");    //播放name.avi这个视频,视频宽为800px,高为400px        
2 system("killall -STOP mplayer &");     //暂停视频
3 system("killall -CONT mplayer &");    //继续视频
4 system("killall mplayer");    //结束视频

  3)菜单栏界面的实现

  菜单栏其实就是一张界面图,和显示主界面显示音乐界面是同一个道理,只不过它是在固定位置显示界面图,老师给了我们一个接口函数实现这个功能:

  int show_shapebmp(int x,int y,int w,int h,char *bmpname);

  这个函数可以把图片以固定大小放在固定位置,使用到了linux的内存映射函数mmap(),mmap()函数放在第二点进行学习。

  4)遇到的问题

  做法和做音乐功能差不多,框架基本相同,但是这样拷到开发板运行时会有一个问题:播放视频后菜单栏被覆盖,即菜单栏界面无法显示,不过菜单栏所在位置的暂停继续等功能依然可以正常使用,解决这一问题的方法就是使用线程,线程放在第三点讲解。

二)内存映射函数mmap()

  1)同样是显示界面的功能,show_shapebmp()就比show_screen()高级了,可以调整显示位置,不需要预先翻转图片,实现方法是将屏幕地址映射到用户空间(mmap),show_screen()是使用的read和write函数来实现的界面显示,就是文件读写可以使用read和write函数,也可以使用mmap()实现对文件的读写。

  2)mmap的学习

  点击这个链接学习mmap,这篇博客写滴很棒我觉得

三)线程(看不懂的话没关系,结合着例子看就懂了,例子在本点最后给出)

  1)问题描述

  点击视频进入视频界面,当播放视频时菜单栏无法显示,就是此时屏幕上只有一种操作,要么播放视频,要么显示菜单栏,二者不能够同时发生,但是我们又希望它同时发生。

  2)主线程与子线程

  解决上述问题的方法就是把用户交互和视频播放这两个事情分离开来,由此需要用到线程,主线程响应用户交互,子线程响应视频播放。

  3)线程理解

  目前对线程只是处于了解层面,培训时也只是讲一点必要的,以下内容只是目前的个人理解,正确与否希望大家不吝赐教啦。

  ①主线程就是程序正常运行时的走的路,比如此刻正在执行main函数的第n行,那么此时程序的运行就是主线程,如果我们希望在执行完这一行后就开始播放视频,也就是增加一条路,让它去播放视频,这条路就叫做子线程,图解如下,主线程和子线程的运行不会互相干扰,就是两者可以同时进行。

  ②创建子线程的函数原型以及参数解释

 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         参数一:线程的id
 7         参数二:线程的属性  ---- 设置成NULL就行
 8         参数三:线程要执行的函数
 9         void *(*start_routine) (void *) ---- 函数指针 start_routine--函数指针变量
10         函数类型:void *start_routine (void *)
11         第三个参数应该传入的是函数的地址  --- 也就是函数名
12         参数四:该参数做为参数三的函数的传参 --- 设置成NULL就行
13 
14   返回值: 创建子线程是否成功
15           成功:0
16           出错:错误的数字    

  4)使用实例

  总结一下目前掌握的线程使用方法:

  ①写好子线程函数

  ②在想要插入的地方插入,创建子线程

  ③末尾加上pthread_join()函数

四)触摸屏

  1)触摸屏的原理

  ①“触摸屏”是一种设备文件,意思就是说有这么一个文件,这个文件上的内容专门用于描述用户对屏幕触摸的操作。

  ②当用户点击触摸屏时,linux系统就会记录下用户的操作,比如记录下所触摸位置的xy坐标,然后把这个记录下来的信息是保存到这个“触摸屏”文件中。

  ③那么触摸位置就确定了,这个时候我们就只需要读取出这个文件中保存的位置坐标,就可以得到用户触摸的位置,根据此位置就可以实现自己想要实现的功能。

  ④举个例子:我们希望当用户点击某个区域时,播放一首歌,那么相应的逻辑就是→用户触摸屏幕→触摸位置的坐标被保存到“触摸屏”文件中→从该文件中读取用户触摸的位置→判断该位置是不是播放音乐的位置→如果是就播放音乐

  2)input.h

  linux系统把触摸屏当做一种输入设备,触摸屏幕相当于向linux系统输入数据,描述这整个功能的文件就是input.h文件

  input.h文件保存在linux系统的linux目录里,通过cd /usr/include/linux进入到linux目录,通过ls可以查看到input.h这个文件,可以在linux或者windows下查看input.h头文件的内容

  ①vi input.h-------在linux查看

  ②cp input.h /mnt/hgfs/smarthome--------把它拷贝到共享文件夹里在windows查看

  3)input.h中对触摸屏的描述(建议结合实例一起看,不然可能比较不懂)

 1 /*
 2 * The event structure itself
 3 */
 4 struct input_event {
 5     struct timeval time; //事件发生的时间
 6     __u16 type; //事件发生的类型:触摸屏
 7     __u16 code; //x轴 或者 Y轴
 8     __s32 value; //x的坐标或者y的坐标
 9 };
10 为了使用该结构体,必须包含其头文件 :
11 #include<linux/input.h>
12 #include <unistd.h>
13 定义该结构体变量时
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.h

  4)实例

 1 /****************************************
 2 *功能:获取触摸屏的坐标
 3 *参数:x----x坐标
 4 *       y----y坐标
 5 *****************************************/
 6 #include <linux/input.h> 
 7 #include <unistd.h>
 8 int fd_ts = open("/dev/event0",O_RDWR);  //打开开发板的触摸屏
 9 void get_xy(int* x,int* y)
10 {
11     struct input_event ts_event;
12     //两个标志位
13     int get_x=0;
14     int get_y=0;
15     //触摸屏幕引发检测,进入while循环,一次点击扫描两次,第一次扫描x轴,第二次扫描y轴
16     while(1)
17     {
18         /*点击屏幕,会产生触摸信息,该信息被保存到fd_ts文件里,
19         然后通过read把这个信息保存到结构体变量ts_event里*/
20         read(fd_ts,&ts_event,sizeof(struct input_event));
21         //判断ts_event里的各种值
22         if(ts_event.type == EV_ABS) //触摸屏发生
23         {
24             //第一次扫描x轴,只要点击屏幕,x轴就有值,get_x就改变标志
25             if(ts_event.code == ABS_X) 
26             {
27                 *x = ts_event.value;//把x坐标保存到变量x里
28                 get_x++;
29             }
30             //第二次扫描y轴,只要点击屏幕,y轴就有值,get_y就改变标志
31             if(ts_event.code == ABS_Y) 
32             {
33                 *y = ts_event.value;//把y坐标保存到变量y里
34                 get_y++;
35             }
36         }
37         //两次扫描过后得到x和y的坐标,就说明已经得到了xy的坐标,于是退出循环结束该函数
38         if(get_x == 1 && get_y==1)
39         {
40             break;
41         }    
42     }
43 }
sample

五)所想

  1)如果老师可以详细讲一下mmap就好了,听老师讲的话感觉会更好理解

  2)感觉线程挺有意思的

  3)视频界面图

六)总结

   1)完成了视频这块功能

  2)学习了mmap内存映射文件的方法

  3)学习了使用线程实现两个模块同时进行

  4)总结了触摸屏获取触摸坐标的方法

posted @ 2019-01-11 09:45  Lin_Ye  阅读(318)  评论(0编辑  收藏  举报