linux flash驱动设计思想总结

问题1: linux内核中的subsys_initcall是干什么的?

在编译某驱动为内置代码时,subsys_initcall与module_init仅仅是__define_initcall的第二个参数不同而已,前者使用4,后者使用6,因此归纳出仅仅是谁先被执行的差异,subsys_initcall比module_init先执行。

问题2: EXPORT_SYMBOL 是干什么的? EXPORT_SYMBOL(abc_flash_ctrl);

EXPORT_SYMBOL标签内定义的函数或者符号对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用,即使用EXPORT_SYMBOL可以将一个函数以符号的方式导出给其他模块使用。

     使用方法
         1、在模块函数定义之后使用“EXPORT_SYMBOL(函数名)”来声明。
         2、在调用该函数的另外一个模块中使用extern对之声明。
         3、先加载定义该函数的模块,然后再加载调用该函数的模块,请注意这个先后顺序。

问题3: flash_init函数名前面 __init 是干什么的?

对只需要初始化运行一次的函数都加上__init属性,__init 宏告诉编译器如果这个模块被编译到内核则把这个函数放到(.init.text)段,module_exit的参数卸载时同__init类似,如果驱动被编译进内核,则__exit宏会忽略清理函数,因为编译进内核的模块不需要做清理工作,显然__init和__exit对动态加载的模块是无效的,只支持完全编译进内核。

 

问题4: linux内核中的platform_driver_register是干什么的?

platform_driver_register(&abc_flash_drvier) 会向系统注册abc_flash_drvier这个驱动程序,这个函数会根据 abc_flash_drvier中的.name内容(这里就是abc_flash),搜索系统注册的device中有没有这个platform_device,如果有,就会执行 platform_driver(也就是abc_flash_drvier的类型)中的.probe函数。

工程代码中的platform_driver_register与platform_device_register_simple两个函数,会调用到这个文件中定义的abc_flash_probe函数完成通过FLASH_DEVICE_NAME匹配的platform_device——”abc_flash”的注册。对应sys文件系统中的/sys/devices/platform/abc_flash目录。

int platform_device_register(struct platform_device * pdev)
{ device_initialize(&pdev->dev); //初始化设备结构
return platform_device_add(pdev); //添加一个片上的设备到设备层
}

int device_register(struct device *dev)
{ device_initialize(dev); //初始化设备结构
return device_add(dev); //添加设备到设备层
}

device_register()和platform_device_register()都会首先初始化设备
区别在于第二步:其实platform_device_add()包括device_add(),只不过要先注册resources

struct resource {
resource_size_t start;
resource_size_t end;
const char *name;
unsigned long flags;
struct resource *parent, *sibling, *child;
};

platform机制相对于传统的device driver 机制优点在于:将设备本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过platform device提供的标准接口进行申请并使用。这样提高了驱动和资源管理的独立性,并且拥有较好的可移植性和安全性(这些标准接口是安全的)。

问题4:abc_flash_probe函数什么?

platform_set_drvdata函数的目的是存储用户在probe()中主动申请的内存区域的指针以防止丢失。misc_register  在内核中,misc杂项设备驱动接口是对一些字符设备的简单封装,他们共享一个主设备号10,有不同的次设备号,共享一个open调用,其他的操作函数在打开后运用linux驱动程序的方法重载进行装载。 内核维护一个misc_list链表,misc设备在misc_register注册的时候链接到这个链表,在misc_deregister中解除链接。主要的设备结构就是miscdevice。MISC_DYNAMIC_MINOR,则是动态次设备号misc设备结构,主要包含次设备号,设备名和文件操作结构指针。设备名最终会出现在/dev下,生成设备文件abc_flash。在/sys/devices/virtual/misc/下生成设备目录,里面包含设备属性文件。在/sys/class/misc/下生成符号链接文件abc_flash指向/sys/devices/virtual/misc/abc_flash目录。

device_create_file函数会在/sys/devices/virtual/misc/下生成设备属性文件test

Flash_device 结构体s_flash_dev全局变量在abc_flash_probe函数内部分配内存,然后在实际使用的芯片驱动代码中通过调用abc_flash_register函数赋值。

struct flash_device {
    struct miscdevice md;
    const struct abc_flash_driver_ops *ops[ABC_FLASH_MAX];
    void *driver_data[ABC_FLASH_MAX];
    int flashlight_status[ABC_FLASH_MAX];
    unsigned short attr_test_value;
};
static struct platform_device *pdev;
static struct flash_device *s_flash_dev;

各个芯片驱动内部实现flash_device设备结构体内部的操作方法abc_flash_driver_ops与参数结构体flash_driver_data的赋值。

struct abc_flash_driver_ops {
    int (*open_torch)(void *drvd, uint8_t idx);
    int (*close_torch)(void *drvd, uint8_t idx);
    int (*open_preflash)(void *drvd, uint8_t idx);
    int (*close_preflash)(void *drvd, uint8_t idx);
    int (*open_highlight)(void *drvd, uint8_t idx);
    int (*close_highlight)(void *drvd, uint8_t idx);
    int (*cfg_value_torch)(void *drvd, uint8_t idx);
    int (*cfg_value_preflash)(void *drvd, uint8_t idx);
    int (*cfg_value_highlight)(void *drvd, uint8_t idx);
};

问题5: Flash_drv.c函数中还包含一个flash_sysfs_test函数,它的作用是?

DEVICE_ATTR可以在sys fs中添加“文件”,通过修改该文件内容,可以实现在运行过程中动态控制device的目的。DEVICE_ATTR的功能就是定义一个device_attribute结构体对象。
device_create_file利用该对象在device下创建文件。

类似的还有DRIVER_ATTR,BUS_ATTR,CLASS_ATTR。
这几个东东的区别就是,DEVICE_ATTR对应的文件在/sys/devices/目录中对应的device下面。
而其他几个分别在driver,bus,class中对应的目录下。

DEVICE_ATTR(_name, _mode, _show, _store)

_name:名称,也就是将在sys fs中生成的文件名称。

_mode:上述文件的访问权限,与普通文件相同,UGO的格式。

_show:显示函数,cat该文件时,此函数被调用。

_store:写函数,echo内容到该文件时,此函数被调用。

flash_sysfs_test函数作为DEVICE_ATTR的第四个参数:_store:写函数,echo内容到该文件时,此函数被调用。

使用echo向该设备文件写入内容举例:

开手电筒     echo 10 > /sys/devices/virtual/misc/abc_flash/test       
关手电筒     echo 11 > /sys/devices/virtual/misc/abc_flash/test

linux flash驱动设计思想总结_第1张图片

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(LINUX)