驱动:
基于framebuffer,整体代码参考内核s3c-fb.c
代码初始化步骤:
1、申请fb_info
2、初始化fb_info
3、管脚设置
4、时钟设置
5、控制芯片设置
6、注册fb
代码:
1 /*head file*/ 2 #include <linux/module.h> 3 #include <linux/init.h> 4 #include <linux/clk.h> 5 #include <linux/fb.h> 6 #include <linux/io.h> 7 #include <linux/uaccess.h> 8 #include <linux/kernel.h> 9 #include <linux/slab.h> 10 #include <linux/dma-mapping.h> 11 #include "mylcd.h" 12 13 /*module info*/ 14 MODULE_LICENSE("Dual BSD/GPL"); 15 16 static struct fb_info *my_fbInfo = NULL; 17 static int myLcdBpp = 32; /*位深*/ 18 static short myPaletteSize = 256; /*调色板大小*/ 19 static unsigned int myXvSize = 1024; /*缓冲列大小*/ 20 static unsigned int myYvSize = 600; /*缓冲行大小*/ 21 static unsigned int pseudo_palette[16]; 22 23 /*io管脚寄存器*/ 24 static unsigned int * __iomem gpf0con; 25 static unsigned int * __iomem gpf1con; 26 static unsigned int * __iomem gpf2con; 27 static unsigned int * __iomem gpf3con; 28 static unsigned int * __iomem gpd0con; 29 /*pwm寄存器*/ 30 static unsigned int * __iomem tcfg0; 31 static unsigned int * __iomem tcfg1; 32 static unsigned int * __iomem tcon; 33 static unsigned int * __iomem tcntb1; 34 static unsigned int * __iomem tcmpb1; 35 /*时钟相关寄存器*/ 36 static unsigned int * __iomem clk_div_lcd; 37 static unsigned int * __iomem clk_src_lcd0; 38 static unsigned int * __iomem lcdblk_cfg; 39 static unsigned int * __iomem lcdblk_cfg2; 40 /*lcd寄存器*/ 41 static unsigned int * __iomem vidcon0; 42 static unsigned int * __iomem vidcon1; 43 static unsigned int * __iomem vidcon2; 44 static unsigned int * __iomem vidtcon0; 45 static unsigned int * __iomem vidtcon1; 46 static unsigned int * __iomem vidtcon2; 47 static unsigned int * __iomem wincon0; 48 static unsigned int * __iomem vidoso0a; 49 static unsigned int * __iomem vidoso0b; 50 static unsigned int * __iomem vidoso0c; 51 static unsigned int * __iomem shaadowcon; 52 static unsigned int * __iomem winchmap2; 53 static unsigned int * __iomem vidw00add0b0; 54 static unsigned int * __iomem vidw00add1b0; 55 static unsigned int * __iomem win0map; 56 static unsigned int * __iomem vidw00add2; 57 58 //static T_LCD_REG * __iomem lcdBase; 59 60 static inline unsigned int chan_to_field(unsigned int chan, 61 struct fb_bitfield *bf) 62 { 63 chan &= 0xffff; 64 chan >>= 16 - bf->length; 65 return chan << bf->offset; 66 } 67 68 static int my_fb_setcolreg(unsigned regno, 69 unsigned red, unsigned green, unsigned blue, 70 unsigned transp, struct fb_info *info) 71 { 72 unsigned int val = 0; 73 switch (info->fix.visual) { 74 case FB_VISUAL_TRUECOLOR: 75 /* true-colour, use pseudo-palette */ 76 if (regno < 16) { 77 u32 *pal = info->pseudo_palette; 78 79 val = chan_to_field(red, &info->var.red); 80 val |= chan_to_field(green, &info->var.green); 81 val |= chan_to_field(blue, &info->var.blue); 82 83 pal[regno] = val; 84 } 85 break; 86 default: 87 return 1; /* unknown type */ 88 } 89 90 return 0; 91 } 92 93 static struct fb_ops my_fb_ops = { 94 .owner = THIS_MODULE, 95 .fb_setcolreg = my_fb_setcolreg, 96 .fb_fillrect = cfb_fillrect, 97 .fb_copyarea = cfb_copyarea, 98 .fb_imageblit = cfb_imageblit, 99 }; 100 101 static int fb_fill_var(struct fb_info *myfb) 102 { 103 myfb->var.activate = FB_ACTIVATE_NOW; 104 myfb->var.vmode = FB_VMODE_NONINTERLACED; 105 myfb->var.bits_per_pixel = myLcdBpp; 106 myfb->var.xres_virtual = myXvSize; 107 myfb->var.yres_virtual = myYvSize; 108 myfb->var.xres = myXvSize; 109 myfb->var.yres = myYvSize; 110 myfb->var.xoffset = 0; 111 myfb->var.yoffset = 0; 112 /* always ensure these are zero, for drop through cases below */ 113 myfb->var.transp.offset = 0; 114 myfb->var.transp.length = 0; 115 116 switch (myfb->var.bits_per_pixel) { 117 case 1: 118 case 2: 119 case 4: 120 case 8: 121 /* non palletised, A:1,R:2,G:3,B:2 mode */ 122 myfb->var.red.offset = 5; 123 myfb->var.green.offset = 2; 124 myfb->var.blue.offset = 0; 125 myfb->var.red.length = 2; 126 myfb->var.green.length = 3; 127 myfb->var.blue.length = 2; 128 myfb->var.transp.offset = 7; 129 myfb->var.transp.length = 1; 130 break; 131 132 case 19: 133 /* 666 with one bit alpha/transparency */ 134 myfb->var.transp.offset = 18; 135 myfb->var.transp.length = 1; 136 /* drop through */ 137 case 18: 138 myfb->var.bits_per_pixel = 32; 139 140 /* 666 format */ 141 myfb->var.red.offset = 12; 142 myfb->var.green.offset = 6; 143 myfb->var.blue.offset = 0; 144 myfb->var.red.length = 6; 145 myfb->var.green.length = 6; 146 myfb->var.blue.length = 6; 147 break; 148 149 case 16: 150 /* 16 bpp, 565 format */ 151 myfb->var.red.offset = 11; 152 myfb->var.green.offset = 5; 153 myfb->var.blue.offset = 0; 154 myfb->var.red.length = 5; 155 myfb->var.green.length = 6; 156 myfb->var.blue.length = 5; 157 break; 158 159 case 32: 160 case 28: 161 case 25: 162 myfb->var.transp.length = myfb->var.bits_per_pixel - 24; 163 myfb->var.transp.offset = 24; 164 /* drop through */ 165 case 24: 166 /* our 24bpp is unpacked, so 32bpp */ 167 myfb->var.bits_per_pixel = 32; 168 myfb->var.red.offset = 16; 169 myfb->var.red.length = 8; 170 myfb->var.green.offset = 8; 171 myfb->var.green.length = 8; 172 myfb->var.blue.offset = 0; 173 myfb->var.blue.length = 8; 174 break; 175 176 default: 177 printk("invalid bpp\n"); 178 return -EINVAL; 179 } 180 return 0; 181 } 182 183 static int fb_fill_fix(struct fb_info *myfb) 184 { 185 unsigned int real_size, virt_size, size; 186 dma_addr_t map_dma; 187 188 strcpy(myfb->fix.id ,"mylcd"); 189 190 myfb->fix.type = FB_TYPE_PACKED_PIXELS; //在该方式下,像素值与内存直接对应 191 myfb->fix.accel = FB_ACCEL_NONE; 192 myfb->fix.line_length = (myfb->var.xres_virtual * myfb->var.bits_per_pixel) / 8; //一行的大小(字节数) 193 myfb->fix.xpanstep = myfb->var.xres_virtual > myfb->var.xres ? 1 : 0; 194 myfb->fix.ypanstep = myfb->var.yres_virtual > myfb->var.yres ? 1 : 0; 195 196 switch (myfb->var.bits_per_pixel) { 197 case 32: 198 case 24: 199 case 16: 200 case 12: 201 myfb->fix.visual = FB_VISUAL_TRUECOLOR; 202 break; 203 case 8: 204 if (myPaletteSize >= 256) 205 myfb->fix.visual = FB_VISUAL_PSEUDOCOLOR; 206 else 207 myfb->fix.visual = FB_VISUAL_TRUECOLOR; 208 break; 209 case 1: 210 myfb->fix.visual = FB_VISUAL_MONO01; 211 break; 212 default: 213 myfb->fix.visual = FB_VISUAL_TRUECOLOR; 214 break; 215 } 216 217 /*计算整体缓冲大小*/ 218 real_size = myfb->var.xres * myfb->var.yres; 219 virt_size = myfb->var.xres_virtual * myfb->var.yres_virtual; 220 size = (real_size > virt_size) ? real_size : virt_size; 221 size *= (myfb->var.bits_per_pixel > 16) ? 32 : myLcdBpp; 222 size /= 8; 223 myfb->fix.smem_len = size; 224 size = PAGE_ALIGN(size); 225 myfb->screen_base = dma_alloc_writecombine(myfb->dev, size, 226 &map_dma, GFP_KERNEL); 227 if (!myfb->screen_base) 228 { 229 return -ENOMEM; 230 } 231 memset(myfb->screen_base, 0x0, size); 232 myfb->fix.smem_start = map_dma; 233 234 return 0; 235 } 236 237 /*fun*/ 238 static void myfb_Init(struct fb_info *myfb) 239 { 240 /*var init*/ 241 fb_fill_var(myfb); 242 /*fix init*/ 243 fb_fill_fix(myfb); 244 /*ops init*/ 245 myfb->fbops = &my_fb_ops; 246 /*other init*/ 247 myfb->flags = FBINFO_FLAG_DEFAULT; 248 myfb->pseudo_palette = pseudo_palette; 249 } 250 251 static void mygpio_Init(void) 252 { 253 gpf0con = ioremap(LCD_F0,4); 254 gpf1con = ioremap(LCD_F1,4); 255 gpf2con = ioremap(LCD_F2,4); 256 gpf3con = ioremap(LCD_F3,4); 257 258 writel(LCD_F0_VAL, gpf0con); 259 writel(LCD_F1_VAL, gpf1con); 260 writel(LCD_F2_VAL, gpf2con); 261 writel(LCD_F3_VAL, gpf3con); 262 263 //背光 264 if(1) //pwm方式 265 { 266 gpd0con = ioremap(LCP_PWMIO_BASE,4); 267 writel((readl(gpd0con) & (~(0xf<<4))) | (0x2<<4) , gpd0con); 268 } 269 else //直接点亮方式 270 { 271 int val; 272 273 unsigned int * __iomem gpd0con; 274 unsigned int * __iomem gpd0dat; 275 276 gpd0con = ioremap(0x114000A0,0x4); 277 gpd0dat = ioremap(0x114000A4,0x4); 278 279 val = readl(gpd0con); 280 val &= ~(0xf << 4); 281 val |= (0x1 << 4); 282 writel(val, gpd0con); 283 284 val = readl(gpd0dat); 285 val |= (1 << 1); 286 writel(val, gpd0dat); 287 } 288 } 289 290 static void myclk_Init(void) 291 { 292 clk_div_lcd = ioremap(CLK_DIV_LCD,0x4); 293 clk_src_lcd0 = ioremap(CLK_SRC_LCD,0x4); 294 lcdblk_cfg = ioremap(LCDBLK_CFG, 0x4); 295 lcdblk_cfg2= ioremap(LCDBLK_CFG2, 0x4); 296 297 /*时钟源选择MPLL,具体参考<Exyons 4412 datasheet pg453> 298 *SCLK_FIMD0 = MOUTFIMD0/(FIMD0_RATIO + 1) = 800M/1 = 800M 299 */ 300 writel(readl(clk_div_lcd)&~0xf,clk_div_lcd); 301 writel((readl(clk_src_lcd0)&~0xf)|0x6,clk_src_lcd0); 302 303 /*选择FIMD0 具体参考<Exyons 4412 datasheet pg1796模块图FIMD6.0 > 304 *<Exyons 4412 datasheet pg1799> 305 *Using the display controller data, you can select one of the above data paths by setting LCDBLK_CFG Register 306 *(0x1001_0210). For more information, refer to the "System Others" manual. 307 *<Exyons 4412 datasheet pg1874> 308 *While using RGB interface, the VT_LBLKx bit fields in LCDBLKC_CFG (0x1001_0210) register should be set to 309 RGB Interface out (2'b00), even though you use DSI Video Mode.*/ 310 writel((readl(lcdblk_cfg)&(~(0x3<<10)))|(1<<1),lcdblk_cfg); 311 //writel(readl(lcdblk_cfg2)|(1<<0),lcdblk_cfg2); 312 } 313 314 static void mypwm_Init(void) 315 { 316 tcfg0 = ioremap(LCP_PWM_TCFG0,4); 317 tcfg1 = ioremap(LCP_PWM_TCFG1,4); 318 tcon = ioremap(LCP_PWM_TCON,4); 319 tcntb1 = ioremap(LCP_PWM_TCNTB1,4); 320 tcmpb1 = ioremap(LCP_PWM_TCMPB1,4); 321 /*占空比控制背光亮度*/ 322 writel((readl(tcfg0) &(~0xff))|0xff,tcfg0); 323 writel((readl(tcfg1) &(~(0xf<<4)))|0x4<<4,tcfg1); 324 writel(300,tcntb1); 325 writel(150,tcmpb1); 326 writel((readl(tcon)&(~(0xf<<8)))|(0x1<<9),tcon); 327 328 //使能 329 writel((readl(tcon)&(~(0x1<<9)))|(0x1<<8),tcon); 330 } 331 332 static int lcd_Init(struct fb_info *myfb) 333 { 334 unsigned int val; 335 //lcd设置,寄存器太多,懒得放头文件了 336 vidcon0 = ioremap(0x11c00000,0x4); 337 vidcon1 = ioremap(0x11c00004,0x4); 338 vidcon2 = ioremap(0x11c00008,0x4); 339 vidtcon0 = ioremap(0x11c00010,0x4); 340 vidtcon1 = ioremap(0x11c00014,0x4); 341 vidtcon2 = ioremap(0x11c00018,0x4); 342 343 win0map = ioremap(0x11C00180, 0x4); 344 wincon0 = ioremap(0x11c00020, 0x4); 345 346 vidoso0a = ioremap(0x11c00040,0x4); 347 vidoso0b = ioremap(0x11c00044,0x4); 348 vidoso0c = ioremap(0x11c00048,0x4); 349 shaadowcon = ioremap(0x11c00034,0x4); 350 winchmap2 = ioremap(0x11c0003c,0x4); 351 vidw00add0b0 = ioremap(0x11c000a0,0x4); 352 vidw00add1b0 = ioremap(0x11c000d0,0x4); 353 vidw00add2 = ioremap(0x11C00104, 0x4); 354 355 /*HV mode fclk :44.9~63 推荐51.2Mhz 参考<JT70DT5012-ZH.pdf pg11> 356 *vidcon0 [13-6] VCLK = FIMD*SCLK/(CLKVAL+1) 357 *50M = 800M/(CLK_VAL+1) CLK_VAL= 15 这里为了取整,取50M 358 */ 359 writel(15 << 6, vidcon0); 360 361 /* 362 *<Exyons 4412 datasheet pg1848(时序)> :VSYNC,HSYNC高电平触发信号,VCLK上升沿开始传输数据 363 *<JT70DT5012-ZH pg10(时序)>:VSD,HSD低电平触发信号,CLKV下降沿开始传输数据 364 * 365 *VIDCON1: 366 * [5]:IVSYNC ===> 1 : Inverted(反转) 367 * [6]:IHSYNC ===> 1 : Inverted(反转) 368 * [7]:IVCLK ===> 1 : Fetches video data at VCLK rising edge (下降沿触发,反转?) 369 * [10:9]:FIXVCLK ====> 01 : VCLK running 370 * */ 371 writel((1<<9)|(1<<7)|(1 << 5)|(1 << 6),vidcon1); 372 373 //Reserved: This bit should be set to 1. 374 writel(1 << 14, vidcon2); 375 376 /*参考<JT70DT5012-ZH.pdf pg11> HV mode 377 * thbp: 160 (DCLK) 378 * thfp: 160 (DCLK) 379 * thpw: 1-140 (DCLK) 380 * tvpw: 1-20 (Th) 381 * tvbp: 23 (Th) 382 * tvfp: 12 (Th) 383 */ 384 385 #define HSPW 10 //行同步 386 #define HBPD 160 387 #define HFPD 160 388 #define VSPW 1 //帧同步 389 #define VBPD 23 390 #define VFPD 12 391 writel(((VBPD << 16)|(VFPD << 8)|(VSPW << 0)),vidtcon0); 392 writel(((HBPD << 16)|(HFPD << 8)|(HSPW << 0)),vidtcon1); 393 394 /*设置大小,参考<JT70DT5012-ZH.pdf pg4> Display Format Graphic 1024RGB*600 Dot-matrix 395 * HOZVAL = (Horizontal display size) – 1 and LINEVAL = (Vertical display size) – 1. 396 */ 397 writel(((1023 << 0) | (599 << 11)), vidtcon2); 398 399 /*绑定win,这里直接使用了win0 400 * TODO:0xd=32位,这里强行写的,具体需要参考实际情况写16或32 401 */ 402 writel((1<<6)|(0xD<<2)|1,wincon0); 403 404 /* LCD左上角坐标*/ 405 writel(0<<11|0, vidoso0a); 406 /* LCD右下角坐标 参考 <exynos4412 pg1895> 407 * 24 BPP mode should have X position by 1 pixel. (For example, X = 0, 1, 2, 3….) 408 * 16 BPP mode should have X position by 2 pixel. (For example, X = 0, 2, 4, 6….) 409 * 8 BPP mode should have X position by 4 pixel. (For example, X = 0, 4, 8, 12….) 410 */ 411 if(myLcdBpp == 16) 412 { 413 val = (((1023*2) << 11) | ((599*2) << 0)); 414 } 415 else if((myLcdBpp == 24) || (myLcdBpp == 32)) 416 { 417 val = (((1023) << 11) | ((599) << 0)); 418 } 419 writel(val, vidoso0b); 420 421 /*总大小*/ 422 writel(1024*600, vidoso0c); 423 424 /*帧缓冲起始地址*/ 425 writel(myfb->fix.smem_start, vidw00add0b0); 426 /*帧缓冲结束地址*/ 427 writel(myfb->fix.smem_start+myfb->fix.smem_len, vidw00add1b0); 428 /*设置偏移和宽度*/ 429 writel((0 << 13) | ((1024 * myLcdBpp / 8)<< 0), vidw00add2); 430 431 /*绑定通道和窗口*/ 432 writel(1, shaadowcon); 433 writel((readl(winchmap2)&(~(0x7<<16))&(~0x7))|(1<<16)|(1<<0), winchmap2); 434 435 /*Enables the video output and video control signal*/ 436 writel(readl(vidcon0)|0x3, vidcon0); 437 return 0; 438 } 439 440 static int fs4412_lcd_init(void) 441 { 442 int ret =0 ; 443 /************************kernel相关*******************************/ 444 /**这部分参考s3c-fb.c**/ 445 /*申请fb_info*/ 446 my_fbInfo = framebuffer_alloc(0,NULL); //这里没有私有数据,所以是0;dev没有,平台驱动需要添加。 447 /*初始化fb_info*/ 448 myfb_Init(my_fbInfo); 449 /************************硬件相关*******************************/ 450 /*管脚设置*/ 451 mygpio_Init(); 452 /*时钟设置*/ 453 myclk_Init(); 454 /*控制芯片设置*/ 455 mypwm_Init(); 456 lcd_Init(my_fbInfo); 457 458 /*注册*/ 459 ret = register_framebuffer(my_fbInfo); 460 if(0 > ret){ 461 printk(KERN_ERR "failed to register framebuffer \n"); 462 //dma_free_coherent(fs_info->dev, fs_info->fix.smem_len,fs_info->screen_base, fs_info->fix.smem_start); 463 return ret; 464 } 465 466 printk("Lcd init ok\n"); 467 return 0; 468 } 469 470 /*没考虑退出,这里暂时没写*/ 471 static void fs4412_lcd_exit(void) 472 { 473 printk("Lcd exit\n"); 474 } 475 476 /**/ 477 module_init(fs4412_lcd_init); 478 module_exit(fs4412_lcd_exit);
应用:
下载一个字符转换工具,转换字符,我用的是字模提取V2.2。
先取一个字符转换码:
1、先在右下角的文字输入区输入需要转码的字,按Ctrl+Enter 输入结束
2、在左边列里面 选择取模方式,C51 格式,点击后在右下的 点阵生成区显示转换的字节数组。

