赞
踩
arm-linux-gcc main.c -o main
输出main文件是一个arm的编译器文件,相当于ros的一个节点,可以直接在arm操作系统运行
arm-linux-gnueabi-gcc test.c -o test
但是用arm-linux-gnueabi-gcc命令输出的文件和arm-linux-gcc不一样?
需要统一环境,所以还是用老师给的环境虚拟机吧
尝试了一下winterm的xomdem功能好像传不了,还是老老实实用securyCRT吧
// linux文件IO编程(系统调用函数) // open(打开文件) write(写入) #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include "stdio.h" #include <unistd.h> // man open // man read // man write // man close int main() { int fd; //打开文件 fd = open("1.txt",O_RDWR); // 自动创建 //fd = open("2.txt", O_RDWR|O_CREAT); if (fd < 0) { perror("open file fail"); return -1; } char buf[20] = {0}; int ret; ret = read(fd,buf,10); printf("buf:%s, ret:%d\n", buf, ret); close(fd); return 0; }
// linux文件IO编程(系统调用函数) // open(打开文件) write(写入) #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include "stdio.h" #include <unistd.h> // man open // man read // man write // man close // lseek int main() { int fd; //打开文件 fd = open("1.txt",O_RDWR); // 自动创建 //fd = open("2.txt", O_RDWR|O_CREAT); if (fd < 0) { perror("open file fail"); return -1; } char buf[20] = {0}; int ret; ret = read(fd,buf,10); printf("buf:%s, ret:%d\n", buf, ret); /*写入文件*/ char buf1[] = "abcdef"; int ret_wirte; ret_wirte = write(fd,buf1,7); printf("write_buf:%s, ret_write:%d\n",buf1,ret_wirte); close(fd); return 0; }
// linux文件IO编程(系统调用函数) // open(打开文件) write(写入) #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include "stdio.h" #include <unistd.h> // man open // man read // man write // man close // lseek int main() { int fd; //打开文件 fd = open("1.txt",O_RDWR); // 定位文件 lseek(fd, 3, SEEK_SET); printf("len=%d\n", lseek(fd,0,SEEK_END)); if (fd < 0) { perror("open file fail"); return -1; } char buf[20] = {0}; int ret; ret = read(fd,buf,10); printf("buf:%s, ret:%d\n", buf, ret); close(fd); return 0; }
/*实现文件复制,如果文件内容大于5个字节,则循环每次先复制5个字节,一直到复制完*/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <string.h> #include <assert.h> int main(int argc, char *argv[]) { int fd1,fd2; int b; char buff[5] ; fd1 = open("img.png",O_RDWR); fd2 = open("copy.png", O_RDWR | O_CREAT,); //先把文件偏移量移到文件末尾,返回文件内容大小,然后再使文件偏移量移到文件头 b = lseek(fd1, 0, SEEK_END); lseek(fd1, 0, SEEK_SET); while(b>0 && b>=5) { read(fd1, buff, sizeof(buff)); write(fd2,buff,sizeof(buff)); b -=5; } close(fd1); close(fd2); return 0; }
#include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #define SIZE 1024 int main(int argc,char *argv[]) { //打开源文件 int fd_src,fd_dst; fd_src = open(argv[1],O_RDWR); if(fd_src < 0) { printf("open %s fail\n",argv[1]); return -1; } //打目标文件 fd_dst = open(argv[2],O_RDWR|O_CREAT); if(fd_src < 0) { printf("open %s fail\n",argv[2]); return -1; } //清空数据存储区 char buf[SIZE]; memset(buf,0,sizeof(buf)); int ret_rd,ret_wr,i=0; while(1) { //读源文件 ret_rd = read(fd_src,buf,SIZE); //写目标文件 ret_wr = write(fd_dst,buf,ret_rd); printf("rd:%d wr:%d count:%d\n",ret_rd,ret_wr,++i); //读写的结束条件 if(ret_rd < SIZE) break; } //关闭文件 close(fd_src); close(fd_dst); return 0; }
运行指令
gcc copy_images.c -o copy
./copy img.png copy.png
void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
在这个函数原型中:
参数addr:指定映射的起始地址,通常设为NULL,由内核来分配
参数length:代表将文件中映射到内存的部分的长度。
参数prot:映射区域的保护方式。可以为以下几种方式的组合:
PROT_EXEC 映射区域可被执行
PROT_READ 映射区域可被读取
PROT_WRITE 映射区域可被写入
PROT_NONE 映射区域不能存取
参数flags:映射区的特性标志位,常用的两个选项是:
MAP_SHARD:写入映射区的数据会复制回文件,且运行其他映射文件的进程共享
MAP_PRIVATE:对映射区的写入操作会产生一个映射区的复制,对此区域的修改不会写会原文件
参数fd:要映射到内存中的文件描述符,有open函数打开文件时返回的值。
参数offset:文件映射的偏移量,通常设置为0,代表从文件最前方开始对应,offset必须是分页大小的整数倍。
函数返回值:实际分配的内存的起始地址。
#include <stdio.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #define LCD_WIDTH 800 #define LCD_HEIGHT 480 #define FB_SIZE 800*480*4 #define WHITE_COLOR 0x00FFFFFF void lcd_draw_point(unsigned int x, unsigned int y, unsigned int color, unsigned int *lcd_ptr) { if( x<LCD_WIDTH && y<LCD_HEIGHT ) { *(lcd_ptr+LCD_WIDTH*y+x) = color; } } void lcd_draw_circle(unsigned r_x, unsigned int r_y, unsigned int radius, unsigned int *lcd_ptr) { unsigned int x_begin, y_begin; if(r_x-radius<0) { r_x = radius; } if(r_y-radius<0) { r_y = radius; } for(y_begin=r_y-radius; y_begin<r_y+radius; y_begin++) { for(x_begin=r_x-radius; x_begin<r_x+radius; x_begin++) { if((r_x-x_begin)*(r_x-x_begin) + (r_y-y_begin)*(r_y-y_begin) < radius*radius) { lcd_draw_point(x_begin, y_begin, 0x00ff0000, lcd_ptr); } } } } void lcd_draw_single_color(unsigned int color, unsigned int *lcd_ptr) { int x, y; for(y=0; y<LCD_HEIGHT; y++) { for(x=0; x<LCD_WIDTH; x++) { *(lcd_ptr+LCD_WIDTH*y+x) = color; } } } int open_lcd_device(unsigned int **lcd_ptr) { int lcd_fd; lcd_fd = open("/dev/fb0", O_RDWR); if(lcd_fd == -1) { perror("open lcd device failed\n"); return -1; } *lcd_ptr = mmap( NULL, FB_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0); if(lcd_ptr == MAP_FAILED) { perror("map lcd_fb error\n"); return -1; } return lcd_fd; } int close_lcd_device(int lcd_fd, unsigned int *lcd_ptr) { munmap(lcd_ptr, FB_SIZE); return close(lcd_fd); } int main(int argc,char *argv[]) { int lcd_fd, radius = 100; unsigned int *lcd_ptr; lcd_fd = open_lcd_device(&lcd_ptr); if(lcd_fd == -1) { return -1; } lcd_draw_single_color( WHITE_COLOR, lcd_ptr ); lcd_draw_circle(LCD_WIDTH/2, LCD_HEIGHT/2, radius, lcd_ptr); close_lcd_device(lcd_fd, lcd_ptr); return 0; }
画球算法解析
其实就扫描屏幕的坐标点,满足if((r_x-x_begin)*(r_x-x_begin) + (r_y-y_begin)*(r_y-y_begin) < radius*radius)
这个条件的就给这个地址赋值像素信息
// // Created by zh006 on 2022/5/13. // #include <stdio.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #define LCD_WIDTH 800 #define LCD_HEIGHT 480 #define FB_SIZE 800*480*4 #define WHITE_COLOR 0x00FFFFFF void lcd_draw_point(unsigned int x, unsigned int y, unsigned int color, unsigned int *lcd_ptr) { if( x<LCD_WIDTH && y<LCD_HEIGHT ) { *(lcd_ptr+LCD_WIDTH*y+x) = color; } } void lcd_draw_circle(unsigned r_x, unsigned int r_y, unsigned int radius, unsigned int *lcd_ptr,int color) { unsigned int x_begin, y_begin; if(r_x-radius<0) { r_x = radius; } if(r_y-radius<0) { r_y = radius; } for(y_begin=r_y-radius; y_begin<r_y+radius; y_begin++) { for(x_begin=r_x-radius; x_begin<r_x+radius; x_begin++) { if((r_x-x_begin)*(r_x-x_begin) + (r_y-y_begin)*(r_y-y_begin) < radius*radius) { lcd_draw_point(x_begin, y_begin, color, lcd_ptr); } } } } void lcd_draw_single_color(unsigned int color, unsigned int *lcd_ptr) { int x, y; for(y=0; y<LCD_HEIGHT; y++) { for(x=0; x<LCD_WIDTH; x++) { *(lcd_ptr+LCD_WIDTH*y+x) = color; } } } int open_lcd_device(unsigned int **lcd_ptr) { int lcd_fd; lcd_fd = open("/dev/fb0", O_RDWR); if(lcd_fd == -1) { perror("open lcd device failed\n"); return -1; } *lcd_ptr = mmap( NULL, FB_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0); if(lcd_ptr == MAP_FAILED) { perror("map lcd_fb error\n"); return -1; } return lcd_fd; } int close_lcd_device(int lcd_fd, unsigned int *lcd_ptr) { munmap(lcd_ptr, FB_SIZE); return close(lcd_fd); } int main(int argc,char *argv[]) { int lcd_fd, radius = 50; int green = 0x0000ff00; int red = 0x00ff0000; int blue = 0x00000ff; int yellow = 0x00ffff3; int purple = 0xcc3399; unsigned int *lcd_ptr; lcd_fd = open_lcd_device(&lcd_ptr); if(lcd_fd == -1) { return -1; } lcd_draw_single_color( WHITE_COLOR, lcd_ptr ); lcd_draw_circle(LCD_WIDTH/2-100, LCD_HEIGHT/2, radius, lcd_ptr,green); lcd_draw_circle(LCD_WIDTH/2, LCD_HEIGHT/2, radius, lcd_ptr,red); lcd_draw_circle(LCD_WIDTH/2+100, LCD_HEIGHT/2, radius, lcd_ptr,blue); lcd_draw_circle(LCD_WIDTH/2+200, LCD_HEIGHT/2, radius, lcd_ptr,purple); lcd_draw_circle(LCD_WIDTH/2-200, LCD_HEIGHT/2, radius, lcd_ptr,yellow); close_lcd_device(lcd_fd, lcd_ptr); return 0; }
// // Created by zh006 on 2022/5/13. // #include <stdio.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <math.h> #define LCD_WIDTH 800 #define LCD_HEIGHT 480 #define FB_SIZE 800*480*4 #define WHITE_COLOR 0xFFFFFF void lcd_draw_point(unsigned int x, unsigned int y, unsigned int color, unsigned int *lcd_ptr) { if( x<LCD_WIDTH && y<LCD_HEIGHT ) { *(lcd_ptr+LCD_WIDTH*y+x) = color; } } void lcd_draw_run_circle(unsigned r_x1, unsigned int r_y1, unsigned r_x2, unsigned r_y2, unsigned int radius, unsigned int mv_speed, unsigned int *lcd_ptr, int color1, int color2) { int x_mv1 = mv_speed, y_mv1 = mv_speed; int x_mv2 = mv_speed, y_mv2 = mv_speed; // 第一个球配置 unsigned int x_begin1, y_begin1; if(r_x1-radius<0) { r_x1 = radius; } if(r_y1-radius<0) { r_y1 = radius; } // 第二个球配置 unsigned int x_begin2, y_begin2; if(r_x2-radius<0) { r_x2 = radius; } if(r_y2-radius<0) { r_y2 = radius; } while(1) { // 画第一个球 for(y_begin1=r_y1-radius; y_begin1<r_y1+radius; y_begin1++) { for(x_begin1=r_x1-radius; x_begin1<r_x1+radius; x_begin1++) { if((r_x1-x_begin1)*(r_x1-x_begin1) + (r_y1-y_begin1)*(r_y1-y_begin1) < radius*radius) { lcd_draw_point(x_begin1, y_begin1, color1, lcd_ptr); } } } // 画第二个球 for(y_begin2=r_y2-radius; y_begin2<r_y2+radius; y_begin2++) { for(x_begin2=r_x2-radius; x_begin2<r_x2+radius; x_begin2++) { if((r_x2-x_begin2)*(r_x2-x_begin2) + (r_y2-y_begin2)*(r_y2-y_begin2) < radius*radius) { lcd_draw_point(x_begin2, y_begin2, color2, lcd_ptr); } } } // 第一个球边缘碰撞检测 if(r_x1<radius || r_x1>= LCD_WIDTH - radius) { x_mv1 = -x_mv1; } if(r_y1<radius || r_y1>= LCD_HEIGHT - radius) { y_mv1 = -y_mv1; } // 第二个球边缘碰撞检测 if(r_x2<radius || r_x2>= LCD_WIDTH - radius) { x_mv2 = -x_mv2; } if(r_y2<radius || r_y2>= LCD_HEIGHT - radius) { y_mv2 = -y_mv2; } // 两球相撞检测 int dx = r_x1 - r_x2; int dy = r_y1 - r_y2; float distance = sqrt(dx * dx + dy * dy); if (distance <= 2*radius) { x_mv1 = -x_mv1; y_mv1 = -y_mv1; x_mv2 = -x_mv2; y_mv2 = -y_mv2; } // 第一个球坐标赋新值 r_y1 += y_mv1; r_x1 += x_mv1; // 第二个坐标赋新值 r_y2 += y_mv2; r_x2 += x_mv2; // 第一个球的之前的地方重新填补白色 for(y_begin1=0; y_begin1<LCD_HEIGHT; y_begin1++) { for(x_begin1=0; x_begin1<LCD_WIDTH; x_begin1++) { if((r_x1-x_begin1)*(r_x1-x_begin1) + (r_y1-y_begin1)*(r_y1-y_begin1) >= radius*radius) { lcd_draw_point(x_begin1, y_begin1, WHITE_COLOR, lcd_ptr); } } } for(y_begin2=r_y2-radius; y_begin2<r_y2+radius; y_begin2++) { for(x_begin2=r_x2-radius; x_begin2<r_x2+radius; x_begin2++) { if((r_x2-x_begin2)*(r_x2-x_begin2) + (r_y2-y_begin2)*(r_y2-y_begin2) < radius*radius) { lcd_draw_point(x_begin2, y_begin2, color2, lcd_ptr); } } } // 第二个球的之前的地方重新填补白色 for(y_begin2=0; y_begin2<LCD_HEIGHT; y_begin2++) { for(x_begin2=0; x_begin2<LCD_WIDTH; x_begin2++) { if((r_x2-x_begin2)*(r_x2-x_begin2) + (r_y2-y_begin2)*(r_y2-y_begin2) >= radius*radius) { lcd_draw_point(x_begin2, y_begin2, WHITE_COLOR, lcd_ptr); } } } } } void lcd_draw_single_color(unsigned int color, unsigned int *lcd_ptr) { int x, y; for(y=0; y<LCD_HEIGHT; y++) { for(x=0; x<LCD_WIDTH; x++) { *(lcd_ptr+LCD_WIDTH*y+x) = color; } } } int open_lcd_device(unsigned int **lcd_ptr) { int lcd_fd; lcd_fd = open("/dev/fb0", O_RDWR); if(lcd_fd == -1) { perror("open lcd device failed\n"); return -1; } *lcd_ptr = mmap( NULL, FB_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0); if(lcd_ptr == MAP_FAILED) { perror("map lcd_fb error\n"); return -1; } return lcd_fd; } int close_lcd_device(int lcd_fd, unsigned int *lcd_ptr) { munmap(lcd_ptr, FB_SIZE); return close(lcd_fd); } int main(int argc,char *argv[]) { int lcd_fd, radius = 70; int green = 0x0000ff00; int red = 0x00ff0000; int blue = 0x00000ff; int yellow = 0x00ffff3; int purple = 0xcc3399; unsigned int *lcd_ptr; lcd_fd = open_lcd_device(&lcd_ptr); if(lcd_fd == -1) { return -1; } lcd_draw_single_color( WHITE_COLOR, lcd_ptr ); lcd_draw_run_circle(LCD_WIDTH/2, LCD_HEIGHT/2, LCD_WIDTH/2+200, LCD_HEIGHT/2, radius, 3, lcd_ptr,purple, yellow); close_lcd_device(lcd_fd, lcd_ptr); return 0; }
老师代码
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> int main() { //打开lcd int fd; fd = open("/dev/fb0",O_RDWR); if(fd < 0) { perror("open lcd fail"); return -1; } //lcd的映射 int *addr; addr = mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if(addr == NULL) { perror("mmap fail"); return -1; } int black = 0x00000000; int red = 0x00ff0000; int green = 0x0000ff00; int a=400,b=240,r=100; int a1=150,b1=350,r1=80; int m=10,n=20; //球1 int m1=8,n1=5; //球2 int tmp; int x; int y; while(1) { for(y=0;y<480;y++) { for(x=0;x<800;x++) { *(addr+y*800+x) = black; if((x-a)*(x-a)+(y-b)*(y-b) <= r*r) *(addr+y*800+x) = red; //球1 if((x-a1)*(x-a1)+(y-b1)*(y-b1) <= r1*r1) *(addr+y*800+x) = green; //球2 } } //球1动 a+=m;b+=n; //球1反弹 if(a<100||a>700) m = -m; if(b<100||b>380) n = -n; //球2动 a1+=m1;b1+=n1; //球2反弹 if(a1<80||a1>720) m1 = -m1; if(b1<80||b1>400) n1 = -n1; //两球相碰 if((a-a1)*(a-a1)+(b-b1)*(b-b1)<=(r+r1)*(r+r1)) { //反弹 m = -m;n = -n; m1 = -m1;n1 = -n1; //换色 tmp = red; red = green; green = tmp; } } //lcd的映射释放 munmap(addr,800*480*4); //关闭lcd close(fd); return 0; }
一个问题就是我的代码需要小球运动后需要重新填充颜色,但是老师的代码没有体现这个
功能:循环显示三张图片,中间间隔1s
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> int show_bmp(char * pathname, int *addr) { if(addr == NULL) { perror("mmap fail"); return -1; } //打开一张bmp图 int fd_bmp; fd_bmp = open(pathname,O_RDWR); if(fd_bmp < 0) { perror("open bmp fail"); return -1; } //去掉bmp图片的头54个字节 lseek(fd_bmp,54,SEEK_SET); //读bmp图 char buf[800*480*3] = {0}; read(fd_bmp,buf,800*480*3); int x; int y; for(y=0;y<480;y++) { for(x=0;x<800;x++) { *(addr+(479-y)*800+x) = (buf[(y*800+x)*3+0]) | (buf[(y*800+x)*3+1]<<8) | (buf[(y*800+x)*3+2]<<16); //479 = buf[0]|buf[1]<<8|buf[2]<16 //478 = buf[3]|buf[4]<<8|buf[5]<16 } } // unsigned int sleep(unsigned int seconds);以秒为单位 sleep(1); } int main() { int fd; fd = open("/dev/fb0",O_RDWR); if(fd < 0) { perror("open lcd fail"); return -1; } //lcd的映射 int *addr = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (addr == NULL) { perror("mmap fail"); return -1; } while(1) { show_bmp("lufei.bmp", addr); show_bmp("sabo.bmp", addr); show_bmp("aisi.bmp", addr); } //lcd的映射释放 munmap(addr,800*480*4); //关闭lcd close(fd); return 0; }
创建项目多文件处理的形式
arm-linux-gcc src/*.c -o draw_circle -I include
1.将jpegsrc.v9a.tar.gz 解压到共享目录, ①tar -zxvf jpegsrc.v9a.tar.gz -C ~ x c z j 压缩GZ:cz 解压bz2格式:xj -C :指定包解压的位置 Linux: gz bz2 xz x:解压 c:压缩 z:gz格式 j:bz2格式 2.在家目录创建一个jpeg目录 ②cd ③mkdir jpeg 3.进入jpeg-9a目录 ④cd jpeg-9a 4.配置jpeg-9a ⑤./configure --prefix=/home/gec/jpeg/ CC=arm-linux-gcc --host=arm-linux --enable-shared --enable-static host:指定编译的命令 prefix : jpeg安装的位置 5.编译jpeg ⑥make -j 5.安装jpeg ⑦make install ①将/home/gec/jpeg/arm-jpeg/lib/libjpeg.so.9,下载到开发板/lib目录,然后修改库权限 ②在windowns建一个文件, ③将/home/gec/jpeg/arm-jpeg/lib里面的所有拷贝到windowns放进该文件夹 ④将/home/gec/jpeg/arm-jpeg/include里面的头文件拷贝到windowns放进该文件夹 6.编译代码 1. arm-linux-gcc *.c -o main -I./libjpeg -L./libjpeg -ljpeg *.c :当前目录下的所有.c文件(只有一个.c文件有main函数) -I./libjpeg :指定第三方库的一个头文件路径 -L./libjpeg :指定第三方动态库的路径 -ljpeg :指定动态库的库名 规定:libxxxx.so 库名 -lxxxx就代表链接库文件
arm-linux-gcc *.c -o main -I./libjpeg -L./libjpeg -ljpeg -L./ -lfont
使用举例:(有libtest.a静态库)
g++ -o compress compress.cpp -I./include/ -L/lib/ -ltest
**1)-I(大写i):**指定头文件搜索路径;
-I./include/表示将./include/目录作为第一个寻找头文件的目录,寻找的顺序是:
./include/ --> /usr/include --> /usr/local/include
**2)-L(大写l):**指定库文件搜索路径;
表示:编译程序按照-L指定的路进去寻找库文件,一般的在-L的后面可以一次用-l指定多个库文件。
-L/lib/表示到/lib/目录下找库文件
**3)-l(小写l)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。