(frame buffer -> fb0)屏幕设备内存映射操作(1)

来源:互联网 发布:7.0神器数据库 编辑:程序博客网 时间:2024/06/18 18:41

/**
 * @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;
}
结果:

屏幕设备内存映射操作(1) - jake - 自由人生
红色部分 划出的一条线
0 0
原创粉丝点击