3、把字节数组放到测试程序中,我为了方便,直接在c里面用了一个数组来装载。
应用编码
1 #include <unistd.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <fcntl.h> 5 #include <string.h> 6 #include <linux/fb.h> 7 #include <sys/mman.h> 8 #include <sys/ioctl.h> 9 #include <arpa/inet.h> 10 #include <errno.h> 11 12 #define MY_W 320 //图像宽 13 #define MY_H 240 //图像高 14 #define MAX_SIZE 1024*600*4 //lcd屏幕大小,具体要看对应的lcd手册。我的是1024*600 15 16 /*字符矩阵 16*14*/ 17 #define C_W 40 18 #define C_H 35 19 20 static char *fbp = 0; //映射内存起始地址 21 static int fbfd = 0; //帧缓冲fd 22 23 /*存放转换后的汉字字节*/ 24 const unsigned char cbuf[1024]= 25 { 26 /*-- 文字: 我 --*/ 27 /*-- 宋体26; 此字体下对应的点阵为:宽x高=35x35 --*/ 28 /*-- 宽度不是8的倍数,现调整为:宽度x高度=40x35 --*/ 29 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x38,0x00,0x00,0x00, 30 0x0F,0xBE,0x00,0x00,0x00,0x7F,0xFD,0xE0,0x00,0x07,0xF8,0x3C,0x78,0x00,0x3E,0x78, 31 0x3C,0x7C,0x00,0x00,0x78,0x3C,0x3E,0x00,0x00,0x78,0x3C,0x1C,0x00,0x00,0x78,0x3C, 32 0x0C,0x00,0x00,0x78,0x3C,0x06,0x00,0x00,0x78,0x3C,0x0F,0x00,0x7F,0xFF,0xFF,0xFF, 33 0x80,0x00,0x78,0x3C,0x00,0x80,0x00,0x78,0x1C,0x10,0x00,0x00,0x78,0x1C,0x38,0x00, 34 0x00,0x78,0x1C,0x3C,0x00,0x00,0x78,0x5C,0x7E,0x00,0x00,0x7F,0xDC,0x70,0x00,0x00, 35 0x7E,0x1C,0xF0,0x00,0x01,0xF8,0x1F,0xE0,0x00,0x1F,0xF8,0x1F,0xC0,0x00,0x7F,0x78, 36 0x0F,0x80,0x00,0x3C,0x78,0x0F,0x00,0x00,0x30,0x78,0x0F,0x01,0x80,0x00,0x78,0x3F, 37 0x81,0x80,0x00,0x78,0x7B,0xC1,0x80,0x00,0x78,0xF1,0xE1,0x80,0x00,0x7B,0xC0,0xF3, 38 0x80,0x00,0x7F,0x00,0x7F,0x80,0x0F,0xFC,0x00,0x3F,0x80,0x01,0xF0,0x00,0x0F,0xC0, 39 0x00,0xE0,0x00,0x03,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 40 }; 41 42 /*转换,并显示*/ 43 void pch(int *add,const unsigned char* buf) 44 { 45 int row = 0; 46 int col = 0; 47 int i = 0; 48 int color = 0x0; 49 for(row=0;row<C_H;row++) 50 { 51 /*一行数据,按位转换*/ 52 unsigned char tmp[C_W]; 53 int index = 0; 54 int j = 0; 55 int k = 0; 56 for(k=0;k<(C_W/8);k++) 57 { 58 for(j=0;j<8;j++) 59 { 60 tmp[index] = (buf[i] & ((0x1<<7)>>j))>0?1:0 ; 61 index++; 62 } 63 i++; 64 j = 0; 65 } 66 67 /*一行数据,按位显示*/ 68 for(col=0;col<C_W;col++) 69 { 70 if(tmp[col]&1) 71 { 72 color = 0xffff0000; //显示成红色,这里需要什么颜色自己设置(可以自行百度RGB颜色) 73 printf("1"); 74 } 75 else 76 { 77 color = 0x0; //显示成黑色,背景色 78 printf("0"); 79 } 80 add[row*1024+col] = color; 81 } 82 printf("\n\n"); 83 } 84 } 85 86 /*清整屏幕,全部置为黑色*/ 87 void clearfb(void) 88 { 89 memset(fbp,0,MAX_SIZE); //显示成黑色,背景色 90 } 91 92 int main() 93 { 94 int i; 95 fbfd = open("/dev/fb0", O_RDWR); 96 fbp = (char *)mmap(0, MAX_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fbfd, 0); 97 if (fbp == NULL) 98 { 99 printf("Error: failed to map framebuffer device to memory.\n"); 100 return -1; 101 } 102 103 int *add; 104 while(1) 105 { 106 add = (int *)fbp+1024*3+100; /*第三行,偏移100*/ 107 clearfb(); 108 pch(add,cbuf); 109 sleep(2); 110 } 111 112 munmap((void *)add,1024*600*4); 113 return 0; 114 }
显示效果:

posted on
浙公网安备 33010602011771号