《智能家居系统》3

一、图片翻转

        for ( i = 0; i < 800*480; i++)
	{
		lcd_buf[i] = (bmp_buf[i*3+2]<<16)+(bmp_buf[i*3+1]<<8)+(bmp_buf[i*3]<<0);
	}
    
    int fli_buf[800*480];
    int x,y;
    for(y=0;y<480;y++)
    {
     	for(x=0; x<800; x++)
     	{
     		fli_buf[y*800+x]=lcd_buf[(479-y)*800+x];
     	}

    }

===========================================================================

二、linux用户资源限制

gec@ubuntu:/mnt/hgfs/东莞理工实训/笔记/day3$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 3712
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 3712
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited

=================================================================================

三、程序编译后的分段以及在内存中的位置

见图
内存的布局

=================================================================================

四、如何播放音乐

1、音乐播放器
[root@GEC6818 /test]#which madplay
/usr/bin/madplay

2、如何查找文件
[root@GEC6818 /test]#find / -name *.mp3
/IOT/mp3/end.mp3
/IOT/mp3/left.mp3
/IOT/mp3/right.mp3
/IOT/mp3/test.mp3
/usr/local/Qt-Embedded-5.7.0/examples/svg/embedded/desktopservices/data/sax.mp3

3、播放音乐
[root@GEC6818 /test]#madplay /IOT/mp3/end.mp3

4、madplay的移植
查找资料

5、如何编写程序,调用音乐播放器

   #include <stdlib.h>

   int system(const char *command);

例:
system(“madplay ./test,mp3 -r &”); // -r — 循环播放, & — 后台运行

音乐暂停:
system(“killall -STOP madplay &”);

音乐继续:
system(“killall -CONT madplay &”);

音乐退出:
system(“killall -9 madplay &”);

练习:
设计四个按钮,实现音乐的播放、暂停、继续、结束

=================================================================================

五、多线程编程

1、例:

单线程程序
int main(void)
{

//显示智能家居主界面

//获取触摸屏的坐标
if(如果点击了“数码相册按钮”)
{
	while(1)
	{
		//播放图片1

		获取触摸屏坐标     ------>如果触摸屏没有按下,则进程会阻塞在这个位置。
		if(判断是否点击右下角)
			//显示智能家居主界面
			//退出循环
		

		//播放图片2
			.......

		//播放图片3
			.......
	}

}

}

2、例

多线程的程序

void 子线程()
{
	while(1)
	{
		读取触摸屏的坐标
	}
}

int main(void) //主线程
{

//创建一个子线程

//显示智能家居主界面


if(如果点击了“数码相册按钮”)
{
	while(1)
	{
		//播放图片1
		if(判断是否点击右下角)
			//显示智能家居主界面
			//退出循环
		

		//播放图片2
			.......

		//播放图片3
			.......
	}
}

}

3、线程的创建

#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);

Compile and link with -pthread. ------>使用多线程的库

参数说明:
pthread_t *thread ----- 创建线程后,得到的线程ID,这个ID是一个32位的无符号整形值,唯一的
const pthread_attr_t *attr ----- 线程的属性,一般为NULL
void *(*start_routine) (void *) ------ 线程的执行函数
void *arg ----向线程执行函数传递的参数
返回值:
On success, pthread_create() returns 0; on error, it returns an error
number,

gcc -o test test.c -pthread

例子代码:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

int count = 1;

void *child_thread(void *arg) //子线程
{
	while(1)
	{
		count ++;
		printf("in child: get ts,count =%d\n",count);
		sleep(1);		
	}
	
	return NULL;
}


int main(void)
{
	int ret;
	pthread_t child_id;
	ret = pthread_create(&child_id, NULL, child_thread, NULL);
	if(ret < 0)
	{
		perror("thread create error");
		return -1;		
	}
	
	while(1) //主线程
	{
		count ++;
		printf("in main: play bmp,count=%d\n",count);
		sleep(1);		
	}
	
	return 0;	
}



注意:
1、主线程和创建的子线程属于同一个进程,这个线程使用的全局变量可以共享。
2、如果主线程退出,这个主线程创建的所有的子线程会自动退出。

4、线程的等待函数
在主线程中,调用这个函数,这个函数就会等待子线程,如果子线程不退出,主线程就不会退出。

   #include <pthread.h>

   int pthread_join(pthread_t thread, void **retval);

参数说明:
pthread_t thread ----->等待的子线程的ID
void **retval ---->子线程退出的时候,返回值。

5、线程的退出函数

void pthread_exit(void *retval);
参数:
线程退出的时候,该线程的返回值,返回值可以通过pthread_join()来获取。也可以是NULL。
NULL是什么?------>((void *)0)

调用这个函数的线程会立即退出。

6、使一个线程退出的函数

#include <pthread.h>
int pthread_cancel(pthread_t thread);
参数说明:
pthread_t thread — 退出线程的ID
这个函数用来结束指定的线程。

7、获取线程ID的函数
#include <pthread.h>

   pthread_t pthread_self(void)

;

六、嵌入式系统的启动过程(ARM + Linux)

1、启动处理器内部固化小的启动程序
原厂(samsung)固化的代码,我们不能修改。主要做CPU的启动,然后去存储器中找u-boot,然后启动u-boot

2、启动uboot
U-Boot是一个通用的启动引导程序,相当于PC机平台的BIOS。uboot会初始化硬件(处理器、内存、时钟、看门狗、IIC、USB、串口、中断、…),并启动Linux系统内核。

