内核版本:Linux-2.6.32.2 实验平台:mini2440 + 统宝3.5寸屏(TD035STED4)
这里主要是对lcd的帧缓存进行读写操作,并显示出红色,当然也可以显示其他任何东西。
首先介绍一下用到的mmap系统调用,mmap系统调用原型如下:
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
void munmap(void *addr, sizt_t length);
mmap系统调用的作用是将文件内容映射到进程的虚拟地址空间,通过对这段内存的读取和修改,来实现对文件的读取和修改,而不必再通过read、write等操作。
mmap系统调用介绍完了,那么来看对lcd的操作代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
void show(char *fb, int width, int height)
{
int x, y;
short *p = (short *)fb;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
/*
* rgb565
* 11111 000000 00000 -> red
* 00000 111111 00000 -> green
* 00000 000000 11111 -> blue
*/
*p++ = 0xf800;
}
}
}
int main(void)
{
int fd;
struct fb_var_screeninfo var;
int size;
char *fb;
fd = open("/dev/fb0", O_RDWR);
if (fd < 0) {
printf("can't open /dev/fb0!\n");
return -1;
}
ioctl(fd, FBIOGET_VSCREENINFO, &var);
printf("xres %d yres %d bpp %d\n", var.xres,
var.yres, var.bits_per_pixel);
size = var.xres * var.yres * (var.bits_per_pixel / 8);
fb = (char *)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
show(fb, var.xres, var.yres);
while (1);
munmap(fb, size);
close(fd);
return 0;
}
另附上mini2440上显示bmp图片的代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <string.h>
#define rgb888_to_rgb565(r, g, b) \
((((r) << 8) & 0xf800) | (((g) << 3) & 0x07e0) | (((b) >> 3)))
void show(char *fb, int width, int height,
char *image, int image_width, int image_height, int row_width)
{
int x, y;
short *p;
char *tmp;
image += row_width * (image_height - 1);
for (y = 0; y < height && y < image_height; y++, image -= row_width) {
p = (short *)(fb + y * width * 2);
tmp = image;
for (x = 0; x < width && x < image_width; x++, tmp += 3) {
*p++ = rgb888_to_rgb565(tmp[2], tmp[1], tmp[0]);
}
}
}
int main(int argc, char *argv[])
{
int fd;
struct fb_var_screeninfo var;
int size;
char *fb;
FILE *fp;
char fh[14];
char ih[40];
char *image;
int width;
int height;
int row_width;
if (argc < 2) {
printf("please select a bitmap file!\n");
return -1;
}
fd = open("/dev/fb0", O_RDWR);
if (fd < 0) {
printf("can't open /dev/fb0!\n");
return -1;
}
ioctl(fd, FBIOGET_VSCREENINFO, &var);
printf("xres %d yres %d bpp %d\n", var.xres,
var.yres, var.bits_per_pixel);
size = var.xres * var.yres * (var.bits_per_pixel / 8);
fb = (char *)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
fp = fopen(argv[1], "rb");
if (fp == NULL) {
printf("no such bitmap file!\n");
return -1;
}
fread(fh, 1, sizeof(fh), fp);
fread(ih, 1, sizeof(ih), fp);
if (fh[0] != 0x42 && fh[1] != 0x4d) {
printf("not a bitmap file!\n");
return -1;
}
if ((*(short *)&ih[14]) != 24) {
printf("not suport this format!\n");
return -1;
}
width = *((int *)&ih[4]);
height = *((int *)&ih[8]);
printf("width %d height %d\n", width, height);
row_width = width * ((*((short *)&ih[14])) / 8);
while ((row_width & 3) != 0) row_width++;
image = (char *)malloc(row_width * height);
if (image == NULL) {
printf("no enough memory!\n");
return -1;
}
fread(image, 1, row_width * height, fp);
memset(fb, 0, size); /* clear the screen */
show(fb, var.xres, var.yres, image, width, height, row_width);
/* while (1);*/
free(image);
fclose(fp);
munmap(fb, size);
close(fd);
return 0;
}
全文完。