十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
1,概念
宁洱ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18980820575(备注:SSL证书合作)期待与您的合作!
电子枪:用来打像素点
像素点:即分辨率
RGD:三原色 在计算机领域中,每个像素点又RGB三原色组成像素点的要素值。屏幕上的一个点对应一个具体的数值,该初始值包含红绿蓝三者的值
显存:它会从DDRAM中划出一部分当显存用,操作LCD就变成操作显存和LCD对应的值。那我们LCD驱动主要工作就是配置LCD控制器,往显卡中传输要在LED上显示的内容,
LCD驱动开发的主要工作:申请显存,配置LED控制器,让LED控制器自动的,周期性的,读取显存中的数据,按照一定的时序(点和点时间间隔,换行时间,换屏时间)将读取到的数据发送给LCD屏LCD硬件会完成像素点的显示,也就是配置他们之间传数据要和它打点速度兼容
framebuffer:导出LCD物理缓冲区(显存)到用户空间(0~3G),用户空间要显示一副图像到LCD屏,在用户空间直接操作显存,在用户空间直接操作显存,将要显示的图像拷贝到显存中的相应位置,要实现mmap
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/mmap.h>
#include<linux/fb.h>
srtuct fb_fix_screeninfo fbfix = {0};
struct fb_var_screeninfo fbvar = {0};
int *fb32 = NULL;
#define COLOR_RED 0x00ff0000
#define COLOR_GREEN 0X0000FF00
#define COLOR_BLUE 0X000000FF
/*记录显存大小*/
long screensize = 0;
int main()
{
intfd = -1;
int x = 0;
int y = 0;
fd = open;
fd = open("/dev/fb0");
if(fd<0)
{
printf("open /dev/fb0/ failed! \n");
return -1;
}
/*获取屏幕固定信息*/
ioctl(fd,FBIOGET_FSCREENINFO,&fbfox);
/*获得屏幕可变信息*/
ioctl(fd,FBIOGET_VSCREENINFO,&fbvar);
screensize = fbvar.xres *fbvar.yres *(fbvar.bits_per_pixel);
fb32 = mmap(0,screensize,PROT_READ,MAP_SHARED,fd,0);
if(fb32 = =NULL)
{
printf("mmap framebuffer to user space failed! \n");
return -1;
}
/*操作显存*/
if(fbvar.bits_per_pixel ==8)
{
printf("starting 8 bpp framebuffer test ... \n");
}
else if(fbvar.bits_per_pixel ==16)
{
printf("starting 16 bpp framebuffer test ... \n");
}
if(fbvar.bits_per_pixel ==24)
{
printf("starting 24 bpp framebuffer test ... \n");
}
if(fbvar.bits_per_pixel ==32)
{
printf("starting 32 bpp framebuffer test ... \n");
for(;y<fbvar.yres/3;y++)
{
for(x=0;x<fbvar.xres;x++)
{
*(fb32 + x+y*fbvar.xres)= COLOR_RED;
}
}
for(;y<fbvar.yres2/3;y++)
{
for(x=0;x<fbvar.xres;x++)
{
*(fb32 + x+y*fbvar.xres)= COLOR_GREEN;
}
}
for(;y<fbvar.yres;y++)
{
for(x=0;x<fbvar.xres;x++)
{
*(fb32 + x+y*fbvar.xres)= COLOR_BLUE;
}
munmap(fd32,screensize);
close(fd);
return 0;
}
一般芯片把不确定的信息变成可调节的信息
LCD 管脚:VD0~VD23:数据管脚 传送RGB
HSYNC:当该管脚收到信号是,电子枪由最右端跳回最左端
VSYNC:该管脚收到信号时,电子枪由右下角跳回左上角
VCLK::每个VCLK信号使电子枪跳到下一个像素点
VNEN:视频数据使能电子枪接收VD0~VD23上的数据。
3.时序图
HSPW:水平同步脉冲宽度
HBPD:从水平同步信号到下一行有效信号的宽度,即电子枪从最右端回到最左端的时间
HOZVAL:一行像素个数
HFPD:打完一行像素到下一个水平同步信号,
VSPW垂直同步脉冲宽度
VBPD:一针结束后,垂直同步信号以后的无效行数
LINEVAL:一共有多少行
VFPD:一针结束后,垂直同步信号以前的无效行数
极性:信号的极性根据外接LCD相应极性可配置
linux中framebuffer框架
linux下LCD驱动开发的最主要数据结构
struct fb_info{
atomic_t count;
int node;
int flags;
struct mutex lock;/* Lock for open/release/ioctl funcs */
struct mutex mm_lock;/* Lock for fb_mmap and smem_* fields */
struct fb_var_screeninfo var;/* Current var */
struct fb_fix_screeninfo fix;/* Current fix */
struct fb_monspecs monspecs;/* Current Monitor specs */
struct work_struct queue;/* Framebuffer event queue */
struct fb_pixmap pixmap;/* Image hardware mapper */
struct fb_pixmap sprite;/* Cursor hardware mapper */
struct fb_cmap cmap;/* Current cmap */
struct list_head modelist; /* mode list */
struct fb_videomode *mode;/* current mode */
struct fb_ops *fbops; //重点
#endif
char __iomem *screen_base;/* Virtual address *///显存的起始虚拟地址3G~4G
unsigned long screen_size;/* Amount of ioremapped VRAM or 0 */ //记录显存大小
}
struct fb_var_screeninfo {
__u32 xres;/* visible resolution*/
__u32 yres;
__u32 xres_virtual;/* virtual resolution*/
__u32 yres_virtual;
__u32 xoffset;/* offset from virtual to visible */
__u32 yoffset;/* resolution*/
__u32 bits_per_pixel;/* guess what*/
__u32 grayscale;/* != 0 Graylevels instead of colors */
struct fb_bitfield red;/* bitfield in fb mem if true color, */
struct fb_bitfield green;/* else only length is significant */
struct fb_bitfield blue;
struct fb_bitfield transp;
}
struct fb_fix_screeninfo {
char id[16];/* identification string eg "TT Builtin" */
unsigned long smem_start;/* Start of frame buffer mem */显存的起始位置且是物理的
/* (physical address) */
__u32 smem_len;/* Length of frame buffer mem */显存大小
__u32 type;/* see FB_TYPE_**/
__u16 reserved[3];/* Reserved for future compatibility */
};
如果要自己写个LCD驱动,框架应该怎么写
1)分配一个fb_info
s3cfb_alloc_framebffer()
2)设置/填充该结构体
3)初始化硬件 如:配置GPIO管脚功能,时序初始化配置,申请显存,将申请到的显存起始地址告诉LCD控制器
4)注册fb_info结构
s3cfb_register_framebuffer(...);
5)内核中的驱动程序
通过make menuconfig可以得到一个路径和变量。我的变量和路径是:Graphics support->Support for frame buffer devices(S5P Framebuffer support (Defined at drivers/video/samsung/Kconfig:5 CONFIG_FB_S5P ) ) Select LCD Type (WA101S)(CONFIG_FB_S5P_WA101S)
->Select LCD Type
平台设备总线架构
bus
device:evs.c
driver:s3cfb.c
资源 static struct resource s3cfb_resource={}
platfirm_data
核心文件是 fbmen.c
s3cfb.c s3cfb_fimd6x.c
s3cfb.c ->需要完成的驱动程序 ,s3cfb_fimd6x.c封装了功能函数,供s3cfb.c调用
LCD手册中
thpw:1~40:20
thb:46
HBPD:46-20
s3cfb_init_global(fbdev)
{
s3cfb_set_polarity(ctrl);
s3cfb_set_timing(ctrl);
}
struct file_operations fb_fops
{
.opem
.read
.write
.mmap
.ioctl
}
找对应关系的算法register_fb[minor] =fb_info
用户空间 open()
fb_ops.open()
{
看/dev/fbn对应的fb_info.fbops->ops
存在则调用fb_info.fbops->open不存在执行默认操作
}
5驱动程序要驱动的硬件和CPU连接方式
1,gpio连接
2. 类似于内存接口,有数据线,地址线,控制线BANK
3,协议类接口