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; j d_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; j d_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