嵌入式开发框架之模块化代码实现(仿linux设备驱动)

    在上一篇https://blog.csdn.net/MINGTING1323/article/details/100173420介绍了模块化编程思想,但实际应用中具体应该怎么实现呢?古人云“知行合一”,道理谁都懂,但真正到了应用的时候可能又为难了。在这,我想到了很好地思路,就是我很好的借鉴linux驱动代码去实现。

     linux驱动代码很好的实现了模块化思想。需要加载驱动可以insmod加载或取消。每个模块的代码通过module_init()注册和module_exit()函数进行卸载。同时像外部提供了open,close,write,read,等相同的外部接口。用户新增驱动时,只需要填充struct file_operations结构体即可。这样部分模块没有加载也不影响其他模块的正常使用。因此,我们也借鉴这个思路实现模块化代码。

     另外一个思路就是各个模块编译成.so,我们只需要将接口提供给使用者即可。

     结合两种思路。我们的代码没实现ismod注册功能,但实现类似module_init()相关功能。但可以根据实际需求,进行修改。也可以修改为读取配置.so进行加载。

    首先,我们要明确每个模块应该做什么事。我很抽象的出了三件事:一.做自己的事(相当于下面的CALLBACK_FUNC)。二.做别人的交代的事。三.给别人予以回馈 APP_COMMAND。除了这三件事应该没有其他。

typedef void *  APP_HANDLE ;
typedef int ( * CALLBACK_FUNC ) ( APP_HANDLE * head, void* pdata, void* pparam ) ;
typedef int ( * APP_MESSAGE ) ( int sender, void * msg ) ;
typedef int ( * APP_COMMAND ) ( int op, int ilen, void * ibuf, int olen, void * obuf ) ;
typedef void *(*THREAD_FUNC)(void*)  ;

    其次,我们设计出模块的结构如下。每个模块对外接口都是一样的send_message,与do_command,好比驱动里面的write、read。


typedef void * SYSTEM_CONFIG ;

//模块信息结构
typedef struct
{
    char * description  ;			//模块名称
    int    id    ;					//模块ID

    APP_MESSAGE  send_message ;		//模块消息接收处理函数
    APP_COMMAND  do_command   ;		//模块处理函数
} APP_MODULE ;

   再次,我们应该定义模块结构。模块之间的通讯接口如下:

//系统消息结构
typedef struct
{
    int  sender   ;      //发送模块
    int  receiver ;      //接受模块
    int  command  ;      //命令字
    int  length   ;      //内容长度
    char data[BASE_PACK_LEN] ;     //内容,
} KERNEL_MESSAGE;

统一管理所有模块的结构体如下:

typedef struct _tagAPP_MODULE_LIST
{
    char              name[64];
    APP_HANDLE        handle   ;    //记录so的句柄
    APP_INIT          app_init ;
    APP_EXIT          app_exit ;
    APP_MODULE      * module ;    //模块输出函数等
    struct _tagAPP_MODULE_LIST * next   ;
} APP_MODULE_LIST ;

typedef struct
{
    char      * name ;	//模块名称
    APP_INIT    init ;	//模块注册
    APP_EXIT    exit ;	//模块退出
} INTERNAL_MODULE ;

对外接口提供的两种方式的模块调用时如下:

/
//     Function : CORE_send_message
//  Description : send message to one module
//        Input :
//       Output :
//发送消息,无返回数据
int  CORE_send_message( KERNEL_MESSAGE * msg )
{
    APP_MODULE_LIST * app, * call = NULL ;
    int ret  = 0 ;

    if( core_context == NULL )
        return 0 ;

    pthread_mutex_lock( &core_context->module_mutex ) ;
    app = core_context->module ;

    while( app != NULL )
    {
        if( app->module->id == msg->receiver && app->module->send_message != NULL )
        {
            call = app ;
            break ;
        }
        app = app->next ;
    }
    pthread_mutex_unlock( &core_context->module_mutex ) ;

    if( call )
    {
        ret = call->module->send_message( msg->sender, msg ) ;
        //LOG_PRINTF("msg->sender is %d \n",(msg->sender));
	}

    return ret ;
}
/
//     Function : CORE_do_command
//  Description : ask other module to execute one command
//        Input :
//       Output :
//执行一个命令,可以有返回值
int  CORE_do_command  ( int module, int op, int ilen, void * ibuf, int olen, void * obuf )
{
    APP_MODULE_LIST * app, * call = NULL ;
    int ret = 0;

    if( core_context == NULL )
        return 0 ;

    pthread_mutex_lock( &core_context->module_mutex ) ;
    app = core_context->module ;
    while( app != NULL )
    {
        if( app->module->id == module && app->module->do_command != NULL )
        {
            call = app ;
            break ;
        }
        app = app->next ;
    }
    pthread_mutex_unlock( &core_context->module_mutex ) ;
    if( call )
        ret = call->module->do_command( op, ilen, ibuf, olen, obuf ) ;
    return ret ;
}

后续还将提供一份代码,以app_sysctrl模块提供一份示例,希望大家能够喜欢。

代码路径:https://download.csdn.net/download/mingting1323/11647276

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值