20141122 【 ARM - 电子音乐相册 】

ARM型号我不太记得了(其实也不太懂);

好像是:三星 ARM-Cortex-A9 吧,由粤嵌公司做的一个板子。。。




周六周日两天,由粤嵌公司的工程师带我们做了一个项目——电子音乐相册。


不过这只是初步。。。毕竟我们以前没接触过 ARM 的开发。(部分同学学过单片机,我只是多学了个初等的 Arduino)


本以为这次是从入门到完成,从 Linux 系统上安装 ARM 编译所需--到-- ARM 下驱动编写以及多进程同时调度音乐播放和图片播放。


结果……老师觉得我们不行,都封装好给我们了(Ubuntu的镜像都直接集成了,ARM与计算机的网口通信,还有可怜的音乐图片不能同时播放,以及没有触屏功能)。


所以课程还是比较轻松(对于我来说)。。。


这两天感觉心情不错,主要是做出东西总是有成就感的(虽然这个巨人有点大)。
但也感到很多不足,包括Linux的自大,网络知识的自负,ARM的无知,操作系统的无视,还有体力的自信。。。


总之,要感谢这两天教导我们的 邓工程师,以及粤嵌公司的其它老师。。。


_________________________________________________________











以下,邓工程师的教导笔记(日记吧)

linux 环境编程:  -------> linux 一切都是文件  
  
  
设备文件存放在 /dev   ----> /dev/fb0  
  
  
  
----------------------------安装共享文件夹------------------------------  
  
  
  Vmware    
    
    
  VM   --->  setting  --->  Options  --->  share folders  ---> Always enable   
    
  配置 windows 系统的共享目录:  
    
    D:/share  
      
      
  在 linux系统中:  
    
  cd  /mnt/hgfs/share    
  
  
  
------------------------------tftp32使用-------------------------------------  
  
  
确保开发板与PC的IP同一网段       
  
  
开发板:  
  
ifconfig  eth0  192.168.2.xx    ----->  xx 为开发板的ip  
  
tftp 192.168.2.yy -g -r xxx.bmp    ----> yy 为tftp32的ip  
  
tftp 192.168.2.yy -g -r lcd  
  
------------------------------------------------------------------------  
  
  
  
