玖叶教程网

前端编程开发入门

《嵌入式设备驱动程序基础笔记》第20期

上期文章编写了LCD的驱动程序,测试时用的catecho命令进行测试,这期视频编写一个LCD的应用测试程序。

lcd.c

/* 
*@project:			Application test program
*@author:  			逗比小憨憨
*@breif:  
*	Test program method: input in the terminal:
*					./lcd  /dev/fb0
*date:     			2020
*compile method:  	arm-linux-gcc -o outputFileName originFile
*/

#include<sys/ioctl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<asm/page.h>
#include<linux/fb.h>
#include<sys/mman.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include"font_libs.h"

//a framebuffer device structure;
typedef struct fbdev{
	int fb;
	unsigned long fb_mem_offset;
	unsigned long fb_mem;
	struct fb_fix_screeninfo fb_fix;
	struct fb_var_screeninfo fb_var;
	char dev[20];
} FBDEV, *PFBDEV;

//Define variables
static struct fb_var_screeninfo vinfo;
static struct fb_fix_screeninfo finfo;
static unsigned long screen_size;
static char *framebuffer_ptr;
static unsigned int bpp	=16;
unsigned int xsize	=480;    //lcd 
unsigned int ysize	=272;

//Function declaration:
static int fb_open(PFBDEV pFbdev);
static int fb_close(PFBDEV pFbdev);
static int get_display_depth(PFBDEV pFbdev);
static void fb_memset(void *addr, int c, size_t len);
static void Display_character(unsigned int x,unsigned int y,unsigned int len,unsigned char *string);
static void Draw_ASCII(unsigned int x,unsigned int y,unsigned int color,const unsigned char ch[]);
static void Draw_Text16(unsigned int x,unsigned int y,unsigned int color,const unsigned char ch[]);
static void PutPixel(unsigned int x, unsigned int y, unsigned int color);
/////////////////////////////////////////////////////////////////////////////////////////////

//Function define:
static int init_lcd(char *dev_name)
{
	int framebuffer_fd;
	/*1. Turn on the frame buffer device*/
	framebuffer_fd =open(dev_name,O_RDWR);
	if(framebuffer_fd<0)
	{
		printf("Error: failed open framebuffer device!\n");
		return -1;
	}
	/*2. Get fixed parameters*/
	if(ioctl(framebuffer_fd,FBIOGET_FSCREENINFO,&finfo))
	{
		printf("Error:failed get the framebuffer device`s fix informations!\n");
		return -1;
	}
	/*3. Get variable parameters*/
	if(ioctl(framebuffer_fd,FBIOGET_VSCREENINFO,&vinfo))
	{
		printf("Error:failed get the framebuffer device`s var informations!\n");
		return -1;
	}
	/*Print parameters*/
	printf("xres =%ld\n",vinfo.xres);
	printf("yres =%ld\n",vinfo.yres);
	screen_size =(vinfo.xres *vinfo.yres*vinfo.bits_per_pixel/8);
	printf("screensize =%ld\n",screen_size);
	/*
	Through the mmap()  function, 
	the physical memory space of the graphics card is mapped 
	to the user space address.
	For an explanation of this mmap() function, see:@1
	*/
	framebuffer_ptr =(char *)mmap(  NULL,
							     screen_size,		
							     PROT_READ|PROT_WRITE,
							     MAP_SHARED,		
							     framebuffer_fd,		
							     0);			
	if(framebuffer_ptr<0)
	{
		printf("Error:failed to mmap device mem!\n");
		return -1;
	}
	memset(framebuffer_ptr,0,screen_size);
	printf("framebuffer_ptr is mmaped ok!\n");
	return framebuffer_fd;
}

//main function
int main(int argc, char **argv)
{
	FBDEV fbdev;
	int fd;
	char key;
	unsigned int length1;
	unsigned int length2;
	unsigned char string1[]="欢迎关注逗比小憨憨";
	unsigned char string2[]="This is lcd test code!";
	char *var_default="/dev/fb0";
	char *var=argv[1];
	
	fd=init_lcd(argv[1]);
	while(-1==fd)
	{
		printf("initalize fail,please input again: \n");
		key = getchar();
		if((key == 'o') || (key == 'O'))
			fd=init_lcd(var_default);
		if(fd!=-1)
			break;
		printf("input:%c is error!!\n",key);
	}
	printf("The file is opened! Enter test menu:\n");
	while(1)
	{
		printf("Application test program menu\n");
		printf("please select:\n");
		printf("\t<1>: clear   display\n");
		printf("\t<2>: display characters\n");
		printf("\t<3>: exit\n");
		key=getchar();
		printf("your selection:%c\n",key);
		switch(key)
		{
			case '1':
				memset(framebuffer_ptr,0,screen_size);
				break;
			case '2':
				//Display characters
				length1 =sizeof(string1);
				printf("%s\n",string1);
				length2 =sizeof(string2);
				printf("%s\n",string2);
				printf("length1 =%d\n",length1);
				Display_character(140,100,length1,string1);
				Display_character(140,120,length2,string2);	
				break;
			case '3':
				goto exit_test;
			default:
				printf("\tInput error!\n");
				break;
		}	
	}
exit_test:
	munmap((void *)fd,screen_size);
	close(fd);
	return 0;
}

static void fb_memset (void *addr, int c, size_t len)
{
	memset(addr, c, len);
}

/*These function already exist in /driver/vedio/fbmem.c.
when we use open() function to open file,that is,
open the device of fb0,Auto call fb_open() 
in /driver/vedio/fbmem.c
*/
#if 0
static int fb_close(PFBDEV pFbdev)
{
	close(pFbdev->fb);
	pFbdev->fb=-1;
}

