尽量用新版本的ubuntu,旧版本的ubuntu还需要自己打开framebuffer的配置.
编写代码
main.c
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include "fbmap.h"
#define WIDTH 800
#define HEIGHT 600
// 设置颜色
void set(uint8_t *map, uint32_t mapSize, uint32_t rgbColor)
{
uint32_t offset;
uint8_t r = (rgbColor >> 16) & 0xFF;
uint8_t g = (rgbColor >> 8) & 0xFF;
uint8_t b = (rgbColor >> 0) & 0xFF;
for (offset = 0; offset < mapSize;)
{
map[offset++] = r;
map[offset++] = g;
map[offset++] = b;
}
}
int main(void)
{
// rgbMap就是显示到屏幕上的内容数组 [300*300*3]
uint8_t rgbMap[WIDTH * HEIGHT * 3];
static uint32_t key=0;
while(1)
{
set(rgbMap, sizeof(rgbMap), 0x0000FF);//蓝
fb_output(rgbMap, 0, 0, WIDTH, HEIGHT);
sleep(1);
}
return 0;
}
fbmap.c
/*
* fb矩阵输出
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include "fbmap.h"
typedef struct
{
int fd;
unsigned char *fb;
size_t fbSize;
struct fb_var_screeninfo fbInfo;
//bytes per point
int bpp;
//bytes width, height
int bw, bh;
} FbMap;
static FbMap *fbmap = NULL;
int fb_width = 1024, fb_height = 600;
void fb_release(void)
{
if (!fbmap)
return;
if (fbmap->fb)
munmap(fbmap->fb, fbmap->fbSize);
if (fbmap->fd > 0)
close(fbmap->fd);
free(fbmap);
fbmap = NULL;
}
//返回0正常
int fb_init(void)
{
if (fbmap)
return 0;
fbmap = (FbMap *)calloc(1, sizeof(FbMap));
fbmap->fd = open(FB_PATH, O_RDWR);
if (fbmap->fd < 1)
{
fprintf(stderr, "fb_init: open %s err \r\n", FB_PATH);
fb_release();
return -1;
}
if (ioctl(fbmap->fd, FBIOGET_VSCREENINFO, &fbmap->fbInfo) < 0)
{
fprintf(stderr, "fb_init: ioctl FBIOGET_VSCREENINFO err \r\n");
fb_release();
return -1;
}
printf("frameBuffer: %s, %d x %d, %dbytes / %dbpp\r\n",
FB_PATH, fbmap->fbInfo.xres, fbmap->fbInfo.yres, fbmap->fbInfo.bits_per_pixel / 8, fbmap->fbInfo.bits_per_pixel);
fbmap->bpp = fbmap->fbInfo.bits_per_pixel / 8;
fbmap->bw = fbmap->bpp * fbmap->fbInfo.xres;
fbmap->bh = fbmap->bpp * fbmap->fbInfo.yres;
fbmap->fbSize = fbmap->fbInfo.xres * fbmap->fbInfo.yres * fbmap->bpp;
fb_width = fbmap->fbInfo.xres;
fb_height = fbmap->fbInfo.yres;
fbmap->fb = (unsigned char *)mmap(0, fbmap->fbSize, PROT_READ | PROT_WRITE, MAP_SHARED, fbmap->fd, 0);
if (!fbmap->fb)
{
fprintf(stderr, "fb_init: mmap size %ld err \r\n", fbmap->fbSize);
fb_release();
return -1;
}
return 0;
}
/*
* 屏幕输出
* data: 图像数组,数据长度必须为 width*height*3, RGB格式
* offsetX, offsetY: 屏幕起始位置
* width, height: 图像宽高
*/
void fb_output(uint8_t *data, uint32_t offsetX, uint32_t offsetY, uint32_t width, uint32_t height)
{
int x, y, offset;
//初始化检查
if (fb_init())
return;
//参数检查
if (!data || width < 1 || height < 1)
return;
//起始坐标限制
if (offsetX < 0)
offsetX = 0;
else if (offsetX >= fbmap->fbInfo.xres)
return;
if (offsetY < 0)
offsetY = 0;
else if (offsetY >= fbmap->fbInfo.yres)
return;
//范围限制
if (width < 1)
return;
else if (offsetX + width - 1 >= fbmap->fbInfo.xres)
width = fbmap->fbInfo.xres - offsetX;
if (height < 1)
return;
else if (offsetY + height - 1 >= fbmap->fbInfo.yres)
height = fbmap->fbInfo.yres - offsetY;
//覆盖画图
for (y = 0; y < height; y++)
{
//当前行在fb数据的偏移
offset = (y + offsetY) * fbmap->bw + (0 + offsetX) * fbmap->bpp;
//画data中的一行数据
for (x = 0; x < width; x++)
{
if (fbmap->bpp == 4)
fbmap->fb[offset + 3] = 0xff; //A
fbmap->fb[offset + 2] = *data++; //R
fbmap->fb[offset + 1] = *data++; //G
fbmap->fb[offset + 0] = *data++; //B
offset += fbmap->bpp;
}
}
}
fbmap.h
/*
* fb矩阵输出
*/
#ifndef _FBMAP_H_
#define _FBMAP_H_
#include <stdint.h>
//指定fb设备
#define FB_PATH "/dev/fb0"
//屏幕宽高(调用一次fb_output之后更新)
extern int fb_width, fb_height;
/*
* 屏幕输出
* data: 图像数组,数据长度必须为 width*height*3, RGB格式
* offsetX, offsetY: 屏幕起始位置
* width, height: 图像宽高
*/
void fb_output(uint8_t *data, uint32_t offsetX, uint32_t offsetY, uint32_t width, uint32_t height);
#endif
切换到命令行界面(关闭ubuntu的图形界面)
ctrl+alt+f1
(切回ubuntu的图形界面可以按 ctrl +alt +f7 )
进行代码编译并运行