编程控制设备:  
  
      1)  文件IO API  
        
      2)  linux 管理系统  
        
      3)  设备访问规则  
        
        3.1) 获取资源许可:   ----->  man  man  
          
              open();  
                
              获得LCD控制许可:  
                  
              #include   
              #include   
              #include                    
              int open(const char *pathname, int flags);  
                
              pathname: “/dev/fb0”  
              flags:      O_RDWR   
                
                
        3.2) 控制LCD  
          
                #include   
                write/read  
                  
                ssize_t write(int fd, const void *buf, size_t count);  
                  
                fd:  lcd的文件描述符 ,open成功返回的int 值  
                buf: 写入LCD的图形数据  
                count: 写入数据的大小  
                  
                // cat  /bin/busybox  >  /dev/fb0  
                // LCD 显示的是颜色 ---> RGB数值  --->  32bit =》 8:8:8:8(透明度:红色:绿色:蓝色)  
                // LCD 显示的大小   ---> 分辨率   --->  800*480  
                // LCD 显示一帧图像的 存储容量:  800*480*4 = 1536000字节  = 1.5M  
                // RGB =》  0xFFFFFF  ---> 白色    0x00000000  --> 黑色  
                  
                  
          3.3)回收资源  
            
          #include   
  
          int close(int fd);  
            
          fd: lcd的文件描述符 ,open成功返回的int 值  
            
            
            
          3.4) 图片操作  
            
            open();  
              
            read();  
              
              
            ssize_t read(int fd, void *buf, size_t count);  
                    fd:图片的文件描述符 ,open成功返回的int 值  
                    buf: 图片内容  
                    count: 读取图片内容的大小  
                      
                      
                      
           文件指针移动  
             
           lseek(int fd, off_t offset, int whence);  
           fd:图片的文件描述符 ,open成功返回的int 值   
           offset:  文件操作指针移动偏移量  
           whence:  文件指针操作的起始位置  
                     SEEK_SET  文件头部  
                     SEEK_CUR  文件当前位置  
                     SEEK_END  文件尾部  
             
             
           lseek(bmp_fd,54,SEEK_SET);  
             
             
             
             
           3.5 ) 多张图片操作  
             
                  3.5.1) 文件夹操作  
                    
                       #include   
                       #include   
                         
                       //打开文件目录,获取目录流指针  
                       DIR *opendir(const char *name);  
                       name : 文件目录名称  
                       DIR:  文件目录流结构  
                         
                       //读取目录流指针,获取当前的struct dirent目录项指针  
                       struct dirent *readdir(DIR *dirp);  
                              
              struct dirent {  
               ino_t          d_ino;       /* inode number */  
               off_t          d_off;       /* offset to the next dirent */  
               unsigned short d_reclen;    /* length of this record */  
               unsigned char  d_type;      /* type of file; not supported  
                                              by all file system types */  
               char           d_name[256]; /* filename */  
           };  
          
             
             
           在开发板建立图片目录:  
             
             
          mkdir pic  
                   
          将图片下载到pic中,让后通过代码进行目录访问:  
            
            
          DIR *  pic_dir = opendir("/pic");  
          struct dirent * pic_dirent ;  
          char pathname[30];  
            
          while( (pic_dirent= readdir(pic_dir)) != NULL )  
          {  
              if(strstr(pic_dirent->d_name,".bmp"))  
              {  
                 snprintf(pathname,30,"/pic/%s",pic_dirent->d_name);  
                 bmp_fd[i] = open(pathname,O_RDWR);   
                 ...   
              }     
                
          }  
            
          closedir(pic_dir);  
  
                      
       3.6) 图片翻转  
            
            
            //24bit to 32bit  
            for(i=0,j=800*480*4-1;i<800*480*3;i+=3)  
            {  
             pic_mem[j-3] = bmp_mem[i] ;  
                 pic_mem[j-2] = bmp_mem[i+1] ;  
                 pic_mem[j-1] = bmp_mem[i+2] ;  
                 j-=4;  
            }           
            
            
            
            
       3.7) 微缩图操作  
            
            
        char narrow_buf[4][400*240*3];    
            
        for(i=0,j=0;i=0;y-=2)  
            for(x=0;x<800*3;x+=3)  
            {  
                  for(count=0;count<3;count++)  
                        narrow_buf[i][j++] = bmp_mem[y*800*3+x++] ;  
            }     
  
        }  
     
      for(i=0,j=0;i  
            
  int key_fd;  
    struct input_event key_event;  
    key_fd = open("/dev/event1",O_RDWR);  
    if(key_fd < 0)  
        {  
            perror(" open key err !");  
            return -1;  
        }  
  
    read(key_fd,&key_event,sizeof(key_event));  
    if(key_event.type == EV_KEY)  
        {  
            if(key_event.code == KEY_LEFT)  
                {  
                    //显示放大图片  
  
                }  
            if(key_event.code == KEY_RIGHT)  
                {  
                    //显示微缩图  
  
                }  
  
        }            
            
     close(key_fd)       
            
            
            
            
            
            
            
          3.9) 幻灯片播放  
            
            
            
            
            
          4.0)音乐播放  
            
            
            
            
            
            
            
            
             
         
        --------------------------------------------------------------------------------------------     
            
          程序编译:  
            
            本地编译:   运行与编译的环境一致 (PC 编程)  
              
            交叉编译:   运行与编译的环境不一致 (在一个平台编译另外一个平台的代码,PC --> ARM)  
              
            编译器: 本地编译器 ,交叉编译器  
              
                         gcc      arm-linux-gcc  
            
  
              使用:  
                
                      cd /mnt/hgfs/share  
                
                      arm-linux-gcc  lcd.c  -o  lcd    //得到执行程序 lcd    
                        
                        
                      查看文件的类型属性:  
                         
                      file  a.out  
  
  
              
              
            在开饭的超级终端中将应用程序下载到开发板运行测试:  
              
              
            输入: rx  lcd   回车  
              
            超级终端选择:“传送” --->  发送文件  ---->  协议: Xmodem  文件: d:/share/lcd  回车  
              
              
            修改文件执行权限:  chmod  777 lcd  
              
              
            执行测试:   ./lcd  
              
              
              
              
              
            -------------------------BMP图片下载-----------------------------  
              
              
            rx  1.bmp   回车  
              
            pwd 查看当前路径  
               
                  
  
------------man   man ---(q 退出)---------  
  
       1   Executable programs or shell commands  
       2   System calls (functions provided by the kernel)  
       3   Library calls (functions within program libraries)  
  