注意:
uboot是一个免费、开源的软件。但是他不是一个操作系统。是直接在硬件上运行的程序----裸机程序。

3、启动linux内核
是linux操作系统的核心,所谓linux系统是免费的,主要是指linux内核。linux内核的主要作用:(linux内核由哪几个部分组成的)
1)进程管理和进程通信。
2)内存管理
3)文件系统
4)设备管理----硬件的驱动
5)网络协议(TCP/UDP)

4、挂载根文件系统
什么是根文件系统?
根文件系统是一个软件包,可以看成是linux运行的一个环境。 里面包含了linux的shell命令,运行程序使用的库,linux环境配置文件、设备文件、应用程序、…
[root@GEC6818 /IOT]#ls /
IOT etc lmh root test
bin h lost+found run tmp
dev lib mnt sbin usr
driver linuxrc proc sys var

5、执行配置环境变量的脚本文件
脚本文件:/etc/init.d/rcS 或 /etc/profile

例:
如果linux系统启动后,想要自动运行一个应用程序,如何解决??? —> /test/play_bmp

打开/etc/profile
[root@GEC6818 /test]#vi /etc/profile

修改/etc/profile文件
输入i,进入vi的插入模式,只有进入插入模型,才可以修改文件。----->注释掉原来自动启动应用程序的过程—>加入自己应用程序的调用

#cd /IOT
#insmod led.ko
#./aa

cd /test
./play_bmp &
cd /

保存/etc/profile,并推出。
按下“Esc”按键,退出vi的插入模型,进入命令模型—>输入":wq".----》重启开发板—>看到应用程序自动运行

输入top命令,可以查看play_bmp进程正在运行
Mem: 26836K used, 801008K free, 0K shrd, 616K buff, 3880K cached
CPU: 0.0% usr 0.1% sys 0.0% nic 99.8% idle 0.0% io 0.0% irq 0.0% sirq
Load average: 0.00 0.00 0.00 1/89 140
PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND
130 126 root S 5584 0.6 5 0.0 ./play_bmp
136 126 root R 3336 0.4 1 0.0 top
47 2 root SW 0 0.0 0 0.0 [kworker/0:1]
1 0 root S 3336 0.4 2 0.0 init
126 1 root S 3336 0.4 1 0.0 -/bin/sh
5 2 root SW 0 0.0 2 0.0 [kworker/u:0]
102 2 root SW 0 0.0 3 0.0 [mmcqd/0]
2 0 root SW 0 0.0 0 0.0 [kthreadd]
3 2 root SW 0 0.0 0 0.0 [ksoftirqd/0]
4 2 root SW 0 0.0 0 0.0 [kworker/0:0]
6 2 root SW 0 0.0 0 0.0 [migration/0]
7 2 root SW 0 0.0 0 0.0 [watchdog/0]
8 2 root SW 0 0.0 1 0.0 [migration/1]
9 2 root SW 0 0.0 1 0.0 [kworker/1:0]
10 2 root SW 0 0.0 1 0.0 [ksoftirqd/1]
11 2 root SW 0 0.0 1 0.0 [watchdog/1]
12 2 root SW 0 0.0 2 0.0 [migration/2]
13 2 root SW 0 0.0 2 0.0 [kworker/2:0]
14 2 root SW 0 0.0 2 0.0 [ksoftirqd/2]
15 2 root SW 0 0.0 2 0.0 [watchdog/2]

6、执行应用程序

注意:如果要退出play_bmp程序。
使用top命令,找到play_bmp进程的PID–>130

输入命令:
[root@GEC6818 /]# kill -9 130

七、如何控制LED灯的状态

在嵌入式linux系统中,控制硬件需要硬件的驱动。液晶屏和触摸屏的驱动已经安装到linux内核中。我们可以直接访问。
液晶屏:/dev/fb0
触摸屏:/dev/input/event0
访问液晶屏和触摸屏的方法:open()、read()、write()、close()

1、LED灯的驱动程序
led_drv.c----LED驱动程序的源文件
Makefile ----- 编译驱动程序使用的Makefile文件
led_drv.ko ---->已经编译好的驱动程序
test.c ---->访问驱动程序的应用程序

2、驱动程序的安装
[root@GEC6818 /test]#insmod led_drv.ko
[ 110.830000] gec6818_led_init

3、查看驱动的设备文件
[root@GEC6818 /test]#ls /dev/led_drv -l
crw-rw---- 1 root root 100, 0 Jan 1 00:01 /dev/led_drv

4、通过设备文件来控制LED


int main(void)
{
	int fd;
	int ret;
	char buf[2]; //buf[1]---LED灯的灯号:8、9、10、11
                     //buf[0]---LED灯的状态:1--on, 0--off

	fd = open("/dev/led_drv", O_WRONLY); //打开LED驱动
	if(fd < 0)
	{
		perror("open led driver");
		return -1;		
	}
	while(1)
	{
		buf[1]=8; buf[0]=1;//LED8 on
		ret = write(fd,buf,sizeof(buf));
		if(ret != 2)
			perror("write led driver ");
		usleep(300*1000);//300ms
		
		buf[1]=8; buf[0]=0;//LED8 off
		ret = write(fd,buf,sizeof(buf));
		if(ret != 2)
			perror("write led driver ");
		usleep(300*1000);//300ms
	}
	
	close(fd);
	
	return 0;
}























  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WeSiGJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值