static int fb_open(PFBDEV pFbdev)
{
	pFbdev->fb = open(pFbdev->dev, O_RDWR);
	if(pFbdev->fb < 0)
	{
		printf("Error opening %s: %m. Check kernel config\n", pFbdev->dev);
		return 0;
	}
	if (-1 == ioctl(pFbdev->fb,FBIOGET_VSCREENINFO,&(pFbdev->fb_var)))
	{
		printf("ioctl FBIOGET_VSCREENINFO\n");
		return 0;
	}
	if (-1 == ioctl(pFbdev->fb,FBIOGET_FSCREENINFO,&(pFbdev->fb_fix)))
	{
		printf("ioctl FBIOGET_FSCREENINFO\n");
		return 0;
	}
	//map physics address to virtual address
	pFbdev->fb_mem_offset=(unsigned long)(pFbdev->fb_fix.smem_start) & (~PAGE_MASK);
	pFbdev->fb_mem = (unsigned long int)mmap(NULL, pFbdev->fb_fix.smem_len + pFbdev->fb_mem_offset, PROT_READ | PROT_WRITE, MAP_SHARED, pFbdev->fb, 0);
	if (-1L == (long) pFbdev->fb_mem)
	{
		printf("mmap error! mem:%d offset:%d\n", pFbdev->fb_mem, pFbdev->fb_mem_offset);
		return 0;
	}
	return 1;
}
#endif

//dispaly function
static void Display_character(unsigned int x,unsigned int y,unsigned int len,unsigned char *string)
{
	int k, xx;
	unsigned char qh,wh;
	const unsigned char *mould;
	unsigned int length =len;
	
	printf("length =%d\n",length);
	for(k=0,xx=x;k<length-1;k++)
	{
		if(string[k]&0x80)   //Chinese characters
		{
			qh =string[k]-0xa0;			//Area code
			wh =string[k+1]-0xa0;		//Tag number
			mould =&__CHS[((qh-1)*94+wh-1)*32];
			Draw_Text16(4+xx,y,0x0000ff,mould);
			xx+=16;
			k++;
		}
		else
		{
			mould =&__ASCII[string[k]*16];
			Draw_ASCII(4+xx,y,0xff0000,mould);
			xx+=8;
		}
	}
}

void Draw_Text16(unsigned int x,unsigned int y,unsigned int color,const unsigned char ch[])
{
	unsigned short int i,j;
	unsigned char mask,buffer;
	for(i=0;i<16;i++)
	{
		mask =0x80;			//Mask
		buffer =ch[i*2];	//Extract the first byte of a row
		for(j=0;j<8;j++)
		{
			if(buffer &mask)
			{
				PutPixel(x+j,y+i,color);	//Color the brush	
			}
			mask =mask >>1;
		}
		mask =0x80;
		buffer =ch[i*2+1];
		for(j=0;j<8;j++)
		{
			if(buffer &mask)
			{
				PutPixel(x+j+8,y+i,color);
			}
			mask =mask>>1;	
		}
			
	}
}

#if 0
void Draw_ASCII(unsigned int x,unsigned int y,unsigned int color,const unsigned char ch[])
{
	unsigned short int i,j;
	unsigned char mask,buffer;
	for(i=0;i<16;i++)
	{
		mask =0x80;
		buffer =ch[i];
		for(j=0;j<8;j++)
		{
			if(buffer&mask)
			{
				PutPixel(x+j,y+i,color);
			}
			mask =mask>>1;
		}
	}
}

#else
void Draw_ASCII(unsigned int x,unsigned int y,unsigned int color,const unsigned char ch[])
{
       unsigned short int i,j;
       unsigned char mask,buffer;
       for(i=0;i<16;i++)
       {
              mask=0x80;
              buffer=ch[i];
              for(j=0;j<8;j++)
              {                   

                    if(buffer&mask)
                    {
                    	PutPixel(x+j,y+i,color);
                    }
                    mask=mask>>1;                   
              }
       }
}

#endif

/*
@brief:  Draw a point
	Input parameters:
@x,y: pixel coordinates
@color: color value
*For 16bpp: the format of color is 0xaarrggbb (AA = transparency),
*Need to convert to 5:6:5 format
*For 8bpp: color is the index value in the palette,
*The color depends on the value in the palette
*/
static void PutPixel(unsigned int x, unsigned int y, unsigned int color)
{
    unsigned char red,green,blue;
    switch (bpp){
        case 16:
        {
            unsigned short *addr = (unsigned short *)framebuffer_ptr + (y * xsize + x);
            red   = (color >> 19) & 0x1f;
            green = (color >> 10) & 0x3f;
            blue  = (color >>  3) & 0x1f;
            color = (red << 11) | (green << 5) | blue; // 格式5:6:5
            *addr = (unsigned short) color;
            break;
        }
        
        case 8:
        {
            unsigned char *addr = (unsigned char *)framebuffer_ptr + (y * xsize + x);
            *addr = (unsigned char) color;
            break;
        }

        default:
            break;
    }
}

/*@1:
char *fbp = (char *)mmap(start, size, PROT_READ | PROT_WRITE, MAP_SHARED,fbfd, offsize);  
The meaning of each parameter is as follows:

@start:
	Start points to the starting address of the memory to be mapped, 
	which is usually set to null, which means that the system will 
	automatically select the address. After the mapping is successful, 
	the address is returned.
@size:
	Size represents how much of the file is mapped to memory.
@PROT_READ | PROT_WRITE:
	is readable and writable
@MAP_SHARED:
	MAP_SHARED writes to the mapped area are copied back into the file, 
	allowing other processes that map the file to share.
@fbfd:
	is mapped to the file descriptor in memory, 
	that is, the descriptor after the open file.
@offsize:
	Offset of the offsize file mapping
*/


输入2进行显示:

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言