zoukankan      html  css  js  c++  java
  • 设备驱动之SPI

    本文非专业讲SPI,只是讲网上看到的资料略微总结,并加上自己的想法,附资料links。

    devs.c  :各个platform_device 的定义,比如I2C、USB、SPI等等。应该是内核加载时,读取该配置文件,然后注册进系统。目录在/arch/arm/plat-samsung/devs.c

      比如:

        

    /* SPI */
    
    #ifdef CONFIG_PLAT_S3C24XX
    static struct resource s3c_spi0_resource[] = { //下面s3c_device_spi0对象的资源
        [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI, SZ_32),
        [1] = DEFINE_RES_IRQ(IRQ_SPI0),
    };
    
    struct platform_device s3c_device_spi0 = {  // 声明s3c_device_spi0 platform设备
        .name        = "s3c2410-spi",  //会与驱动匹配,比较两个名字是一样的
        .id        = 0,  //相当于次设备号
        .num_resources    = ARRAY_SIZE(s3c_spi0_resource),
        .resource    = s3c_spi0_resource,
        .dev        = {
            .dma_mask        = &samsung_device_dma_mask,
            .coherent_dma_mask    = DMA_BIT_MASK(32),
        }
    };

     spi_master 本质上是个device,看做总线。spi总线以spi_master体现,可以当做一样

    奇怪  SPI_MASTER: comment "SPI Master Controller Drivers"

    struct spi_master {
        struct device    dev; //说明spi_master本质上是device的封装,总线本身就是一个设备
    
        struct list_head list;
        s16            bus_num;
        u16            num_chipselect;
        u16            dma_alignment;
    
        /* spi_device.mode flags understood by this controller driver */
        u16            mode_bits;
    
        /* other constraints relevant to this driver */
        u16            flags;
    #define SPI_MASTER_HALF_DUPLEX    BIT(0)        /* can't do full duplex */
    #define SPI_MASTER_NO_RX    BIT(1)        /* can't do buffer read */
    #define SPI_MASTER_NO_TX    BIT(2)        /* can't do buffer write */
    
        /* lock and mutex for SPI bus locking */
        spinlock_t        bus_lock_spinlock;
        struct mutex        bus_lock_mutex;
    
        /* flag indicating that the SPI bus is locked for exclusive use */
        bool            bus_lock_flag;
        int            (*setup)(struct spi_device *spi);
    
        int            (*transfer)(struct spi_device *spi,
                            struct spi_message *mesg);
    
        /* called on release() to free memory provided by spi_master */
        void            (*cleanup)(struct spi_device *spi);
    
        bool                queued;
        struct kthread_worker        kworker;
        struct task_struct        *kworker_task;
        struct kthread_work        pump_messages;
        spinlock_t            queue_lock;
        struct list_head        queue;
        struct spi_message        *cur_msg;
        bool                busy;
        bool                running;
        bool                rt;
    
        int (*prepare_transfer_hardware)(struct spi_master *master);
        int (*transfer_one_message)(struct spi_master *master,
                        struct spi_message *mesg);
        int (*unprepare_transfer_hardware)(struct spi_master *master);
    };
    struct boardinfo {
        struct list_head    list;
        struct spi_board_info    board_info;
    };

    SPI分三层:

      SPI核心层:/drivers/spi/spi.c

        postcore_initcall(spi_init);--->内核调用spi_init()---->status = bus_register(&spi_bus_type);spi总线对象注册到platform_bus上。

      SPI控制器驱动层:/drivers/spi/spi-s3c24xx.c   

        module_platform_driver(s3c24xx_spi_driver);--->s3c24xx_spi_driver->probe()初始化控制器各项--->spi_alloc_master()分配一个spi_master(spc.c中fun)--->

        -->spi_bitbang_start()中---->调用spi_register_master()(spc.c中fun)注册spi_master主控制器到platform_bus上,--->device_add(&master->dev);(spc.c中fun)//register the device, then userspace will see it.

      SPI设备驱动层: /drivers/spi/spidev.c

         module_init(spidev_init);--->spidev_init(void)--->spi_register_driver(&spidev_spi_driver);(spi.c中fun) //注册设备驱动

     1、spi_device代表一个外围spi设备,由master controller driver注册完成后扫描BSP中注册设备产生的设备链表并向spi_bus注册产生。

    2、  spi_driver代表一个SPI protocol drivers,即外设驱动。

    3、spi_master代表一个主机控制器,此处即S3C2440中的SPI控制器,它是抽象出来的?

    4、spi_transfer代表一个读写缓冲对,包含接收缓冲区及发送缓冲区,其实,spi_transfer的发送是通过构建spi_message实现,通过将spi_transfer中的链表transfer_list链接到spi_message中的transfers,再以spi_message形势向底层发送数据。

    5、spi_message代表spi消息,由多个spi_ transfer段组成:

    6、s3c24xx_spi代表具体的s3c2440中的spi控制器,包含了控制器的信息,如中断,寄存器等信息,定义于/drivers/spi/spi_s3c24xx.c(因为该结构与具体的硬件有关,属于linux里面的非通用代码)

    7、struct spi_bitbang是具体的负责信息传输的数据结构,它维护一个workqueue_struct,每收到一个消息,都会向其中添加一个work_struct,由内核守护进程在将来的某个时间调用该work_struct中的function进行消息发送。 

     

    related links:

    1、以专家为榜样,不必自己重新探索
    2、解构技能,找出实现80%效果的那20%
    3、不要一心二用
    4、练习练习再练习!然后获得即时反馈
    5、坚持,不要在低谷期放弃
  • 相关阅读:
    web每隔几秒页面刷新
    lucene.Net (C#)
    hibernatesearch
    org.simpleframework.xml.core.Persister
    Hibernate 注解 annotation
    WebService大讲堂之Axis2(2):复合类型数据的传递
    myEclipse代码格式化
    WebService大讲堂之Axis2(1):用POJO实现0配置的WebService
    Hibernate Search基本配置和使用
    java.sql.preparedstatement的应用
  • 原文地址:https://www.cnblogs.com/zhongyuan/p/4283826.html
Copyright © 2011-2022 走看看