在Linux 系统中LCD的应用程序有特定编写模板。
1.打开/dev/fbX
fp = open ("/dev/fb0",O_RDWR);
2.获取可变参数,固定参数
ioctl(fp,FBIOGET_VSCREENINFO,&vinfo) 可变参数
ioctl(fp,FBIOGET_FSCREENINFO,&finfo) 固定参数
3.内存映射(mmap)
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
/*这就是把fp所指的文件中从开始到 screensize 大小的内容给映射出来,得到一个指向这块空间的指针*/
fbp =(unsigned char *) mmap (0, screensize,
PROT_READ | PROT_WRITE,
MAP_SHARED, fp,0);
4.使用映射后的地址对屏进行操作。
使用上面得到的 fbp 指针来操作显示缓冲区了。
把lcd看成是一块内存,使用mmap函数把它的缓冲区映射到进程空间中,然后通过映射后的地址直接操作驱动中的显示缓冲区,往这块缓冲写数据,lcd就会按数值转换成相应颜色显示在LCD屏上。
示例:要在(100,200) 处画一个点:
映射:
mmap:
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
功能:把文件的内存映射到进程的地址空间中。
参数:
addr: 设置一个可用的地址,一般情况你不知道哪个地址是可用的。所以,给0,表示由系统自动分配。
length:映射的长度
prot:属性,如PROT_READ,PROT_WRITE,
PROT_EXEC 映射后的地址空间可以执行代码.
PROT_READ 映射后可以读.
PROT_WRITE 映射后可以写
PROT_NONE 映射后不能访问
flags:保护标志
常用的是共享方式 MAP_SHARED
fd :open返回的文件描述符
offset:是从文件的哪个地方开始映射。
返回值:映射后的地址首地址
fbp =(unsigned char *) mmap (0, screensize,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fp,0);
计算偏移:
off = (800*200+100) * 4;
写成通用的表示-->(xres *y + x) * bpp / 8;
写入数据:
*(unsigned int *)(fbp+off) = 0x00ff0000;
或:
* (fbp+off) = 0x00; //低地址存低字节
* (fbp+off+1) = 0x00;
* (fbp+off+2) = 0xff;
* (fbp+off+3) = 0x00;
封装成一个函数:
void show_pixle(int x,int y,unsigned int c)
{
location = x * (vinfo.bits_per_pixel / 8) + y * finfo.line_length;
*(unsigned int*)(fbp + location) = c;
}
LCD中的换屏技术:
从u-boot开始:
有一个 bootargs 环境变量,这里参数就是传递给内核的。
对tiny4412提供的内核,可以通过修改 bootargs 实现驱动不同的LCD屏。
bootargs=noinitrd root=/dev/nfs nfsroot=192.168.10.106:/root/work/root_nfs/ ip=192.168.10.123:192.168.10.106:192.168.10.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0 coherent_pool=2M lcd=S70
上面传递了 lcd=S70 ,就可以驱动不同屏。
内核启动阶段,根据lcd=S70这个信息,在注册平台设备/驱动前把LCD平台数据修改了。