内核版本: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; }
全文完。