看了很多篇移植DFB的文章,基本上都是只是在Configure配置下就完工的,基本上都是靠DFB已经做好的systems和gfxdrivers。
定制systems和gfxdrivers有指引,文档地址http://directfb.org/index.php?path=Documentation%2FPresentations
这是针对Renesas driver订制的
看下架构图
可以知道大概数据流和控制流的走向,层间关系以及接口调用封装流程
依赖
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
至于每个接口有什么作用,可以看接口的名称,和变量名字去判断
所以进行开发,好的编程规范可以降低注释的量,大大提高开发效率。