1、显示器,显示最小的单位:像素点(开发板的分辨率是800X480)
怎么样去表示每一个像素点?
比如说只有一个位,来显示,那只能显示白色和黑色,比如说有 8bit -> 1Byte 有2^8种情况,位数越大,所能表示的颜色就越多
三原色( ARGB ) 8:8:8:8 每一个像素点有32位来表示
ABGR
char buf[4];
int size;
int r;
fd = open("1.bmp",O_RDONLY);
lseek(fd,2,SEEK_SET);
r = read(fd,buf,4);
size = (buf[3] & 0xff) << 24 | (buf[2] & 0xff) << 16 | (buf[1] & 0xff) << 8 | (buf[0] & 0xff) << 0;
头两个字节,分辨率,大小,位深
read(fd,buf,2);
buf[1] << 8 | buf[0]
2、开发环境搭建和使用
安装minicom
sudo apt-get install minicom
网络问题:
vim /etc/network/interfaces
auto eth0
iface eth0 inet static
address 192.168.5.3//自己号码加65,自己52+65=117;
netmask 255.255.255.0
gateway 192.168.5.1
dns-nameserver 192.168.5.1
sudo ifconfig eth0 IP
sudo route add default gw 192.168.5.1
Ping 192.168.5.1//ping一下网关
ping www.baidu.com//如果能连网但是不能ping百度,可能是不能解析域名;进行下面操作;
sudo vim /etc/resolv.conf 在最下面添加一行 -> nameserver 192.168.5.1
刚才看很多同学wind10的电脑,更新不了软件,是更新源的问题,大家可以下载群里面这个source.list文件,替换系统原来的更新源
法一、如果能连网但是不能下载软件,可能是更新源的问题,sources.list
sudo vim/etc/apt/sources.list进入到里面粘贴百度复制的更新源代码;
百度Ubuntu 14.4源
法二、或者找一个好的sources.list放入share文件里面
sudo cp source.list /etc/apt/
sudo apt-get update
sudo apt-get install minicom
3、minicom的使用
dmesg查看USB转串口是否链接到虚拟机。 /dev/ttyUSB0
配置minicom
sudo minicom -s ---> Serial port setup
+-----------------------------------------------------------------------+
| A - Serial Device : /dev/ttyUSB0 |
| B - Lockfile Location : /var/lock |
| C - Callin Program : |
| D - Callout Program : |
| E - Bps/Par/Bits : 115200 8N1 |
| F - Hardware Flow Control : No |
| G - Software Flow Control : No |
| |
| Change which setting? |
+-----------------------------------------------------------------------+
按对应的字母进入对应的选项来修改设置,修改好之后,回车结束。
然后选择 Save setup as dfl 保存为默认的配置,以后就不需要再进行配置了。
Exit from Minicom
$ sudo minicom -c on
退出 ctrl + a 然后再按q退出
4、LCD的使用
打开对应的设备节点,往framebuffer写入显示的数据
#include
#include
int main()
{
int fd ;
int lcd_buf[800*480];//ARGB -> 4个字节
int i;
for(i=0;i<800*480;i++){
lcd_buf[i] = 0x00FF0000;
}
fd = open("/dev/fb0",O_RDWR);
if(fd < 0)
{
perror("open fail");
return -1;
}
write(fd,lcd_buf,800*480*4);
close(fd);
return 0;
}
编译: arm-linux-gcc -o lcd lcd.c
arm-linux-gcc lcd.c -o lcd
然后通过串口下载到开发板
#rx lcd
#chmod 777 lcd
#./lcd
#ps (查看当前后台运行的iot程序,然后把这个iot程序杀死 ,kill 对应的进程号码)
ps可以查看进程;
5、将framebuffer映射到我们进程空间
首先我们要根据显示设备进行映射,就要获取到它的硬件信息,这个信息在这个头文件有定义:vim /usr/include/linux/fb.h
238 struct fb_var_screeninfo {
239 __u32 xres; /* 宽 度 w */
240 __u32 yres; //高度 h
245
246 __u32 bits_per_pixel; /* 每一个像素用多少位来表示 */
}
FBIOGET_VSCREENINFO
framebuffer设备的参数
2010年11月18日 20:22:00
阅读数:3486
如果应用程序需要知道Framebuffer设备的相关参数,必须通过ioctl()系统调用来完成。
在头文件
前者返回与Framebuffer有关的固定的信息,比如图形硬件上实际的帧缓存空间的大小、能否硬件加速等信息。
而后者返回的是与Framebuffer有关的可变信息。
之所以可变,是因为对同样的图形硬件,可以工作在不同的模式下。
简单来讲,一个支持1024x768x24图形模式的硬件通常也能工作在800x600x16的图形模式下。
可变的信息就是指Framebuffer的长度、宽度以及颜色深度等信息。
这两个命令字相关的结构体有两个:struct fb_fix_screeninfo和struct fb_var_screeninfo。
这两个结构体都比较大,前者用于保存Framebuffer设备的固定信息,后者用于保存Framebuffer设备的可变信息。
在调用ioctl()的时候,要用到这两个结构体。
应用程序中通常要用到struct fb_var_screeninfo的下面这几个字段:
xres、yres、bits_per_pixel,分别表示x轴的分辨率、y轴的分辨率以及每像素的颜色深度(颜色深度的单位为bit/pixel),其类型定义都是无符号32位整型数。
16:32:59
我的电脑 2018/7/17 16:32:59
一、 什么是ioctl。
ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数如下:
int ioctl(int fd, ind cmd, …);
其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,有或没有是和cmd的意义相关的。
ioctl函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道。 【所以说这些cmd不能和内核中的相同,否则就有冲突了】
#include
#include
#include
#include
#include
int main()
{
int fd;
int *plcd=NULL;
fd = open("/dev/fb0",O_RDWR);
if(fd < 0)
{
perror("open lcd fail");
return -1;
}
struct fb_var_screeninfo fbinfo;
ioctl(fd,FBIOGET_VSCREENINFO,&fbinfo);
printf("x:%d y:%d bit_per_pixel:%d\n",fbinfo.xres,fbinfo.yres,fbinfo.bits_per_pixel);
plcd = mmap(
NULL ,//表示映射的地址,为空让系统自动分配
fbinfo.xres*fbinfo.yres*fbinfo.bits_per_pixel/8,//分配内存的大小
PROT_WRITE,//对这个内存区域访问的权限
MAP_SHARED,//其他进程访问的权限
fd,
0//偏移量
);
if(plcd == MAP_FAILED)
{
perror("mmap fail");
close(fd);
return -1;
}
int x,y;
for(y=0;y<480;y++)
{
for(x=0;x<800;x++)
{
*(plcd + x + y*800) = 0x000000FF;
}
}
close(fd);
munmap(plcd,fbinfo.xres*fbinfo.yres*fbinfo.bits_per_pixel/8);
return 0;
}
显示一张图片程序:
#include
#include
#include
#include
#include
#include
int fd;
int *plcd=NULL;
void LCD_Draw_Point(int x,int y,int color)
{
if(x >=0 && x < 800 && y >=0 && y < 480)
{
*(plcd + 800*y + x) = color;
}
}
void bmp_display()
{
int fdBmp;
int w,h;
unsigned char buf[4];
int color_depth;
//打开对应的文件
fdBmp = open("1.bmp",O_RDONLY);
if(fdBmp<0)
{
perror("bmp open fail");
return;
}
//判断是不是BMP图片
read(fdBmp,buf,2);
if(buf[0] != 0x42 || buf[1] != 0x4d)
{
printf("This is not a BMP picture\n");
return;
}
//读图片的宽度
lseek(fdBmp,0x12,SEEK_SET);
read(fdBmp,buf,4);
w = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
//读图片的高度
lseek(fdBmp,0x16,SEEK_SET);
read(fdBmp,buf,4);
h = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
printf("w=%d h=%d\n",w,h);
//读图片的色深
lseek(fdBmp,0x1c,SEEK_SET);
read(fdBmp,buf,2);
color_depth = buf[1] << 8 | buf[0];
//计算图片数据的大小
int size = abs(w*h*color_depth/8) ;
//分配用来保存图片数据的内存空间
unsigned char *pixel = malloc(size);
lseek(fdBmp,54,SEEK_SET);
read(fdBmp,pixel,size);
int x,y;
int i=0;
unsigned char a,r,g,b;
int color;
for(y=0;y < abs(h); y++)
{
for(x=0;x b = pixel[i++]; g = pixel[i++]; r = pixel[i++]; a = (color_depth == 32) ? pixel[i++] : 0; color = a << 24 | r << 16 | g << 8 | b; //组合成一个新的颜色值ARGB int dy = h > 0 ? (h - 1 - y) : y; //判断图片是从左下角还是左上角开始显示 LCD_Draw_Point(x,dy,color); } } free(pixel); close(fdBmp); } int main() { // int fd; // int *plcd=NULL; fd = open("/dev/fb0",O_RDWR); if(fd < 0) { perror("open lcd fail"); return -1; } struct fb_var_screeninfo fbinfo; ioctl(fd,FBIOGET_VSCREENINFO,&fbinfo); printf("x:%d y:%d bit_per_pixel:%d\n",fbinfo.xres,fbinfo.yres,fbinfo.bits_per_pixel); plcd = mmap( NULL ,//表示映射的地址,为空让系统自动分配 fbinfo.xres*fbinfo.yres*fbinfo.bits_per_pixel/8,//分配内存的大小 PROT_WRITE,//对这个内存区域访问的权限 MAP_SHARED,//其他进程访问的权限 fd, 0//偏移量 ); if(plcd == MAP_FAILED) { perror("mmap fail"); close(fd); return -1; } int x,y; for(y=0;y<480;y++) { for(x=0;x<800;x++) { *(plcd + x + y*800) = 0x000000FF; } } bmp_display(); close(fd); munmap(plcd,fbinfo.xres*fbinfo.yres*fbinfo.bits_per_pixel/8); return 0; }