相对来说,低性能的嵌入式用 framebuffer 更好。如果性能好可以用 X 服务实现图形显示。前者基于内核的显示驱动,后者看 X 服务的驱动了。
X 服务可以跑很多软件不需要重新开发,但 c/s 架构效率不是很好。
framebuffer 是软件直接 *** 作硬件的存储器,性能实现比较好。但很多功能都要自己写代码实现。
显示图片在 fb 里面我要是没记错,就是把图片解码成你的软件支持的格式,之后把这部分数据写入 fb 内存。
怎么弄就别找我了。建议看看相关的开发文章。
还有就是 QT 库本身就有直接 fb 输出的函数库,GTK 似乎也有,但目前好像还不是完全可用。用他们作为过渡函数库还不错的。但要注意他们的软件协议!
本移植主要参考友善之臂移植手册完成,做个笔记以备不时之需Linux-2.6.32 内核LCD驱动移植
使用环境:fedora9
交叉编译工具链:arm-linux-gcc-4.4.3
内核源码来源:https://www.kernel.org/pub/linux/kernel/v2.6/
内核存放目录:/opt/mymini2440/linux-2.6.32
一、LCD背光驱动移植
在、opt/mymini2440/linux-2.6.32/drivers/video/目录下添加背光驱动程序mini2440_backlight.c,内容如下:
//以下头文件可能并不是每一个都必须的,但多余的并不会影响驱动程序的内容
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <mach/regs-clock.h>
#include <plat/regs-timer.h>
#include <mach/regs-gpio.h>
#include <linux/cdev.h>
#undef DEBUG
//#define DEBUG
#ifdef DEBUG
#define DPRINTK(x...) {printk(__FUNCTION__"(%d): ",__LINE__)printk(##x)}
#else
#define DPRINTK(x...) (void)(0)
#endif
//定义背光驱动的名称为backligh,将会出现在/dev/backlight
#define DEVICE_NAME "backlight"
//定义背光变量bl_state,以记录背光的开关状态
static unsigned int bl_state
//设置背光开关的函数,主要是翻转背光变量bl_state
static inline void set_bl(int state)
{
bl_state = !!state//翻转bl_state 变量
s3c2410_gpio_setpin(S3C2410_GPG(4), bl_state)//把结果写入背光所用的寄存器GPG4
}
//获取背光状态
static inline unsigned int get_bl(void)
{
return bl_state
}
//从应用程序读取参数,并传递到内核中
static ssize_t dev_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
{
unsigned char ch
int ret
if (count == 0) {
return count
}
//使用copy_from_user 函数从用户层/应用层读取参数
ret = copy_from_user(&ch, buffer, sizeof ch) ? -EFAULT : 0
if (ret) {
return ret
}
ch &= 0x01//判断奇数还是偶数
set_bl(ch)//设置背光状态
return count
}
//把内核参数传递给用户层/应用层的读函数
static ssize_t dev_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
int ret
unsigned char str[] = {'0', '1' }
if (count == 0) {
return 0
}
//使用copy_to_user 函数把内核参数传递到用户层/应用层
ret = copy_to_user(buffer, str + get_bl(), sizeof(unsigned char) ) ? -EFAULT : 0
if (ret) {
return ret
}
return sizeof(unsigned char)
}
//设备 *** 作集
static struct file_operations dev_fops = {
owner: THIS_MODULE,
read:dev_read,
write: dev_write,
}
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
}
//设备初始化,内核启动时就有效
static int __init dev_init(void)
{
int ret
ret = misc_register(&misc)
printk (DEVICE_NAME"\tinitialized\n")
//初始化背光所用的端口GPG4 为输出
s3c2410_gpio_cfgpin(S3C2410_GPG(4), S3C2410_GPIO_OUTPUT)
//启动内核时打开背光
set_bl(1)
return ret
}
static void __exit dev_exit(void)
{
misc_deregister(&misc)
}
module_init(dev_init)//注册背光驱动模块
module_exit(dev_exit)//卸载背光驱动模块
MODULE_LICENSE("GPL")
MODULE_AUTHOR("FriendlyARM Inc.")
在/opt/mymini2440/linux-2.6.32/drivers/video/目录项的菜单文件Kconfig中添加LCD背光驱动配置菜单如下:
config FB_S3C2410_DEBUG
bool "S3C2410 lcd debug messages"
depends on FB_S3C2410
help
Turn on debugging messages. Note that you can set/unset at run time
through sysfs
config BACKLIGHT_MINI2440
tristate "Backlight support for mini2440 from FriendlyARM"
depends on MACH_MINI2440 &&FB_S3C2410
help
backlight driver for MINI2440 from FriendlyARM
config FB_SM501
tristate "Silicon Motion SM501 framebuffer support"
在/opt/mymini2440/linux-2.6.32/drivers/video/Makefile中添加背光驱动目标文件
# the test framebuffer is last
obj-$(CONFIG_FB_VIRTUAL) += vfb.o
#video output switch sysfs driver
obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
obj-$(CONFIG_BACKLIGHT_MINI2440) += mini2440_backlight.o
配置内核:
Device Drivers --->Graphics support ---> <*>Support for frame buffer devices
---><*> Backlight support for mini2440 from FriendlyARM
背光驱动移植完毕!
二、LCD驱动移植
在内核中添加各种LCD 类型的支持(我是X35的屏,也是我只需关注的部分,不过还是都添加了,X35有红色标出)
删除mach-mini2440.c原有代码(本人115行-158行)
162
163 //LCD2VGA(分辨率为1024x768)模块的配置和参数设置
164 #elif defined(CONFIG_FB_S3C2410_VGA1024768)
165 #define LCD_WIDTH 1024
166 #define LCD_HEIGHT 768
167 #define LCD_PIXCLOCK 80000
168 #define LCD_RIGHT_MARGIN 15
169 #define LCD_LEFT_MARGIN 199
170 #define LCD_HSYNC_LEN 15
171 #define LCD_UPPER_MARGIN 1
172 #define LCD_LOWER_MARGIN 1
173 #define LCD_VSYNC_LEN 1
174 #define LCD_CON5 (S3C2410_LCDCON5_FRM565 | S3C2410_LCDCON5_HWSWP)
175
176 #elif defined(CONFIG_FB_S3C2410_X240320)
177 #define LCD_WIDTH 240
178 #define LCD_HEIGHT 320
179 #define LCD_PIXCLOCK 170000
180 #define LCD_RIGHT_MARGIN 25
181 #define LCD_LEFT_MARGIN 0
182 #define LCD_HSYNC_LEN 4
183 #define LCD_UPPER_MARGIN 0
184 #define LCD_LOWER_MARGIN 4
185 #define LCD_VSYNC_LEN 9
186 #define LCD_CON5 (S3C2410_LCDCON5_FRM565 | S3C2410_LCDCON5_INVVDEN | S3C2410_LCDCON5_INVVFRAME | S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVCLK | S3C2410_LCDCON5_HWSWP )
187 #endif
188
189 #if defined (LCD_WIDTH)
190
191 static struct s3c2410fb_display mini2440_lcd_cfg __initdata = {
192 #if !defined (LCD_CON5)
193 .lcdcon5 = S3C2410_LCDCON5_FRM565 |
194 S3C2410_LCDCON5_INVVLINE |
195 S3C2410_LCDCON5_INVVFRAME |
196 S3C2410_LCDCON5_PWREN |
197 S3C2410_LCDCON5_HWSWP,
198 #else
199 .lcdcon5 = LCD_CON5,
200 #endif
201 .type = S3C2410_LCDCON1_TFT,
202 .width = LCD_WIDTH,
203 .height = LCD_HEIGHT,
204 .pixclock = LCD_PIXCLOCK,
205 .xres = LCD_WIDTH,
206 .yres = LCD_HEIGHT,
207 .bpp= 16,
208 .left_margin= LCD_LEFT_MARGIN + 1,
209 .right_margin = LCD_RIGHT_MARGIN + 1,
210 .hsync_len = LCD_HSYNC_LEN + 1,
211 .upper_margin = LCD_UPPER_MARGIN + 1,
212 .lower_margin = LCD_LOWER_MARGIN + 1,
213 .vsync_len = LCD_VSYNC_LEN + 1,
214 }
215
216 static struct s3c2410fb_mach_info mini2440_fb_info __initdata = {
217 .displays = &mini2440_lcd_cfg,
218 .num_displays = 1,
219 .default_display = 0,
220 .gpccon = 0xaa955699,
221 .gpccon_mask= 0xffc003cc,
222 .gpcup = 0x0000ffff,
223 .gpcup_mask = 0xffffffff,
224 .gpdcon = 0xaa95aaa1,
225 .gpdcon_mask= 0xffc0fff0,
226 .gpdup = 0x0000faff,
227 .gpdup_mask = 0xffffffff,
228 .lpcsel = 0xf82,
229 }
230
231 #endif
232
然后打开drivers/video/Kconfig,在大概1935 行加入以下配置信息:
1923 config FB_S3C2410_DEBUG
1924 bool "S3C2410 lcd debug messages"
1925 depends on FB_S3C2410
1926 help
1927 Turn on debugging messages. Note that you can set/unset at run time
1928 through sysfs
1929
1930 choice
1931 prompt "LCD select"
1932 depends on FB_S3C2410
1933 help
1934 S3C24x0 LCD size select
1935
1936 config FB_S3C2410_T240320
1937 boolean "3.5 inch 240X320 Toppoly LCD"
1938 depends on FB_S3C2410
1939 help
1940 3.5 inch 240X320 Toppoly LCD
1941
1942 config FB_S3C2410_N240320
1943 boolean "3.5 inch 240X320 NEC LCD"
1944 depends on FB_S3C2410
1945 help
1946 3.5 inch 240x320 NEC LCD
1947
1948 config FB_S3C2410_TFT640480
1949 boolean "8 inch 640X480 L80 LCD"
1950 depends on FB_S3C2410
1951 help
1952 8 inch 640X480 LCD
1953
1954 config FB_S3C2410_TFT800480
1955 boolean "7 inch 800x480 TFT LCD"
1956 depends on FB_S3C2410
1957 help
1958 7 inch 800x480 TFT LCD
1959
1960 config FB_S3C2410_VGA1024768
1961 boolean "VGA 1024x768"
1962 depends on FB_S3C2410
1963 help
1964 VGA 1024x768
1965
1966 config FB_S3C2410_X240320
1967 boolean "3.5 inch 240X320 LCD(ACX502BMU)"
1968 depends on FB_S3C2410
1969 help
1970 3.5 inch 240X320 LCD(ACX502BMU)
1971
1972 endchoice
1973
1974 config BACKLIGHT_MINI2440
配置内核
Device Drivers ---> Graphics support ---> <*>Support for frame buffer devices ---> LCD select (3.5 inch 240X320 LCD(ACX502BMU)) ---> (X) 3.5 inch 240X320 LCD(ACX502BMU)
LCD驱动移植完成!!!
三、开机logo和开机信息显示
Device Drivers ---> Graphics support ---> <*>Support for frame buffer devices --->[*] Bootup logo ---> [*] Standard 16-color Linux logo (本人的24位死活不能显示,先改成16位吧)
在文件系统rootfs/etc/inittab下作如下修改(为了在LCD上显示打印信息):
1 ::sysinit:/etc/init.d/rcS
2 tty1::askfirst:-/bin/sh//添加
3 s3c2410_serial0::askfirst:-/bin/sh
4 ::ctrlaltdel:/sbin/reboot
5 ::shutdown:/bin/umount -a -r
6
四,编译测试
#make zImage
#cd arch/arm/boot/
#mkimage -n 'mini2440_linux' -A arm -O linux -T kernel -C none -a 0x31000000 -e 0x31000040 -d zImage uImage
#chmod a+x uImage
#cp uImage /tftp/boot
设置U-BOOT参数如下:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)