首页 / 操作系统 / Linux / 嵌入式Linux下真彩Logo的实现
目前嵌入式产品越来越多了,一般都能带Logo显示启动的。让我们来看看Logo显示是怎么做的(我仅仅做Linux方面的,没有做过WinCE的)。参考一些嵌入式平台的做法,基本是fb_prepare_logo(struct fb_info *info, int rotate)、fb_show_logo(struct fb_info *info, int rotate)两个函数实现的。但是该两个函数其实没有参考的价值。最简单的做法就是调用该两个函数。 1. 在 xxx__probe(struct platform_device *dev) 函数 return 0 之前调用 #if defined(CONFIG_LOGO) // 原来代码先检查info->fbcon_par->rotate是否为FB_ROTATE_UR,这里直接设置FB_ROTATE_UR if (fb_prepare_logo(info, FB_ROTATE_UR)) { /* Start display and show logo on boot */ /* fb_set_cmap(info->cmap, info); */ /* Show the logo */ fb_show_logo(info, FB_ROTATE_UR); } #endif 注意:struct fb_info *info = framebuffer_alloc(...); 2. 在编译内核时选择 Boot logo, Logo_clut224 3. 制作ppm格式logo文件 首先使用 Photoshop 制作 png 文件(Windows下) 再将png图片转成pnm(下面步骤为linux下,我使用CentOS 4.7,使用root权限用户) # pngtopnm uclinux_logo.png > uclinux_logo.pnm 然后将pnm图片的颜色数限制在224 # pnmquant 224 uclinux_logo.pnm > logo_linux_clut224.pnm 最后将pnm图片转换成我们需要的ppm # pnmtoplainpnm logo_linux_clut224.pnm > logo_linux_clut224.ppm 将 logo_linux_clut224.ppm 替换 linux-2.6/drivers/video/logo 中对应的图像 我在这里制作的文件是与分辨率同样大小的文件,如果小于分辨率的话,应该显示在左上角。说实话,上面步骤制作的Logo最多为224色图片效果。能不能显示真彩的Logo呢?实际上肯定是可以的。 我的实现方法:制作自己的fb_prepare_logo、fb_show_logo函数,将真彩的颜色值直接写到Frame Buffer的内存中。1. 将分辨率和颜色位数定义放到头文件中 truecolor_logo.h 我的定义为 #define XRES 800 /* The pixel width of the LCD */ #define YRES 480 /* The pixel height of the LCD */ #define BPX 32 /* The bits depth of the LCD */2. 增加一个 truecolor_logo.c 文件,将该文件加入到内核中,该文件实现 int fb_prepare_truecolor_logo(void)、void fb_show_truecolor_logo(struct fb_info *info) 两个函数 static struct TrueColor { int Width, Height; int ColorBytes; const char *BitData; } _true_color_logo; static unsigned char truecolor_logo_data[] = { ... }; 读取图片的颜色值赋值到这里 int fb_prepare_truecolor_logo(void) { _true_color_logo.ColorBytes = BPX/8; _true_color_logo.Width = 351; /* 这里要与truecolor_logo_data的长度相对应 */ _true_color_logo.Height = 137; _true_color_logo.BitData = truecolor_logo_data; printk("fb_prepare_truecolor_logo ok
"); return (_true_color_logo.ColorBytes > 1); /* 仅仅支持 16 位色或者更高位色 */ }void fb_show_truecolor_logo(struct fb_info *info) { char *framebase = info->screen_base; int m, n; int startx, starty; startx = (XRES- _true_color_logo.Width)/ 2; if(startx < 0) startx = 0; starty = (YRES- _true_color_logo.Height)/ 2; if(starty < 0) starty = 0; for(m=0; m<YRES; m++) { /* 设置图片之外(上、下部)是背景色为黑色 */ if((m < starty) || (m >= _true_color_logo.Height+starty)) { memset(framebase+ (m* XRES* _true_color_logo.ColorBytes), 0, XRES* _true_color_logo.ColorBytes); } else { /* 设置图片之外(左边)是背景色为黑色 */ memset(framebase+ ((m* XRES)* _true_color_logo.ColorBytes), 0, _true_color_logo.ColorBytes* startx); /* 将 Logo 显示在中间, 图片上下需要翻转 */ memcpy(framebase+ ((m* XRES+ startx)* _true_color_logo.ColorBytes), // (_true_color_logo.BitData+ ((m-starty)* _true_color_logo.Width)* _true_color_logo.ColorBytes), (_true_color_logo.BitData+ ((_true_color_logo.Height-(m-starty)-1)* _true_color_logo.Width)* _true_color_logo.ColorBytes), _true_color_logo.ColorBytes* _true_color_logo.Width); /* 设置图片之外(右边)是背景色为黑色 */ memset(framebase+ ((m* XRES+ startx+ _true_color_logo.Width)* _true_color_logo.ColorBytes), 0, _true_color_logo.ColorBytes*(XRES- startx- _true_color_logo.Width)); } } } 3. 修改 xxx__probe(struct platform_device *dev) 函数 #if defined(SHOW_TRUECOLOR_LOGO) if(fb_prepare_truecolor_logo()) fb_show_truecolor_logo(info);#elif defined(CONFIG_LOGO) if (fb_prepare_logo(info, FB_ROTATE_UR)) { /* Start display and show logo on boot */ /* fb_set_cmap(info->cmap, info); */ /* Cancel the code */ /* Show the logo */ fb_show_logo(info, FB_ROTATE_UR); } #endif
收藏该网址