minigui demo helloworld在arm目標板子上的執行
把mg-samples-3.0.12編譯完後,在src目錄下有個helloworld,把它copy到板子執行測試我們的環境是否正確。
因為我的板子沒有usr目錄,所以我自己建立一個,使用nfs把build裡面的檔案掛載到板子上執行。
板子上:
掛載/目錄,使/可以讀寫
mount -o remount,rw /
然後:
mount -t nfs -o nolock 172.21.30.200:/home/xxx/build /usr/local\n
把build掛載為usr/local下面。
安裝自己目標板子的實際情況,修改minigui.cfg檔案:
[system]
# GAL engine and default options
gal_engine=fbcon
defaultmode=240x360-8bpp
# IAL engine
ial_engine=console
mdev=/dev/input/mice
mtype=IMPS2
[fbcon]
defaultmode=240x360-8bpp
我平臺上使用framebuffer,所以是影象引擎是:fbcon
defaultmode指明我們的顯示大小和顏色深度,具體參考minigui使用手冊
執行./usr/local/bin/helloworld
./helloworld: error while loading shared libraries: libminigui_ths-3.0 .so.12: cannot open shared object file: No such file or directory
是因為ld path沒有設定導致的。
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
NEWGAL: Does not find matched engine:fbcon.
KERNEL>InitGUI: can not get graphics engine information!
該錯誤資訊是因為我平臺的fb裝置路徑不一致導致的。
minigui預設是從下面查詢fb裝置
libminigui-gpl-3.0.12/src/newgal/fbcon/fbvideo.c
static int FB_VideoInit(_THIS, GAL_PixelFormat *vformat)函式:
/* Initialize the library */
GAL_fbdev = getenv("FRAMEBUFFER");
if ( GAL_fbdev == NULL ) {
GAL_fbdev = "/dev/fb0";
}
console_fd = open(GAL_fbdev, O_RDWR, 0);
if ( console_fd < 0 ) {
GAL_SetError("NEWGAL>FBCON: Unable to open %s\n", GAL_fbdev);
return(-1);
}
我平臺修改為:
/* Initialize the library */
GAL_fbdev = getenv("FRAMEBUFFER");
if ( GAL_fbdev == NULL ) {
GAL_fbdev = "/dev/graphics/fb0";
}
console_fd = open(GAL_fbdev, O_RDWR, 0);
if ( console_fd < 0 ) {
printf("NEWGAL>FBCON: Unable to open %s,line=%d\n", GAL_fbdev,__LINE__);
return(-1);
}
再次執行:
NEWGAL>FBCON:unable to memry map the video hardware
NEWGAL: Does not find matched engine:fbcon.
KERNEL>InitGUI: can not get graphics engine information!
出現這個錯誤是因為我平臺的FB裝置是定製過的,不支援allocate memery導致的,需要預先設定FB大小才可以使用。
最後我把整個FB_VideoInit函式修改如下:
主要修改在#if 1裡面的code。
static int FB_VideoInit(_THIS, GAL_PixelFormat *vformat)
{
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;
int i;
const char *GAL_fbdev;
#if 1
/* Initialize the library */
GAL_fbdev = getenv("FRAMEBUFFER");
if ( GAL_fbdev == NULL ) {
GAL_fbdev = "/dev/graphics/fb0";
}
console_fd = open(GAL_fbdev, O_RDWR, 0);
if ( console_fd < 0 ) {
printf("NEWGAL>FBCON: Unable to open %s,line=%d\n", GAL_fbdev,__LINE__);
return(-1);
}
if(ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo))
{
printf("Error:reading fixed information.lind=%d\n",__LINE__);
return(-1);
}
if(ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo))
{
printf("NEWGAL>FBCON: Couldn't get console pixel format,line=%d\n",__LINE__);
FB_VideoQuit(this);
return(-1);
}
vinfo.xres = DEFAULT_W;
vinfo.yres = DEFAULT_h;
// Set variable screen information
if(ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) == -1)
{
printf(" Error: put variable screen information.x=%d, y=%d,line=%d\n", vinfo.xres, vinfo.yres,__LINE__);
return(-1);
}
if(ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) == -1)
{
printf("Error: reading variable information.line=%d\n",__LINE__);
return(-1);
}
if(ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) == -1)
{
printf(" Error:reading fixed information.line=%d\n",__LINE__);
return(-1);
}
unsigned char enableGOP = 0;
#define G3D_IOC_MAGIC_INFINITY 'F' ///< The Type definition of IOCTL for fb driver
#define IOCTL_FB_GETENABLEGOP _IO(G3D_IOC_MAGIC_INFINITY,26)
if(ioctl(console_fd, IOCTL_FB_GETENABLEGOP, &enableGOP) == -1)
{
printf( " Error:get ENABLE GOP information.line=%d\n",__LINE__ );
return(-1);
}
#define IOCTL_FB_SETENABLEGOP _IO(G3D_IOC_MAGIC_INFINITY,27)
if(enableGOP == 0)
{
enableGOP = 1;
if(ioctl(console_fd, IOCTL_FB_SETENABLEGOP, &enableGOP) == -1)
{
printf( " Error:set ENABLE GOP information.line=%d\n",__LINE__ );
return(-1);
}
printf("Set GOP En/Dis: %d ,(enable=1,disable=0),line=%d\n", enableGOP,__LINE__);
}
//計算螢幕的總大小(位元組)
long int screenSize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
//物件對映
mapped_mem = (char *)mmap(0, screenSize, PROT_READ | PROT_WRITE, MAP_SHARED, console_fd, 0);
if (mapped_mem == (char *)-1)
{
printf("NEWGAL>FBCON: Unable to memory map the video hardware\n");
mapped_mem = NULL;
FB_VideoQuit(this);
return(-1);
}
memset(mapped_mem, 0, screenSize);
/* Memory map the device, compensating for buggy PPC mmap() */
mapped_offset = (((long)finfo.smem_start) -
(((long)finfo.smem_start)&~(getpagesize () - 1)));
mapped_memlen = finfo.smem_len+mapped_offset;
vformat->BitsPerPixel = vinfo.bits_per_pixel;
if ( vformat->BitsPerPixel < 8 ) {
vformat->MSBLeft = !(vinfo.red.msb_right);
return 0;
}
for ( i=0; i<vinfo.red.length; ++i ) {
vformat->Rmask <<= 1;
vformat->Rmask |= (0x00000001<<vinfo.red.offset);
}
for ( i=0; i<vinfo.green.length; ++i ) {
vformat->Gmask <<= 1;
vformat->Gmask |= (0x00000001<<vinfo.green.offset);
}
for ( i=0; i<vinfo.blue.length; ++i ) {
vformat->Bmask <<= 1;
vformat->Bmask |= (0x00000001<<vinfo.blue.offset);
}
for ( i=0; i<vinfo.transp.length; ++i ) {
vformat->Amask <<= 1;
vformat->Amask |= (0x00000001<<vinfo.transp.offset);
}
saved_vinfo = vinfo;
/* Save hardware palette, if needed */
FB_SavePalette(this, &finfo, &vinfo);
/* If the I/O registers are available, memory map them so we
can take advantage of any supported hardware acceleration.
*/
if ( finfo.accel && finfo.mmio_len ) {
mapped_iolen = finfo.mmio_len;
mapped_io = mmap(NULL, mapped_iolen, PROT_READ|PROT_WRITE,
MAP_SHARED, console_fd, mapped_memlen);
if ( mapped_io == (char *)-1 ) {
/* Hmm, failed to memory map I/O registers */
mapped_io = NULL;
}
}
#else
/* Initialize the library */
GAL_fbdev = getenv("FRAMEBUFFER");
if ( GAL_fbdev == NULL ) {
GAL_fbdev = "/dev/fb0";
}
console_fd = open(GAL_fbdev, O_RDWR, 0);
if ( console_fd < 0 ) {
GAL_SetError("NEWGAL>FBCON: Unable to open %s\n", GAL_fbdev);
return(-1);
}
/* Get the type of video hardware */
if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) {
GAL_SetError("NEWGAL>FBCON: Couldn't get console hardware info\n");
FB_VideoQuit(this);
return(-1);
}
switch (finfo.type) {
case FB_TYPE_PACKED_PIXELS:
/* Supported, no worries.. */
break;
default:
GAL_SetError("NEWGAL>FBCON: Unsupported console hardware\n");
FB_VideoQuit(this);
return(-1);
}
switch (finfo.visual) {
#ifdef _MGGAL_SHADOW
case FB_VISUAL_MONO01:
case FB_VISUAL_MONO10:
break;
#endif
case FB_VISUAL_TRUECOLOR:
case FB_VISUAL_PSEUDOCOLOR:
case FB_VISUAL_STATIC_PSEUDOCOLOR:
case FB_VISUAL_DIRECTCOLOR:
break;
default:
GAL_SetError("NEWGAL>FBCON: Unsupported console hardware\n");
FB_VideoQuit(this);
return(-1);
}
/* Memory map the device, compensating for buggy PPC mmap() */
mapped_offset = (((long)finfo.smem_start) -
(((long)finfo.smem_start)&~(getpagesize () - 1)));
mapped_memlen = finfo.smem_len+mapped_offset;
printf("infor:type=%x,visual=%x,start=%x,len=%x\n",finfo.type,finfo.visual,finfo.smem_start,finfo.smem_len);
#ifdef __uClinux__
# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
mapped_mem = mmap(NULL, mapped_memlen,
PROT_READ|PROT_WRITE, MAP_PRIVATE, console_fd, 0);
# else
mapped_mem = mmap(NULL, mapped_memlen,
PROT_READ|PROT_WRITE, 0, console_fd, 0);
# endif
#else
mapped_mem = mmap(NULL, mapped_memlen,
PROT_READ|PROT_WRITE, MAP_SHARED, console_fd, 0);
#endif
if (mapped_mem == (char *)-1) {
GAL_SetError("NEWGAL>FBCON: Unable to memory map the video hardware\n");
mapped_mem = NULL;
FB_VideoQuit(this);
return(-1);
}
/* Determine the current screen depth */
if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) {
GAL_SetError("NEWGAL>FBCON: Couldn't get console pixel format\n");
FB_VideoQuit(this);
return(-1);
}
vformat->BitsPerPixel = vinfo.bits_per_pixel;
if ( vformat->BitsPerPixel < 8 ) {
vformat->MSBLeft = !(vinfo.red.msb_right);
return 0;
}
for ( i=0; i<vinfo.red.length; ++i ) {
vformat->Rmask <<= 1;
vformat->Rmask |= (0x00000001<<vinfo.red.offset);
}
for ( i=0; i<vinfo.green.length; ++i ) {
vformat->Gmask <<= 1;
vformat->Gmask |= (0x00000001<<vinfo.green.offset);
}
for ( i=0; i<vinfo.blue.length; ++i ) {
vformat->Bmask <<= 1;
vformat->Bmask |= (0x00000001<<vinfo.blue.offset);
}
for ( i=0; i<vinfo.transp.length; ++i ) {
vformat->Amask <<= 1;
vformat->Amask |= (0x00000001<<vinfo.transp.offset);
}
saved_vinfo = vinfo;
/* Save hardware palette, if needed */
FB_SavePalette(this, &finfo, &vinfo);
/* If the I/O registers are available, memory map them so we
can take advantage of any supported hardware acceleration.
*/
if ( finfo.accel && finfo.mmio_len ) {
mapped_iolen = finfo.mmio_len;
mapped_io = mmap(NULL, mapped_iolen, PROT_READ|PROT_WRITE,
MAP_SHARED, console_fd, mapped_memlen);
if ( mapped_io == (char *)-1 ) {
/* Hmm, failed to memory map I/O registers */
mapped_io = NULL;
}
}
#endif
/* Fill in our hardware acceleration capabilities */
this->info.hw_available = 1;
this->info.video_mem = finfo.smem_len/1024;
if ( mapped_io ) {
switch (finfo.accel) {
case FB_ACCEL_MATROX_MGA2064W:
case FB_ACCEL_MATROX_MGA1064SG:
case FB_ACCEL_MATROX_MGA2164W:
case FB_ACCEL_MATROX_MGA2164W_AGP:
case FB_ACCEL_MATROX_MGAG100:
/*case FB_ACCEL_MATROX_MGAG200: G200 acceleration broken! */
case FB_ACCEL_MATROX_MGAG400:
#ifdef FBACCEL_DEBUG
fprintf(stderr, "NEWGAL>FBCON: Matrox hardware accelerator!\n");
#endif
FB_MatroxAccel(this, finfo.accel);
break;
case FB_ACCEL_3DFX_BANSHEE:
#ifdef FBACCEL_DEBUG
fprintf(stderr, "NEWGAL>FBCON: 3DFX hardware accelerator!\n");
#endif
FB_3DfxAccel (this, finfo.accel);
break;
#ifdef FB_ACCEL_NEOMAGIC_NM2070
case FB_ACCEL_NEOMAGIC_NM2200:
case FB_ACCEL_NEOMAGIC_NM2230:
case FB_ACCEL_NEOMAGIC_NM2360:
case FB_ACCEL_NEOMAGIC_NM2380:
#ifdef FBACCEL_DEBUG
fprintf(stderr, "NEWGAL>FBCON: NeoMagic hardware accelerator!\n");
#endif
FB_NeoMagicAccel (this, finfo.accel);
break;
#endif
default:
#ifdef FBACCEL_DEBUG
fprintf(stderr, "NEWGAL>FBCON: Unknown hardware accelerator!\n");
#endif
break;
}
}
#ifdef _MGHAVE_PCIACCESS
else {
/* Check accelerated hardware via pciaccess */
pci_accel_driver = FB_ProbePCIAccelDriver (this, &finfo);
}
#endif
/* We're done! */
return(0);
}
關於GOP的設定請忽略,這個是我平臺獨有的。
#define DEFAULT_W 1920
#define DEFAULT_h 1080
對於我平臺裡面的FB size,實際上是2個FULLHD的大小,就是2個1920X1080,程式碼中我只使用了1個,具體平臺需要修改這個。
繼續執行,還是有錯誤:
NEWGAL>FBCON:Error when setting the terminal to graphics mode: Inappropriate ioctl for device
NEWGAL:>FBCON: Maybe is not a console
NEWGAL: Set video mode failure
KERNEL>InitGUI: can not initialize graphics engine !
出現這個錯誤是我平臺的FB裝置不支援text mode,預設就是graphic mode,所以不需要切換。
如下函式需要把_MGCONSOLE_TEXTMODE登出,該巨集在:
Mgconfig.h檔案裡面,如下:
/* Define if your Linux have text mode */
//#define _MGCONSOLE_TEXTMODE 0
static int FB_EnterGraphicsMode (_THIS)
{
#ifdef _MGCONSOLE_TEXTMODE
#ifdef _MGRM_PROCESSES
if (mgIsServer) {
#endif
char* tty_dev;
if (geteuid() == 0)
tty_dev = "/dev/ttyS0";
else /* not a super user, so try to open the control terminal */
tty_dev = "/dev/tty";
printf("tty_dev=%s\n",tty_dev);
/* open tty, enter graphics mode */
ttyfd = open (tty_dev, O_RDWR);
if (ttyfd < 0) {
fprintf (stderr,"NEWGAL>FBCON: Can't open %s: %m\n", tty_dev);
goto fail;
}
if (ioctl (ttyfd, KDSETMODE, KD_GRAPHICS) == -1) {
fprintf (stderr,"NEWGAL>FBCON: Error when setting the terminal to graphics mode: %m\n");
fprintf (stderr,"NEWGAL>FBCON: Maybe is not a console.\n");
goto fail;
}
#ifdef _MGRM_PROCESSES
}
else {
ttyfd = 0;
}
#endif
return ttyfd;
fail:
FB_LeaveGraphicsMode (this);
return -1;
#else
return 0;
#endif
}
最後繼續執行:
[/]## cd usr/local/
[/usr/local]## ./helloworld
[FB Driver] updateinfo_par: GOP_WIDTH = [1920], GOP_HEIGHT = [1080], sg_videomemorysize = 0x3f4800
[FB Driver] vir=0xc3600000, phy=0x23600000
[FB Driver] Get GOP Enable/Disable.
[FB Driver] _MDrv_FBIO_IOC_Get_EnGOP, sg_videomemorysize=0x3f4800
[FB Driver] mdrvinfinityfb_mmap, sg_videomemorysize=0x3f4800
[FB Driver] mmap vma->vm_start=b6999000
vma->vm_end=b6b94000
vma->vm_pgoff =23600
[FB Driver] updateinfo_par: GOP_WIDTH = [240], GOP_HEIGHT = [360], sg_videomemorysize = 0x2a300
[FB Driver] vir=0xc2ec0000, phy=0x22ec0000
IAL: use 'tty' native keyboard engine, with the device file ''
[WARNING] IAL Native Engine: Can not init keyboard right now, No such file or directory().
Please plug in the KEYBOARD!
[WARNING] IAL Native Engine: Can not init mouse right now, No such file or directory(/dev/input/mice).
Please plug in the MOUSE!
後面的waring是輸入裝置沒有修改接上的原因,但是不影響顯示。
will done!Good。