DirectFB Porting without fb device:part 1

看了很多篇移植DFB的文章,基本上都是只是在Configure配置下就完工的,基本上都是靠DFB已经做好的systems和gfxdrivers。

 

定制systems和gfxdrivers有指引,文档地址http://directfb.org/index.php?path=Documentation%2FPresentations

DirectFB Porting without fb device:part 1_第1张图片

 

DirectFB Porting without fb device:part 1_第2张图片

这是针对Renesas driver订制的

看下架构图

可以知道大概数据流和控制流的走向,层间关系以及接口调用封装流程

DirectFB Porting without fb device:part 1_第3张图片

依赖

DFB虽然用C写的,但封装起来具有面向对象的思想,所以回调函数之类会比较多,就跟我之前发的博客差不多,就是给函数指针传值,然后注册(register)到DFB里面,让DFB去调

所以了解依赖很重要,可以将某些模块当黑盒子处理就那样处理,当他透明就是,信任里面的调用,这样可以大大降低开发的复杂性。

这里先看看devmem这个system是怎么写的

#ifndef __DEVMEM_DEVMEM_H__
#define __DEVMEM_DEVMEM_H__

#include <fusion/shmalloc.h>

#include <core/surface_pool.h>

#include "surfacemanager.h"


#define DEV_MEM     "/dev/mem"

extern const SurfacePoolFuncs devmemSurfacePoolFuncs;


typedef struct {
     FusionSHMPoolShared *shmpool;

     CoreSurfacePool     *pool;
     SurfaceManager      *manager;
} DevMemDataShared;

typedef struct {
     DevMemDataShared    *shared;

     void                *mem;
     volatile void       *reg;
} DevMemData;


#endif


devmem.h

 

#include <config.h>

#include <fcntl.h>
#include <sys/mman.h>

#include <directfb.h>

#include <direct/mem.h>

#include <fusion/shmalloc.h>

#include <core/core.h>
#include <core/surface_pool.h>

#include <misc/conf.h>

#include "devmem.h"
#include "surfacemanager.h"


#include <core/core_system.h>

#ifdef HAVE_GFX_SH772X
#include <uiomux/uiomux.h>
#endif

DFB_CORE_SYSTEM( devmem )

/**********************************************************************************************************************/

static DevMemData *m_data;    /* FIXME: Fix Core System API to pass data in all functions. */

/**********************************************************************************************************************/

static DFBResult
MapMemAndReg( DevMemData    *data,
              unsigned long  mem_phys,
              unsigned int   mem_length,
              unsigned long  reg_phys,
              unsigned int   reg_length )
{
     int fd;

     fd = open( DEV_MEM, O_RDWR | O_SYNC );
     if (fd < 0) {
          D_PERROR( "System/DevMem: Opening '%s' failed!\n", DEV_MEM );
          return DFB_INIT;
     }

     data->mem = mmap( NULL, mem_length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mem_phys );
     if (data->mem == MAP_FAILED) {
          D_PERROR( "System/DevMem: Mapping %d bytes at 0x%08lx via '%s' failed!\n", mem_length, mem_phys, DEV_MEM );
          return DFB_INIT;
     }

     if (reg_phys && reg_length) {
          data->reg = mmap( NULL, reg_length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, reg_phys );
          if (data->reg == MAP_FAILED) {
               D_PERROR( "System/DevMem: Mapping %d bytes at 0x%08lx via '%s' failed!\n", reg_length, reg_phys, DEV_MEM );
               munmap( data->mem, mem_length );
               close( fd );
               return DFB_INIT;
          }
     }

#ifdef HAVE_GFX_SH772X
	uiomux_register (data->mem, mem_phys, mem_length);
#endif

     close( fd );

     return DFB_OK;
}

static void
UnmapMemAndReg( DevMemData   *data,
                unsigned int  mem_length,
                unsigned int  reg_length )
{
     munmap( data->mem, mem_length );

     if (reg_length)
          munmap( (void*) data->reg, reg_length );
}

/**********************************************************************************************************************/

static void
system_get_info( CoreSystemInfo *info )
{
     info->type = CORE_DEVMEM;
     info->caps = CSCAPS_ACCELERATION;

     snprintf( info->name, DFB_CORE_SYSTEM_INFO_NAME_LENGTH, "DevMem" );
}

