/**
* @file demo1.c
* @Synopsis /dev/fb0 屏幕设备内存映射操作
* 1:当在ubuntu 下可能有的不存在此设备,需要进行相关参数配制。这里就不作详解了。
* 2:不过在打开此设备情况下,需要对该设备文件
* 进行权限设置sudo chmod 777 /dev/fb0
* 3:运行此程序时如果开启了图形界面功能,则需切换终端
* CTRL+ALT+F1 切换终端
* ALT+F7 切回图形界面
* 当然如果是糸统默认加载是非图形界面,这里就不需要切换了。
*
* @author MrClimb
* @version 1.1.0
* @date 2012-05-10
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
/**
* 定义一个结构体
*/
typedef struct
{
int w;
int h;
int bpp;
void *memo;// 存内存范型首地址
} fbscr_t;
fbscr_t fb_v;
void init_data(void)
{
/**
* 打开屏幕设备
*/
int fd = open("/dev/fb0", O_RDWR);
if(fd < 0)
{
perror("fb0");
exit(1);
}
struct fb_var_screeninfo fb_var;//定义设备屏幕信息
/**
* int ioctl(int d, int request, ...);
* function:用来控制设备文件的属性
* @param int d 文件描述符 这里相当于把这个设备传给了ioctl
* @param int request
* @param ... 一般为 char *argp
* 它随第二个参数 request 不同而不同,参数request 决定了argp是向ioctl 传数据,还是从ioctl 取数据
* @return -1 出错 0 成功
* FBIOGET_VSCREENINFO 对屏幕控制
* file byte io get v screen info
* 获得该屏幕设备信息放组装到 fb_var 中结构体中
*
*/
if(ioctl(fd, FBIOGET_VSCREENINFO, &fb_var) < 0)
{
perror("ioctl");
exit(1);
}
printf("屏幕的宽度:%d\n",fb_var.xres);
printf("屏幕的高度:%d\n",fb_var.yres);
printf("每像素比特位数:%d\n",fb_var.bits_per_pixel);
fb_v.w = fb_var.xres;// 设置屏幕宽度
fb_v.h = fb_var.yres;// 设置屏幕高度
fb_v.bpp = fb_var.bits_per_pixel;// 设置每像素比特位数值
printf("width: %d\n",fb_v.w);
printf("height:%d\n",fb_v.h);
printf("bpp:%d\n",fb_v.bpp);
/**
* void * mmap(void*addr,size_t length,int prot,int flags,int fd,off_t offset);
* 划分屏幕内存映射
* @param void *addr 指向内存的地址,这里由糸统自定义分配
* @param size_t length 在内存区域划分的长度,这里以屏幕来进行计算值
* (屏宽* 屏高 * 每像素比特位数)/8 = ?字节数
* 每像素比特位数这里在 32位操作糸统下 为32
* 一个字节占8位,这里所以除8啦
* @param prot PROT_READ|PROT_WRITE 对映射的这块数据执行读与定权限
* @param flags MAP_SHARED 线程共享的
* @param int fd 文件描述符
* @param off_t offset 从0 位置偏移映射
* @return MAP_FAILED | void * 有效地址
*/
fb_v.memo = mmap(NULL, fb_v.w*fb_v.h*fb_v.bpp/8, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
/**
* MAP_FAILED 映射失败
*/
if(fb_v.memo == MAP_FAILED)
{
perror("map");
exit(1);
}
/**
* 反回无符号 整型地址,也就是内存映射屏幕 整型指针首地址
*/
unsigned int *p = fb_v.memo;
/**
* p+1024*100+512
*/
int i = 0;
for(i = 0; i<100; i++)
{
//*(p+i) = 0x00ff0000;// 32 位 结果发现画出了一条红线
/**
* 我想换一行划出横线
*/
// *(p+1024+i) = 0x00ff0000;// 结果没看出效果
/**
* 下面移位50行划出一行线
*/
// *(p+1024*50+i) = 0x00ff0000;
/**
* 向右移,移到差不多中间去
*/
*(p+1024*100+512+i) = 0x00ff0000;
}
close(fd);
}
int main(void)
{
init_data();
return 0;
}