• module_param


     该宏定义在include/linux/moduleparam.h中

    #define ___module_cat(a,b) __mod_ ## a ## b
    #define __module_cat(a,b) ___module_cat(a,b)
    #define __MODULE_INFO(tag, name, info)                      
    static const char __module_cat(name,__LINE__)[]                  
      __used                                  
      __attribute__((section(".modinfo"),unused)) = __stringify(tag) "=" info
    
    #define __MODULE_PARM_TYPE(name, _type)                      
      __MODULE_INFO(parmtype, name##type, #name ":" _type)
    /* This is the fundamental function for registering boot/module
       parameters.  perm sets the visibility in sysfs: 000 means it's
       not there, read bits mean it's readable, write bits mean it's
       writable. */
    #define __module_param_call(prefix, name, set, get, arg, perm)        
        /* Default value instead of permissions? */            
        static int __param_perm_check_##name __attribute__((unused)) =    
        BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2))    
        + BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN);    
        static const char __param_str_##name[] = prefix #name;        
        static struct kernel_param __moduleparam_const __param_##name    
        __used                                
        __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) 
        = { __param_str_##name, perm, set, get, { arg } }
    
    #define module_param_call(name, set, get, arg, perm)                  
        __module_param_call(MODULE_PARAM_PREFIX, name, set, get, arg, perm)
    
    /* Helper functions: type is byte, short, ushort, int, uint, long,
       ulong, charp, bool or invbool, or XXX if you define param_get_XXX,
       param_set_XXX and param_check_XXX. */
    #define module_param_named(name, value, type, perm)               
        param_check_##type(name, &(value));                   
        module_param_call(name, param_set_##type, param_get_##type, &value, perm); 
        __MODULE_PARM_TYPE(name, #type)
    
    #define module_param(name, type, perm)                
        module_param_named(name, name, type, perm)

    下面以驱动模块中的用例展开宏,

    static int tiger=1;
    module_param(tiger,int,S_IRUGO)

    1.第一步展开

    #define module_param(name, type, perm)                
        module_param_named(name, name, type, perm)

    展开结果为

    module_param_named(tiger,tiger,int,S_IRUGO)    

    2.第二步展开,展开为三项

    /* Helper functions: type is byte, short, ushort, int, uint, long,
       ulong, charp, bool or invbool, or XXX if you define param_get_XXX,
       param_set_XXX and param_check_XXX. */
    #define module_param_named(name, value, type, perm)               
        param_check_##type(name, &(value));                   
        module_param_call(name, param_set_##type, param_get_##type, &value, perm); 
        __MODULE_PARM_TYPE(name, #type)

    2.1 param_check_##type(name, &(value));

    展开结果为,又是一个宏定义

    __param_check(tiger, &(tiger), int)
    #define __param_check(name, p, type) 
        static inline type *__check_##name(void) { return(p); }

    上面的宏再展开为一个内联函数,返回某类型的指针

    static inline int*__check_tiger(void) { return(&(tiger)); 

    2.2 module_param_call(name, param_set_##type, param_get_##type, &value, perm);

    这也是一个宏

    #define MODULE_PARAM_PREFIX /* empty */
    #define module_param_call(name, set, get, arg, perm)                  
        __module_param_call(MODULE_PARAM_PREFIX, name, set, get, arg, perm)

    展开为

    __module_param_call(MODULE_PARAM_PREFIX,tiger, param_set_int, param_get_int, &tiger, S_IRUGO)
    #define __module_param_call(prefix, name, set, get, arg, perm)        
        /* Default value instead of permissions? */            
        static int __param_perm_check_##name __attribute__((unused)) =    
        BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2))    
        + BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN);    
        static const char __param_str_##name[] = prefix #name;        
        static struct kernel_param __moduleparam_const __param_##name    
        __used                                
        __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) 
        = { __param_str_##name, perm, set, get, { arg } }

    上面的宏又展开为3项

    2.2.1 

    static int __param_perm_check_tiger __attribute__((unused)) =    BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) + BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN);

    2.2.2

    static const char __param_str_tiger[] = "tiger";    

    2.2.3

    static struct kernel_param  __param_tiger      __used    __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *))))                         
                = { __param_str_tiger, S_IRUGO, param_set_int, param_get_int, {&tiger}  }

    2.3 __MODULE_PARM_TYPE(name, #type)

    #define __MODULE_PARM_TYPE(name, _type)                      
      __MODULE_INFO(parmtype, name##type, #name ":" _type)

    该宏展开如下

    __MODULE_INFO(parmtype, tigertype, "tiger" ":" "int")
    #define ___module_cat(a,b) __mod_ ## a ## b
    #define __module_cat(a,b) ___module_cat(a,b)
    #define __MODULE_INFO(tag, name, info)                      
    static const char __module_cat(name,__LINE__)[]    __used           
    __attribute__((section(
    ".modinfo"),unused)) = __stringify(tag) "=" info

    最终展开为

    static const char __mod_tigertype__LINE__[] __attribute__((section(".modinfo"),unused)) = "parmtype=tiger:int"
    

    还有一个重要的宏,定义了get/set参数的函数

    #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn)      	
    	int param_set_##name(const char *val, struct kernel_param *kp)	
    	{								
    		tmptype l;						
    		int ret;						
    									
    		if (!val) return -EINVAL;				
    		ret = strtolfn(val, 0, &l);				
    		if (ret == -EINVAL || ((type)l != l))			
    			return -EINVAL;					
    		*((type *)kp->arg) = l;					
    		return 0;						
    	}								
    	int param_get_##name(char *buffer, struct kernel_param *kp)	
    	{								
    		return sprintf(buffer, format, *((type *)kp->arg));	
    	}
    

    以STANDARD_PARAM_DEF(int, int, "%i", long, strict_strtol);为例展开如下:

    int param_set_int(const char *val, struct kernel_param *kp)	
    {								
    	long l;						
    	int ret;						
    								
    	if (!val) return -EINVAL;				
    	ret = strict_strtol(val, 0, &l);				
    	if (ret == -EINVAL || ((long)l != l))			
    		return -EINVAL;					
    	*((long *)kp->arg) = l;					
    	return 0;						
    }								
    int param_get_int(char *buffer, struct kernel_param *kp)	
    {								
    	return sprintf(buffer, "%i", *((long *)kp->arg));	
    }
    

      

  • 相关阅读:
    Attribute
    SQL Server 存储过程
    SQL语句:CRUD
    TCP模拟实现文本文件上传Java代码
    C# Attribute-特性
    Android Pull 读取XML
    【转】SVM入门(九~十一)松弛变量(续)
    【转】SVM入门(八)松弛变量
    【转】SVM入门(七)为何需要核函数
    【转】SVM入门(六)线性分类器的求解——问题的转化,直观角度
  • 原文地址:https://www.cnblogs.com/yangjiguang/p/8290518.html
Copyright © 2020-2023  润新知