static DFBResult
system_initialize( CoreDFB *core, void **ret_data )
{
     DFBResult            ret;
     DevMemData          *data;
     DevMemDataShared    *shared;
     FusionSHMPoolShared *pool;

     D_ASSERT( m_data == NULL );

#if 0
     if (!dfb_config->video_phys || !dfb_config->video_length) {
          D_ERROR( "System/DevMem: Please supply 'video-phys = 0xXXXXXXXX' and 'video-length = XXXX' options!\n" );
          return DFB_INVARG;
     }

     if (dfb_config->mmio_phys && !dfb_config->mmio_length) {
          D_ERROR( "System/DevMem: Please supply both 'mmio-phys = 0xXXXXXXXX' and 'mmio-length = XXXX' options or none!\n" );
          return DFB_INVARG;
     }
 #else
 	dfb_config->video_phys = 0;
 	dfb_config->video_length = 1024 * 1024;
	dfb_config->mmio_phys = 0;
	dfb_config->mmio_length = 1024 * 1024;
	dfb_config->accelerator = 1;
	
 
 #endif

     data = D_CALLOC( 1, sizeof(DevMemData) );
     if (!data)
          return D_OOM();

     pool = dfb_core_shmpool( core );

     shared = SHCALLOC( pool, 1, sizeof(DevMemDataShared) );
     if (!shared) {
          D_FREE( data );
          return D_OOSHM();
     }

     shared->shmpool = pool;

     data->shared = shared;

     ret = MapMemAndReg( data,
                         dfb_config->video_phys, dfb_config->video_length,
                         dfb_config->mmio_phys,  dfb_config->mmio_length );
     if (ret) {
          SHFREE( pool, shared );
          D_FREE( data );
          return ret;
     }


     *ret_data = m_data = data;

     dfb_surface_pool_initialize( core, &devmemSurfacePoolFuncs, &shared->pool );

     core_arena_add_shared_field( core, "devmem", shared );

     return DFB_OK;
}

static DFBResult
system_join( CoreDFB *core, void **ret_data )
{
     DFBResult         ret;
     void             *tmp;
     DevMemData       *data;
     DevMemDataShared *shared;

     D_ASSERT( m_data == NULL );

     if (!dfb_config->video_phys || !dfb_config->video_length) {
          D_ERROR( "System/DevMem: Please supply 'video-phys = 0xXXXXXXXX' and 'video-length = XXXX' options!\n" );
          return DFB_INVARG;
     }

     if (dfb_config->mmio_phys && !dfb_config->mmio_length) {
          D_ERROR( "System/DevMem: Please supply both 'mmio-phys = 0xXXXXXXXX' and 'mmio-length = XXXX' options or none!\n" );
          return DFB_INVARG;
     }

     data = D_CALLOC( 1, sizeof(DevMemData) );
     if (!data)
          return D_OOM();

     ret = core_arena_get_shared_field( core, "devmem", &tmp );
     if (ret) {
          D_FREE( data );
          return ret;
     }

     data->shared = shared = tmp;

     ret = MapMemAndReg( data,
                         dfb_config->video_phys, dfb_config->video_length,
                         dfb_config->mmio_phys,  dfb_config->mmio_length );
     if (ret) {
          D_FREE( data );
          return ret;
     }

     *ret_data = m_data = data;

     dfb_surface_pool_join( core, shared->pool, &devmemSurfacePoolFuncs );

     return DFB_OK;
}

static DFBResult
system_shutdown( bool emergency )
{
     DevMemDataShared *shared;

     D_ASSERT( m_data != NULL );

     shared = m_data->shared;
     D_ASSERT( shared != NULL );

     dfb_surface_pool_destroy( shared->pool );

     UnmapMemAndReg( m_data, dfb_config->video_length, dfb_config->mmio_length );

     SHFREE( shared->shmpool, shared );

     D_FREE( m_data );
     m_data = NULL;

     return DFB_OK;
}

static DFBResult
system_leave( bool emergency )
{
     DevMemDataShared *shared;

     D_ASSERT( m_data != NULL );

     shared = m_data->shared;
     D_ASSERT( shared != NULL );

     dfb_surface_pool_leave( shared->pool );

     UnmapMemAndReg( m_data, dfb_config->video_length, dfb_config->mmio_length );

     D_FREE( m_data );
     m_data = NULL;

     return DFB_OK;
}

static DFBResult
system_suspend( void )
{
     D_ASSERT( m_data != NULL );

     return DFB_OK;
}

static DFBResult
system_resume( void )
{
     D_ASSERT( m_data != NULL );

     return DFB_OK;
}

static volatile void *
system_map_mmio( unsigned int    offset,
                 int             length )
{
     D_ASSERT( m_data != NULL );

     return m_data->reg + offset;
}

static void
system_unmap_mmio( volatile void  *addr,
                   int             length )
{
}

static int
system_get_accelerator( void )
{
     return dfb_config->accelerator;
}

static VideoMode *
system_get_modes( void )
{
	printf("[GUM] <%s, %d>\n", __FILE__, __LINE__);
     return NULL;
}

static VideoMode *
system_get_current_mode( void )
{
	printf("[GUM] <%s, %d>\n", __FILE__, __LINE__);
     return NULL;
}

static DFBResult
system_thread_init( void )
{
     return DFB_OK;
}

static bool
system_input_filter( CoreInputDevice *device,
                     DFBInputEvent   *event )
{
     return false;
}

