spi总线设备驱动模型详解(Linux3.4)

(一)spi总线设备驱动框架:
    app:                  open() read() write()
    ------------------------------------------------------------------
                                   系统调用
    --------------------------------------------------------------------
    spi设备驱动:xxx_open() 、xxx_write()、xxx_read()
    --------------------------------------------------------------------
    核心层:  向上提供统一的接口,向下提供管理函数
    --------------------------------------------------------------------
                                spi总线驱动
    ---------------------------------------------------------------------
    硬件:spi控制器1、spi控制器2...  |  从设备1、从设备2....

(二)spi_s3c24xx.c文件分析:(\drivers\spi)

        这个文件用到了 platform总线驱动模型,在platform_driver结构体的probe()函数中注册了spi总线驱动,既然内核已经帮助我们完成了spi总线驱动模型,那么我们要做的就是编写spi设备驱动了,当然,我们也可以不用内核提供的总线驱动,自己编写spi总线设备驱动。

    s3c24xx_spi_init()    
        platform_driver_register
            driver_register
                bus_add_driver              //  bus_add_driver - Add a driver to the bus.
                    kobject_register
                    driver_attach              // try to bind driver to devices.  
                        bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
                        //__driver_attach是一个函数指针,在该函数里,会调用driver_probe_device()函数
                            driver_probe_device()
                                match()
                                    really_probe()
                                         drv->probe()    //就会调用到s3c24xx_spi_probe(),在该函数里面我们做真正的工作。        
                            klist_iter_init_node
                    klist_add_tail
                    module_add_driver
                    driver_add_attrs

          
(三)s3c24xx_spi_probe() 函数分析:
        struct spi_master *master;
        struct spi_board_info *bi;                //定义相关变量
        
        spi_alloc_master()
        spi_master_get_devdata()
        spi_master_get()
        相关设置
        spi_bitbang_start()                        /* register our spi controller */
        spi_new_device()                          /* register all the devices associated */
        spi_master_put(hw->master);;      //和spi_master_get()相对
    
    3.1)spi_bitbang_start() 函数分析:
            spi_register_master          //总线驱动
                class_device_add
                    class_device_get
                    class_device_add_attrs
                    class_device_add_groups
                    make_deprecated_class_device_links
                    list_add_tail
                    list_for_each_entry
                scan_boardinfo
                    list_for_each_entry   //  chip->bus_num == master->bus_num
                    spi_new_device
                        device_register
                            device_add
                                device_add_attrs
                                bus_add_device           //add device to bus
                                bus_attach_device       //Try to attach to driver.
                                    device_attach           // try to attach device to a driver
                                        bus_for_each_drv(dev->bus, NULL, dev, __device_attach)
                                        __device_attach(struct device_driver * drv, void * data)
                                                driver_probe_device(drv, dev);
                                                    drv->bus->match
                                                    really_probe
                                                        drv->probe        
                                list_add_tail
                                list_for_each_entry
    由此可见,当我们注册spi总线驱动时,会自动的向内核添加设备。                  
              
(四)spi设备驱动程序编写:
    xxx_spi_dev.c
        1、设置spi_board_info结构体
        2、spi_register_board_info() 
                spi_match_master_to_boardinfo    //master->bus_num == bi->bus_num,看数量是否相等
                    spi_new_device
        
    xxx_spi_drv.c   //纯软件概念,它的作用就是提供设备读写函数,设备挂接到总线上
        1、分配 spi_driver 结构体
        2、设置
        3、注册 spi_register_driver()
    注:to_spi_device(struct device *dev) 得到 spi_device 结构体,spi_read()和spi_write()函数有可能要用到
        probe函数传进来的参数就是 spi_device结构体指针。
        核心层提供的消息传递函数为:spi_read()、spi_write()。

(五)spi总线驱动程序编写(一般内核都有提供,不过我们也可以自己编写)
    xxx_spi_bus.c
    1、分配 spi_master 结构体
    2、设置    结构体成员
            struct class_device    cdev;
            s16            bus_num;
            u16            num_chipselect;
            int            (*setup)(struct spi_device *spi);
            int            (*transfer)(struct spi_device *spi,struct spi_message *mesg);
            //这个成员函数很重要,spi核心层提供的读写函数最终都会调用到它。
        
            void        (*cleanup)(struct spi_device *spi);
    3、注册 spi_register_master()


                
                
    
        
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章