#include
// 操作FrameBuffer 设备文件所需头文件 */
#include
#include
// 使用 mmap 与munmap 函数所需头文件 */
#include
#include
// 生成 RGB565像素值 */
inlinestatic unsigned short int
make_rgb565(unsigned char r,
unsigned charg,
unsigned char b )
{
// r 1.右移 3 位是为了保留字节高 5 位有效,
2.位与 31是为了将除低 5 位以外的位值变为零,
3.左移 11位是为了将 r 的移到两字节返回值的高 15 ~ 11 位上去 */
// g 1.右移 2 位是为了保留字节高 6 位有效,
2.位与 63是为了将除低 6 位以外的位值变为零,
3.左移 5 位是为了将 r 的移到两字节返回值的中 10 ~ 5位上去 */
// b 1.右移3 位是为了保留字节高 5 位有效,
2.位与 31是为了将除低 5 位以外的位值变为零 */
// 最后将 r、g 、b 三个值组成两字节返回值返回 */
return ( (( ( r >> 3 ) & 31 ) << 11)|
( ( ( g >> 2 ) & 63) << 5 ) |
( ( b>> 3 ) & 31 ) );
}
//<--将< 替换为 * --
//这个结构描述了显示卡的特性
structfb_var_screeninfo
{
__u32xres; // visibleresolution
__u32yres;
__u32xres_virtual; // virtualresolution
__u32yres_virtual;
__u32xoffset; // offsetfrom virtual to visible resolution
__u32yoffset;
__u32bits_per_pixel; // guess what
__u32grayscale; // != 0 Gray levels insteadof colors
structfb_bitfield red; // bitfieldin fb mem if true color,
structfb_bitfield green; // else only length issignificant
structfb_bitfield blue;
structfb_bitfield transp; // transparency
__u32nonstd; // != 0 Non standard pixel format
__u32activate; // seeFB_ACTIVATE_*
__u32height; // height of picture in mm
__u32width; // width of picture in mm
__u32accel_flags; // acceleration flags(hints)
// Timing:All values in pixclocks, except pixclock (of course)
__u32pixclock; // pixel clock inps (pico seconds)
__u32left_margin; // time from sync topicture
__u32right_margin; // time from picture to sync
__u32upper_margin; // time from sync to picture
__u32lower_margin;
__u32hsync_len; // length ofhorizontal sync
__u32vsync_len; // length ofvertical sync
__u32sync; // see FB_SYNC_*
__u32vmode; // see FB_VMODE_*
__u32reserved[6]; // Reserved for futurecompatibility
};
//这个结构在显卡被设定模式后创建,它描述显示卡的属性,并且系统运行时不能被修改;
// 比如FrameBuffer 内存的起始地址。
//它依赖于被设定的模式,当一个模式被设定后,内存信息由显示卡硬件给出,内存的位置等信息就不可以修改。
structfb_fix_screeninfo
{
charid[16]; // identification string eg "TTBuiltin"
unsignedlong smem_start; // Start of frame buffer mem
//physical address
__u32smem_len; // Length of frame buffermem
__u32type; // see FB_TYPE_*
__u32type_aux; // Interleave for interleavedPlanes
__u32visual; // seeFB_VISUAL_*
__u16xpanstep; // zero if no hardwarepanning
__u16ypanstep; // zero if no hardwarepanning
__u16ywrapstep; // zero if no hardwareywrap
__u32line_length; // length of a line inbytes
unsignedlong mmio_start; // Start of Memory Mapped I/O
//physical address
__u32mmio_len; // Length of MemoryMapped I/O
__u32accel; //Type of acceleration available
__u16reserved[3]; // Reserved for future compatibility
};
//描述设备无关的颜色映射信息。
// 可以通过FBIOGETCMAP 和 FBIOPUTCMAP 对应的 ioctl 操作设定或获取颜色映射信息。
structfb_cmap
{
__u32start; // First entry
__u32 len; // Number ofentries
__u16*red; // Redvalues
__u16*green;
__u16*blue;
__u16*transp; // transparency, can be NULL
};
//定义当显卡的当前状态;
// fb_info结构仅在内核中可见,在这个结构中有一个 fb_ops 指针,指向驱动设备工作所需的函数集。
structfb_info
{
charmodename[40]; // default video mode
kdev_tnode;
intflags;
int open; // Has this been open already ?
#defineFBINFO_FLAG_MODULE 1 // Low-level driver is amodule
structfb_var_screeninfo var; // Current var
structfb_fix_screeninfo fix; // Current fix
structfb_monspecs monspecs; // Current Monitorspecs
structfb_cmap cmap; // Currentcmap
structfb_ops *fbops;
char*screen_base; // Virtual address
structdisplay *disp; // initial displayvariable
structvc_data *display_fg; // Console visible on thisdisplay
charfontname[40]; // default font name
devfs_handle_t devfs_handle; // Devfs handle fornew name
devfs_handle_t devfs_lhandle; // Devfs handle for compat.symlink
int(*changevar)(int); // tell console var haschanged
int(*switch_con)(int, struct fb_info*);
// tell fbto switch consoles
int(*updatevar)(int, struct fb_info*);
// tell fbto update the vars
void(*blank)(int, struct fb_info*); // tell fb to (un)blank thescreen
// arg =0: unblank
// arg> 0: VESA level (arg-1)
// Fakepalette of 16 colors and the cursor's color for non palettemode
void*pseudo_palette;
// Fromhere on everything is device dependent
void*par;
};
// 用户应用可以使用ioctl() 系统调用来操作设备,这个结构就是用一支持 ioctl() 的这些操作的。
structfb_ops
{
//open/release and usage marking
structmodule *owner;
int(*fb_open)( struct fb_info *info,
int user);
int(*fb_release)( struct fb_info *info,
int user );
// get nonsettable parameters
int(*fb_get_fix)( struct fb_fix_screeninfo*fix,
int con,
struct fb_info *info );
// getsettable parameters
int(*fb_get_var)( struct fb_var_screeninfo*var,
int con,
struct fb_info *info);
// setsettable parameters
int(*fb_set_var)( struct fb_var_screeninfo*var,
int con,
struct fb_info *info );
// getcolormap
int(*fb_get_cmap)( struct fb_cmap*cmap,
int kspc,
int con,
struct fb_info *info );
// setcolormap
int(*fb_set_cmap)( struct fb_cmap*cmap,
int kspc,
int con,
struct fb_info *info );
// pandisplay (optional)
int(*fb_pan_display)( struct fb_var_screeninfo*var,
int con,
structfb_info *info );
// performfb specific ioctl (optional)
int(*fb_ioctl)( struct inode *inode,
struct file *file,
unsignedint cmd,
unsignedlong arg,
int con,
structfb_info *info );
// performfb specific mmap
int(*fb_mmap)( struct fb_info *info,
struct file *file,
struct vm_area_struct *vma);
// switchto/from raster image mode
int(*fb_rasterimg)( struct fb_info*info,
int start );
};
*/
int
main()
{
// 本函数返回值*/
intiResult = 0;
//FrameBuffer设备文件描述符 */
intfdFrameBuffer = -1;
//屏幕的可变信息结构变量 */
structfb_var_screeninfo sScreenInfoVar;
//屏幕的固定信息结构变量 */
structfb_fix_screeninfo sScreenInfoFix;
// 显存字节大小*/
unsignedlong ulVideoMemByteSize = 0;
// 内存映射地址*/
unsignedchar* pucMapMem = 0;
// for循环行计数器 */
unsignedchar ucForRow = 0;
// for循环列计数器 */
unsignedchar ucForCol = 0;
//屏幕行首地址指针 */
unsignedchar* pucRow = 0;
// W 字模*/
unsignedshort int uiWFont[6][6] = { 63488, 0, 0, 0, 0, 63488,
63488, 0,63488, 63488, 0, 63488,
63488, 0,63488, 63488, 0, 63488,
63488, 0,63488, 63488, 0, 63488,
63488, 63488, 0, 0, 63488, 63488,
0, 63488, 0, 0, 63488, 0 };
// Z 字模*/
unsignedshort int uiZFont[6][6] = { 2016, 2016, 2016, 2016, 2016,2016,
2016, 2016, 2016, 2016, 2016, 2016,
0, 0, 0, 2016,2016, 0,
0, 0, 2016, 2016, 0, 0,
0, 2016, 2016, 2016, 2016,2016,
2016, 2016, 2016, 2016, 2016, 2016};
// H 字模*/
unsignedshort int uiHFont[6][6] = { 31, 31, 0, 0, 31, 31,
31, 31, 0, 0, 31, 31,
31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31,
31, 31, 0, 0, 31, 31,
31, 31, 0, 0, 31, 31 };
// N 字模*/
unsignedshort int uiNFont[6][6] = { 63488, 0, 0, 0, 63488,63488,
63488, 63488, 0, 0, 63488, 63488,
63488, 63488, 63488, 0, 63488, 63488,
63488, 63488, 63488, 63488, 63488,63488,
63488, 63488, 0, 63488, 63488, 63488,
63488, 63488, 0, 0, 63488, 63488 };
// S 字模*/
unsignedshort int uiSFont[6][6] = { 0, 0, 2016, 2016, 2016,2016,
0, 2016, 0, 0, 0, 2016,
2016, 0, 0, 0, 0, 0,
0, 2016, 2016, 2016, 0, 0,
2016, 0, 0, 0, 2016, 0,
2016, 2016, 2016, 2016, 2016, 2016};
// C 字模*/
unsignedshort int uiCFont[6][6] = { 0, 0, 31, 0, 31,31,
0, 31, 31, 0, 31,31,
31, 31, 0, 0, 0, 0,
31, 31, 0, 0, 0, 0,
0, 31, 31, 31, 31, 31,
0, 0, 31, 31, 31, 31};
do //非循环,只是为了减少分支缩进 */
{
// 1.可读写方式打开 framebuffer 设备文件*/
fdFrameBuffer = open("/dev/graphics/fb0", O_RDWR );
if ( -1 == fdFrameBuffer)
{
printf( "Error: Don't Open FrameBufferDevice.\n" );
iResult = -1;
break;
}
// ioctl参数一:设备文件描述符;
参数二:命令编码,如:
FBIOGET_FSCREENINFO -得到屏幕的固定信息(如:显示内存大小)
FBIOGET_VSCREENINFO -得到屏幕的可变信息(如:分辨率、象素结构、每扫描线的字节宽度)
FBIOPUT_VSCREENINFO - 设置屏幕的可变信息
FBIOGETCMAP -获取颜色映射信息
FBIOPUTCMAP -设置颜色映射信息
参数三:与命令编码对应的结构变量指针:
FBIOGET_FSCREENINFO 对应fb_fix_screeninfo 结构体;
FBIOGET_VSCREENINFO 和 FBIOPUT_VSCREENINFO 对应fb_var_screeninfo 结构体;
FBIOGETCMAP 和FBIOPUTCMAP 对应 fb_cmap 结构体;
*/
// 2.得到屏幕的固定信息*/
if ( -1 == ioctl(fdFrameBuffer,
FBIOGET_FSCREENINFO,
&sScreenInfoFix ))
{
printf( "Error: Don't Read Out Fix ScreenInformation.\n" );
iResult = -2;
break;
}
// 3.得到屏幕的可变信息*/
if ( -1 == ioctl(fdFrameBuffer,
FBIOGET_VSCREENINFO,
&sScreenInfoVar ))
{
printf( "Error: Don't Read Out Var ScreenInformation.\n" );
iResult = -3;
break;
}
// 显存所需字节大小 = ( 屏幕宽 * 屏幕高 *每像素位数 ) / 8 */
printf( "xres = %d\nyres =%d\nbits_per_pixel = %d\n",
sScreenInfoVar.xres,
sScreenInfoVar.yres,
sScreenInfoVar.bits_per_pixel );
printf("xoffset:%d\nyoffset:%d\nline_length:%d\n",
sScreenInfoVar.xoffset,
sScreenInfoVar.yoffset,
sScreenInfoFix.line_length );
// Android屏幕坐标系如下:
--------- xres
|
|
|
yres
*/
ulVideoMemByteSize = ( sScreenInfoVar.xres *sScreenInfoVar.yres * sScreenInfoVar.bits_per_pixel ) /8;
// 将 FrameBuffer设备文件内容映射到内存中,对该内存区域的存取即是直接对该文件内容的读写 */
pucMapMem = (unsignedchar*)mmap( 0, // 指向欲对应的内存起始地址,
通常设为 0,代表让系统自动选定地址 */
// 将文件中多少字节对应到内存 */
ulVideoMemByteSize,
// 映射区域可被 读取 和 写入 */
PROT_READ |PROT_WRITE,
// 映射区域的写入数据会复制回文件内,
而且允许其他映射该文件的进程共享 */
MAP_SHARED,
// FrameBuffer 文件描述符 */
fdFrameBuffer,
// 为文件映射的偏移量,
通常设置为0,代表从文件最前方开始对应,
必须是分页大小的整数倍*/
0 );
if ( -1 == (int)pucMapMem)
{
printf( "Error: Map FrameBuffer Device File toMemory Failed.\n" );
iResult = -4;
break;
}
// 清屏 - 黑屏 */
memset(pucMapMem, 0,ulVideoMemByteSize);
for ( ucForRow =0;
ucForRow < 6;
ucForRow++ )
{
// 屏幕第n行首像素对应显存地址 = 行号(基于零) * 一行像素个数 * 每个像素字节个数*/
pucRow = pucMapMem+
( ucForRow*
sScreenInfoVar.xres*
( sScreenInfoVar.bits_per_pixel / 8 ));
// W */
memcpy( pucRow, uiWFont + ucForRow, 12);
// Z */
memcpy( pucRow + 15, uiZFont + ucForRow, 12);
// H */
memcpy( pucRow + 30, uiHFont + ucForRow, 12);
// N */
memcpy( pucRow + 45, uiNFont + ucForRow, 12);
// S */
memcpy( pucRow + 60, uiSFont + ucForRow, 12);
// C */
memcpy( pucRow + 75, uiCFont + ucForRow, 12 );
}
}while( 0);
if ( 0 !=pucMapMem )
{
// 解除内存映射 */
munmap( pucMapMem, // 映射内存起始地址*/
ulVideoMemByteSize ); // 欲取消的内存大小 */
pucMapMem = 0;
}
if ( -1 !=fdFrameBuffer )
{
// 关闭文件 */
close( fdFrameBuffer);
fdFrameBuffer =-1;
}
returniResult;
}
0 0