static unsigned long
system_video_memory_physical( unsigned int offset )
{
     return dfb_config->video_phys + offset;
}

static void *
system_video_memory_virtual( unsigned int offset )
{
     D_ASSERT( m_data != NULL );

     return m_data->mem + offset;
}

static unsigned int
system_videoram_length( void )
{
     return dfb_config->video_length;
}

static unsigned long
system_aux_memory_physical( unsigned int offset )
{
     return 0;
}

static void *
system_aux_memory_virtual( unsigned int offset )
{
     return NULL;
}

static unsigned int
system_auxram_length( void )
{
     return 0;
}

static void
system_get_busid( int *ret_bus, int *ret_dev, int *ret_func )
{
     return;
}

static int
system_surface_data_size( void )
{
     /* Return zero because shared surface data is unneeded. */
     return 0;
}

static void
system_surface_data_init( CoreSurface *surface, void *data )
{
     /* Ignore since unneeded. */
     return;
}

static void
system_surface_data_destroy( CoreSurface *surface, void *data )
{
     /* Ignore since unneeded. */
     return;
}

static void
system_get_deviceid( unsigned int *ret_vendor_id,
                     unsigned int *ret_device_id )
{
     return;
}


devmem.c

 

其实定制system,system接口已经定好了,等你写实现而已

接口声明在core_system.h里面

#ifndef __DFB__CORE__CORE_SYSTEM_H__
#define __DFB__CORE__CORE_SYSTEM_H__

#include <core/system.h>

static void
system_get_info( CoreSystemInfo *info );

static DFBResult
system_initialize( CoreDFB *core, void **data );

static DFBResult
system_join( CoreDFB *core, void **data );

static DFBResult
system_shutdown( bool emergency );

static DFBResult
system_leave( bool emergency );

static DFBResult
system_suspend( void );

static DFBResult
system_resume( void );

static VideoMode*
system_get_modes( void );

static VideoMode*
system_get_current_mode( void );

static DFBResult
system_thread_init( void );

static bool
system_input_filter( CoreInputDevice *device,
                     DFBInputEvent   *event );

static volatile void*
system_map_mmio( unsigned int    offset,
                 int             length );

static void
system_unmap_mmio( volatile void  *addr,
                   int             length );

static int
system_get_accelerator( void );

static unsigned long
system_video_memory_physical( unsigned int offset );

static void*
system_video_memory_virtual( unsigned int offset );

static unsigned int
system_videoram_length( void );

static unsigned long
system_aux_memory_physical( unsigned int offset );

static void*
system_aux_memory_virtual( unsigned int offset );

static unsigned int
system_auxram_length( void );

static void
system_get_busid( int *ret_bus, int *ret_dev, int *ret_func );

static void
system_get_deviceid( unsigned int *ret_vendor_id, unsigned int *ret_device_id );

static int
system_surface_data_size( void );

static void
system_surface_data_init( CoreSurface *surface, void *data );

static void
system_surface_data_destroy( CoreSurface *surface, void *data );


static CoreSystemFuncs system_funcs = {
     .GetSystemInfo       = system_get_info,
     .Initialize          = system_initialize,
     .Join                = system_join,
     .Shutdown            = system_shutdown,
     .Leave               = system_leave,
     .Suspend             = system_suspend,
     .Resume              = system_resume,
     .GetModes            = system_get_modes,
     .GetCurrentMode      = system_get_current_mode,
     .ThreadInit          = system_thread_init,
     .InputFilter         = system_input_filter,
     .MapMMIO             = system_map_mmio,
     .UnmapMMIO           = system_unmap_mmio,
     .GetAccelerator      = system_get_accelerator,
     .VideoMemoryPhysical = system_video_memory_physical,
     .VideoMemoryVirtual  = system_video_memory_virtual,
     .VideoRamLength      = system_videoram_length,
     .AuxMemoryPhysical   = system_aux_memory_physical,
     .AuxMemoryVirtual    = system_aux_memory_virtual,
     .AuxRamLength        = system_auxram_length,
     .GetBusID            = system_get_busid,
     .SurfaceDataSize     = system_surface_data_size,
     .SurfaceDataInit     = system_surface_data_init,
     .SurfaceDataDestroy  = system_surface_data_destroy,
     .GetDeviceID         = system_get_deviceid
};

#define DFB_CORE_SYSTEM(shortname)                              \
__attribute__((constructor)) void directfb_##shortname( void ); \
                                                                \
void                                                            \
directfb_##shortname( void )                                    \
{                                                               \
     direct_modules_register( &dfb_core_systems,                \
                              DFB_CORE_SYSTEM_ABI_VERSION,      \
                              #shortname, &system_funcs );      \
}

#endif


至于每个接口有什么作用,可以看接口的名称,和变量名字去判断

所以进行开发,好的编程规范可以降低注释的量,大大提高开发效率。

你可能感兴趣的:(DirectFB Porting without fb device:part 1)