-------------------------------------------------------





第一天

关于图片的读取与打印屏幕,文件目录文件的读取与24位位图转成32位图

#include 
#include 
#include  
#include 
#include 
#include 
#include 
#include 


char bmp_mem[800*480*3];
char pic_mem[800*480*4];


DIR * pic_dir;
struct dirent *pic_dirent;
char pathname[30];
int pic_count;

int main(int argc,char **argv)
{
	int fd,bmp_fd[30];
	int i=0,j,k;

	
	//获取LCD资源
	fd = open("/dev/fb0",O_RDWR);
	//获取失败处理
	if(fd < 0)
		{
			perror(" open LCD Err !");
			return -1;
		}

	//写屏幕
	memset(pic_mem, 0xFF, 800*480*4);
	write(fd, pic_mem, 800*480*4);

	sleep(3);


	//打开目录
	pic_dir = opendir("/pic");
	
	//读目录
	while( ( pic_dirent =  readdir(pic_dir)) != NULL )
	{
              if(strstr(pic_dirent->d_name,".bmp"))
              {
                 snprintf(pathname,30,"/pic/%s",pic_dirent->d_name);
		  //打开图片,获取图片操作许可
		  //打开文件,将文件描述符写入文件描述符数组
                 bmp_fd[i++] = open(pathname,O_RDWR); 
		  if( bmp_fd[i] <0)
			{
				perror(" open bmp err ");
				return -1;
			}
		  pic_count = i;
              }   		

	}

	



	for(k=0;k






【个人的打印屏幕代码】

#include 
#include 
#include 
#include 
#include 
//控制LCD屏幕

char pic_mem[800*480*4];				/* 图像地址? */
void pic_set(int ss, int ee, char color){
	int i;
	for(i=ss; i<=ee; i++){
		pic_mem[i] = color;
	}
}

int main(int argc, char **argv){
	char pathname[] = "/dev/fb0";		/* 文件路径 */
	int flags = O_RDWR;					/* 访问方式 */
	int fd = open(pathname, flags);		/* 获取文件句柄 */
	if( fd < 0 ){						/* 获取失败 处理 */
		printf("OPEN LCD ERROR!\n");
		return -1;
	}

	//memset(pic_mem, 0xFF, sizeof(pic_mem));
	
    pic_set(0, 500000, 0x00);
	pic_set(500000, 1000000, 0xFF);
	pic_set(1000000,1500000, 0x00);
    pic_set(1500000,2000000, 0xFF);
	pic_set(2500000,3000000, 0x00);
	pic_set(3500000,4000000, 0xFF);
    pic_set(4500000,5000000, 0x00);
    
	/**	写屏幕 */
	write(fd, pic_mem, 800*480*4);		/* 写位置,来源,需要写多少 */		
	/* LCD 颜色8:8:8:8(透明度,红,绿,蓝) */
	/* LCD 大小 分辨率 800*480 *4Byte */
	/* 故, 写一张图片大小 1.5M */
	/* WHITE=0xFFFFFFFF, BLACK=0x00000000 */

	

	close(fd);	/* 关闭文件,回收资源 */
	return 0;	/**	SUCCESS 0, ERROR -1 */
}








【个人代码,随机循环变色(还没加图片处理)】

#include 
#include 
#include 
#include 
#include 
#include 
#include 
//控制LCD屏幕

char pic_mem[800*480*4];				/* 图像地址? */

#define SET_COLOR(color, no)	(char)( ((color)>>(8*no))&0xFF )

unsigned int rand_color(){
	unsigned int res = 0;
	int i;
	for(i=0; i<4; i++)
		res |= (res<<8) | ( rand()%256 );
	return res;
}

void pic_set(int ss, int ee, unsigned int color){
	int i, j;
	for(i=ss; i<=ee; i+=4)
		for(j=3; j>=0; j--)			
			pic_mem[i+j] = SET_COLOR(color, j);
}

int open_err(char path[], int st){
	int pd = open(path, st);
	if( pd < 0 ){
		perror("OPEN file Error!\n");
		return -1;
	}
	return pd;
}

int main(int argc, char **argv){
	char pathname[] = "/dev/fb0";		/* 文件路径 */
	char p01name[] = "/p01.bmp"
	int flags = O_RDWR;					/* 访问方式 */
	
	srand(time(NULL));
	//memset(pic_mem, 0xaa, sizeof(pic_mem));
	unsigned int c[2] = {0x520A0B0C , 0x00AABBCC}, delay_time;
	int flag = 0;
	int fd = open(pathname, flags);		/* 获取文件句柄 */
		if( fd < 0 ){						/* 获取失败 处理 */
			printf("OPEN LCD ERROR!\n");
			return -1;
		}
		
	while( 1 ){
		/* 打开图片 */
	//int bmp_fd = open_err(p01name, flags);

	int bmp_fd;
	read(bmp_fd, p01name, 800*480*3);
			
	    pic_set(0*480*4, 400*480*4, rand_color());
		pic_set(400*480*4, 800*480*4, rand_color());
		flag = 1-flag;
	    
		/**	写屏幕 */
		write(fd, pic_mem, 800*480*4);		/* 写位置,来源,需要写多少 */		

	
	
	/* LCD 颜色8:8:8:8(透明度,红,绿,蓝) */
	/* LCD 大小 分辨率 800*480 *4Byte */
	/* 故, 写一张图片大小 1.5M */
	/* WHITE=0xFFFFFFFF, BLACK=0x00000000 */

			/* 关闭文件,回收资源 */
		for(delay_time=0x00FFFFFF; delay_time; delay_time--);
	}
	close(fd);
	return 0;	/**	SUCCESS 0, ERROR -1 */
}








【个人代码,24位图拓展为32位图(多余Byte为透明度控制),没加翻转处理】

果然没有 邓工程师 NB,人家处理的时候带翻转的,那速度可不是一个数量级的。。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

void delay(unsigned int dt){
	int i;
	while( dt-- )
		for(i=80000; i; i--);
}
char p_tmp[800*480*4];
char picture[800*480*4];

void execute_picture(char picture[]){
	int i, j, len = 800*480*3;
	for(i=0, j=0; id_name, ".bmp") != NULL ){
			snprintf(tmp_path, 111, "%s/%s", dir_path, pic_dirent->d_name);
			fds[plen] = open(tmp_path, O_RDWR);
			if( fds[plen] < 0 ){
				perror("ERROR!\n");
				return -1;
			}
			plen++;
		}
	};

	fd = open(printpath, O_RDWR);
	if( fd<0 ){
		perror("ERROR");
		return -1;
	}

	int i;
	while( 1 ){
		for(i=0; i













第二天

图像压缩,按键监控,音频播放

#include 
#include 
#include  
#include 
#include 
#include 
#include 
#include 
#include 

char bmp_mem[800*480*3];
char swap_bmp[800*480*3];
char pic_mem[800*480*4];
char narrow_buf[4][400*240*3];

DIR * pic_dir;
struct dirent *pic_dirent;
char pathname[30];
int pic_count;

int main(int argc,char **argv)
{
	int fd,bmp_fd[30];
	int i=0,j,k,x,y,count;
	int key_fd;
	struct input_event key_event;

	
	//获取LCD资源
	fd = open("/dev/fb0",O_RDWR);
	//获取失败处理
	if(fd < 0)
		{
			perror(" open LCD Err !");
			return -1;
		}

	//写屏幕
	memset(pic_mem, 0xFF, 800*480*4);
	write(fd, pic_mem, 800*480*4);

	sleep(3);


	//打开目录
	pic_dir = opendir("/pic");
	
	//读目录
	while( ( pic_dirent =  readdir(pic_dir)) != NULL )
	{
              if(strstr(pic_dirent->d_name,".bmp"))
              {
                 snprintf(pathname,30,"/pic/%s",pic_dirent->d_name);
		  //打开图片,获取图片操作许可
		  //打开文件,将文件描述符写入文件描述符数组
                 bmp_fd[i++] = open(pathname,O_RDWR); 
		  if( bmp_fd[i] <0)
			{
				perror(" open bmp err ");
				return -1;
			}
		  pic_count = i;
              }   		

	}


        //获取微缩图
	for(k=0;k=2;y-=2)
            for(x=0;x<800*3;x+=3)
            {
                  for(count=0;count<3;count++)
                        narrow_buf[k][j++] = bmp_mem[y*800*3+x++] ;
            }	

        }

	//清屏,白屏
	lseek(fd,0,SEEK_SET);
	memset(pic_mem,0xff,800*480*4);
	write(fd,pic_mem,800*480*4);


     //将微缩图填充到帧图像数组
      for(i=0;i


madplay 音频播放命令

命令格式:

madplay  option    filename



option:

-v  获取播放时间
-q  不存在任何打印,但现实警告
-Q  不存在任何打印
–downsample  只采用一半数据
-i  忽略CRC校验错误
-o PATH/xx.wav 可以用来转码,将mp3转为wav
也可以是其他格式,见说明;.raw  表示是元素pcm,.hex等
-a 开启衰减音量,增加音量,衰减系统为-175~+18    (当然通过键盘+ —也可以调整音量)
-A 同-a
-1 -2 -m -S 分别指左声道,右声道,双声道,立体声
-s  用于seek播放如:0:1:20:11 ,seek到1小时,2分钟,11秒时开始播放
-t  用于播放时间现在  0:1:20:11 ,播放到1小时,2分钟,11秒时就停止
-z  用于随机播放列表
-r, –repeat[=MAX]   循环播放无限次或Max次
–tty-control            enable keyboard controls  默认是使能热键
–no-tty-control         disable keyboard controls
热键使用
下一首歌曲; f,或ctrl+n 或者>
上一首歌曲  b ,或ctrl+p 或者<
退出:q, Q,获取ctrl+c
获取播放状态信息: i  ?
调节音量: – + _ =
暂停恢复:p
停止:s






【个人代码,图片处理,翻转,压缩,移动】

还是一样的分步处理,邓工程师 可是 处理+翻转 or 处理+翻转+压缩。。。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

void delay(unsigned int dt){
	int i;
	while( dt-- )
		for(i=80000; i; i--);
}
char p_tmp[800*480*4];
char picture[800*480*4];
char p_pic[800*480*4];
char pcom[16][480*800*4/4];

int s_d[4][2] = { 0*800+0,400,	0*800+400,400,	240*800+0,400,	240*800+400,400 };

void re_row(char s[], char t[], int row, int col){
	int i, j;
	col *= 4;
	for(i=0; i=0; i-=rb){
		for(j=0; jd_name, ".bmp") != NULL ){
			snprintf(tmp_path, 111, "%s/%s", dir_path, pic_dirent->d_name);
			fds[plen] = open(tmp_path, O_RDWR);
			if( fds[plen] < 0 ){
				perror("ERROR!\n");
				return -1;
			}
			plen++;
		}
	};

	fd = open(printpath, O_RDWR);
	if( fd<0 ){
		perror("ERROR");
		return -1;
	}

	int i=0, cnt, part = 9;
	while( 1 ){
		for(cnt=0; cnt







【个人代码,按键控制图片缩放】

本来还想加个 缩略图 随机位置显示的,可是没成功 picture_xy() 函数。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define PRINT_PATH		"/dev/fb0"
#define BUTTON_PATH		"/dev/event1"
#define DIR_PATH		"/test"
#define PIC_NAME		".bmp"
#define MUSIC_NAME		".mp3"
#define MUSIC_PLAY		"madplay"
#define MUSICS			"1.mp3"

int fd, fkey;
int options;
int pics[100], pic_count=0;
char nametmp[123];

char picture[480*800*4];
char p_tmp[480*800*4];
char part[16][480*800*3];
char pic_now[480*800*4];

struct input_event key_event;


void execute_picture(char picture[]){
	int i, j, len = 800*480*3;
	for(i=0, j=480*800*4-1; i<800*480*3; i+=3){
		p_tmp[j-3] = picture[i];
		p_tmp[j-2] = picture[i+1];
		p_tmp[j-1] = picture[i+2];
		j -= 4;
	}
	memcpy(picture, p_tmp, 480*800*4);
	
	/*
	for(i=0, j=0; i=0; i-=rb){
		for(j=0; jd_name, PIC_NAME) ) != NULL ){
			snprintf(nametmp, 111, "%s/%s", DIR_PATH, pic_dirent->d_name);
			pics[pic_count] = open(nametmp, O_RDWR);
			if( pics[pic_count] < 0 ){
				perror("OPEN nametmp Error !\n");		
				return -1;
			}
			pic_count++;
		}
	}

	
	fkey = open(BUTTON_PATH, O_RDWR);
	if( fkey < 0 ){
		perror("OPEN BUTTON_PATH Error !\n");
		return -1;
	}
	
	
	
	int i, j;
	srand( time(NULL) );
	while( 1 ){
		
		//for(i=0; i












最后,END

你可能感兴趣的:(物联网,ARM,GEC,Linux)