和菜鳥一起學linux總線驅動之初識spi驅動主要結構

?????? 既然知道了協議了,那么就可以開始去瞧瞧linux kenerl中的spi的驅動代碼了,代碼中有很多的結構體,還是對主要的結構體先做個了解吧,那樣才可以很好的理解驅動。主要是include/linux/spi.h

?

首先是SPI的主機和從機通信接口,也就是SPI總線,

extern struct bus_type spi_bus_type;

bus_type定義在linux/device.h

?

struct bus_type {const char              *name;     //總線的名字struct bus_attribute *bus_attrs;struct device_attribute    *dev_attrs;struct driver_attribute    *drv_attrs; //總線上的device和driver的匹配,匹配成功返回非0值int (*match)(struct device *dev, struct device_driver *drv);int (*uevent)(struct device *dev, struct kobj_uevent_env *env);//當新的device或driver加到總線上的時候,調用driver中的probe函數經行匹配int (*probe)(struct device *dev);int (*remove)(struct device *dev);void (*shutdown)(struct device *dev);int (*suspend)(struct device *dev, pm_message_t state);int (*resume)(struct device *dev);const struct dev_pm_ops *pm;struct subsys_private *p;
};

?

SPI設備

?

struct spi_device {struct device          dev;struct spi_master    *master;    //SPI控制器u32                max_speed_hz;  //最大時鐘頻率u8                  chip_select;     //片選u8                  mode;          //SPI模式
#define    SPI_CPHA     0x01                     /* clock phase */
#define    SPI_CPOL     0x02                     /* clock polarity */
#define    SPI_MODE_0       (0|0)                     /* (original MicroWire) */
#define    SPI_MODE_1       (0|SPI_CPHA)
#define    SPI_MODE_2       (SPI_CPOL|0)
#define    SPI_MODE_3       (SPI_CPOL|SPI_CPHA)
#define    SPI_CS_HIGH      0x04                     /* chipselect active high? */
#define    SPI_LSB_FIRST    0x08                     /* per-word bits-on-wire */
#define    SPI_3WIRE   0x10                     /* SI/SO signals shared */
#define    SPI_LOOP     0x20                     /* loopback mode */
#define    SPI_NO_CS   0x40                     /* 1 dev/bus, no chipselect */
#define    SPI_READY  0x80                     /* slave pulls low to pause */u8                  bits_per_word;              //一次傳輸的bits,可以是8、16、32,默認是8int                 irq;                 void               *controller_state;void               *controller_data;        char               modalias[SPI_NAME_SIZE];  //別名,用于device和driver的匹配
};


?

?

SPI驅動

?

struct spi_driver {const struct spi_device_id *id_table;int                 (*probe)(struct spi_device *spi);  //綁定驅動和SPI設備int                 (*remove)(struct spi_device *spi);void               (*shutdown)(struct spi_device *spi);int                 (*suspend)(struct spi_device *spi, pm_message_t mesg);int                 (*resume)(struct spi_device *spi);struct device_driver         driver;
};


?

SPI主控制器

?

struct spi_master {struct device   dev;   //驅動的設備接口struct list_head list;        //SPI控制器的鏈表頭s16                bus_num;    //總線號/* chipselects will be integral to many controllers; some others* might use board-specific GPIOs.*/u16                num_chipselect;    //SPI設備的片選號u16                dma_alignment;     //dma模式  /* 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;bool               bus_lock_flag;int                 (*setup)(struct spi_device *spi);   //更新SPI設備的模式和SPI設備的采樣時鐘int                 (*transfer)(struct spi_device *spi,    //添加一個消息到控制器的傳輸隊列struct spi_message *mesg);void               (*cleanup)(struct spi_device *spi);};


?

SPI傳輸

?

struct spi_transfer {/* it's ok if tx_buf == rx_buf (right?)* for MicroWire, one buffer must be null* buffers must work with dma_*map_single() calls, unless*   spi_message.is_dma_mapped reports a pre-existing mapping*/const void       *tx_buf;    //要寫的數據void        *rx_buf;                //要讀的數據unsigned  len;                       //數據長度dma_addr_t    tx_dma;       //tx_buf的DMA地址dma_addr_t    rx_dma;         //rx_buf的DMA地址unsigned  cs_change:1;u8           bits_per_word;       //傳輸的bytes數,不選就用默認的u16         delay_usecs;                  //微秒延時,用以傳輸數據后,改變片選信號前u32         speed_hz;            //傳輸速率,不選就用默認的struct list_head transfer_list;     //傳輸鏈表,用以傳輸spi_message};


?

SPI消息

?

struct spi_message {struct list_head       transfers;   // struct spi_device     *spi;      //加到傳輸隊列中的spi設備unsigned         is_dma_mapped:1;   //DMA傳輸控制位/* completion is reported through a callback */void               (*complete)(void *context);      //傳輸完成void               *context;                                    //complete函數的參數                unsigned         actual_length;             //所有成功傳輸字段的總長度int                 status;                                 //傳輸成功返回0,否則返回錯誤/* for optional use by whatever driver currently owns the* spi_message ...  between calls to spi_async and then later* complete(), that's the spi_master controller driver.*/struct list_head       queue;void               *state;};


?

SPI bitbang

?

struct spi_bitbang {struct workqueue_struct *workqueue;struct work_struct   work;spinlock_t              lock;struct list_head       queue;u8                  busy;u8                  use_dma;u8                  flags;             /* extra spi->mode support */struct spi_master    *master;/* setup_transfer() changes clock and/or wordsize to match settings* for this transfer; zeroes restore defaults from spi_device.*/int   (*setup_transfer)(struct spi_device *spi,struct spi_transfer *t);void (*chipselect)(struct spi_device *spi, int is_on);
#define    BITBANG_CS_ACTIVE      1     /* normally nCS, active low */
#define    BITBANG_CS_INACTIVE   0/* txrx_bufs() may handle dma mapping for transfers that don't* already have one (transfer.{tx,rx}_dma is zero), or use PIO*/int   (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t);/* txrx_word[SPI_MODE_*]() just looks like a shift register */u32  (*txrx_word[4])(struct spi_device *spi,unsigned nsecs,u32 word, u8 bits);};


??????? 在SPI控制器里面最常用的用來處理傳輸的結構體spi_bitbang了。

?

SPI borad info

struct spi_board_info {/* the device name and module name are coupled, like platform_bus;* "modalias" is normally the driver name.** platform_data goes to spi_device.dev.platform_data,* controller_data goes to spi_device.controller_data,* irq is copied too*/char  modalias[SPI_NAME_SIZE];const void *platform_data;void  *controller_data;int  irq;/* slower signaling on noisy or low voltage boards */u32  max_speed_hz;/* bus_num is board specific and matches the bus_num of some* spi_master that will probably be registered later.** chip_select reflects how this chip is wired to that master;* it's less than num_chipselect.*/u16  bus_num;u16  chip_select;/* mode becomes spi_device.mode, and is essential for chips* where the default of SPI_CS_HIGH = 0 is wrong.*/u8  mode;/* ... may need additional spi_device chip config data here.* avoid stuff protocol drivers can set; but include stuff* needed to behave without being bound to a driver:*  - quirks like clock rate mattering when not selected*/
};

?????? 控制器里會讀取borad info里的參數

?

SPI gpio_platform_data

?

struct spi_gpio_platform_data {unsigned  sck;unsigned  mosi;unsigned  miso;u16         num_chipselect;};


??????? 因為我用的比較多的是GPIO模擬的,所以還是記錄下這個從platform傳進來的管腳號。

?

?????? OK,對于SPI用到的結構體基本上已經介紹完了,那么接下來就介紹其主要函數了。

?

轉載于:https://www.cnblogs.com/wuyida/archive/2012/08/29/6300060.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/377253.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377253.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377253.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

操作系統大內核和微內核_操作系統中的內核

操作系統大內核和微內核A Kernel is the central component of an Operating System. The Kernel is also said to be the heart of the Operating System. It is responsible for managing all the processes, memory, files, etc. The Kernel functions at the lowest level …

《MySQL——鎖》

全局鎖是什么?全局鎖有什么用?全局鎖怎么用? 全局鎖主要用在邏輯備份過程中,對于InnoDB 引擎的庫,使用–single-transaction; MySQL 提供了一個加全局讀鎖的方法,命令是 Flush tables with read lock (FTW…

搜索引擎Constellio及Google Search Appliances connectors

做搜索產品的時候發現國外一個同類型的產品contellio,發現功能比較強大,先記錄下來 貌似可以添加文檔 網站 以及數據庫等不同類型的數據源 http://wiki.constellio.com/index.php/Main_Page http://www.constellio.com/ http://www.constellio.com htt…

dig下載_DIG的完整形式是什么?

dig下載DIG:副監察長 (DIG: Deputy Inspector General) DIG is an abbreviation of the Deputy Inspector General. It is a high-level position in the Indian Police Service. The officers who already offered service on Senior Superintendent of Police (SS…

分類器是如何做檢測的?——CascadeClassifier中的detectMultiScale函數解讀

原地址:http://blog.csdn.net/delltdk/article/details/9186875 在進入detectMultiScal函數之前,首先需要對CascadeClassifier做初始化。 1. 初始化——read函數 CascadeClassifier的初始化很簡單: cv::CascadeClassifier classifier; cl…

<MySQL>何時使用普通索引,何時使用唯一索引

如果能夠保證業務代碼不會寫入重復數據,就可以繼續往下看。 如果業務不能保證,那么必須創建唯一索引。 關于查詢能力 普通索引和唯一索引在查詢能力上是沒有很大差別的。 如:select id from T where k5 1、普通索引查找到滿足條件的第一個記…

Web版OutLook,利用POP接收郵件服務器郵件

一直想做一個Web版的OutLook,所以才萌生這個想法,其實以前也接觸過這方面的東西。于是上網找了找,漫天的都是Jmail來接收,好吧,既然大家都在用我也就下載下來試試了。 什么,怎么總是報錯呢?原來…

abs std::abs_ABS的完整形式是什么?

abs std::absABS:防抱死制動系統 (ABS: Anti-lock Braking System) ABS is an abbreviation of the Anti-lock Braking System. It is a safety anti-skid braking system that is used on a variety of aircraft, automobiles and other land vehicles, such as mo…

ubuntu 使用

shell 命令歷史搜索 : ctrl r使能 session 選擇界面:安裝gnome-session-fallback安裝lwqq轉載于:https://www.cnblogs.com/JonnyLulu/p/3600263.html

漢字速查使用方法簡介

《漢字速查》(HanziSearcher)是一個支持全漢字字典和詞典的檢索工具。其界面如下所示。 界面上方為工具欄。 左方為字典和詞典檢索欄。 右方在啟動時顯示版權信息和作者的聯系方式,在執行檢索時,顯示檢索結果。 檢索方法 漢字速查…

android jni示例_Android服務示例

android jni示例A service is a component that runs in the background for supporting different types of operations that are long running. The user is not interacted with these. These perform task even if application is destroyed. Examples include handling of…

《MySQL——選錯索引,該如何做》

如果不斷地刪除歷史數據和新增數據,MySQL有時會選錯索引。 選擇索引是優化器的工作,優化器優化時會考慮的因素:掃描行數、是否需要排序、是否使用臨時表 MySQL通過統計索引上的基數,作為索引的區分度。 統計方法時采樣統計&#x…

LPWSTR 類型的實參與const.char *類型形參不兼容

CString csPlus; CString csSummand; m_PlusNumber.GetWindowTextW(csPlus); m_Summand.GetWindowTextW(csSummand); int nPlus atoi(csPlus.GetBuffer(0)); //將編輯框文本轉換成整數// int nPlus atoi(strcpy(csPlus.GetBuffer(10),"aa")); csPlus.ReleaseBu…

空間換時間,把遞歸的時間復雜度降低到O(2n)

遞歸算法的時間復雜度除非只有前兩項,否則都不是線性的,并且相當耗費內存。我們用最常見的的fibonacci數列來說明: function fibonacci(n){if( n 0 || n 1){return n;} else {return fibonacci(n - 1) fibonacci(n - 2);} } 這是一種最常見…

scala char_Scala中的Char數據類型

scala charScala Char數據類型 (Scala Char Data Type) Character (char) in Scala is a data type that is equivalent to 16-bit unsigned integer. The character data type stores a single character. It can be an alphabet, numbers, symbols, etc. The character takes…

《MySQL——給長字符串加索引》

對于長字符串,可用如下方式建立索引: (1)前綴索引 (2)字符串倒敘前綴索引 (3)添加hash字段并在hash字段上加索引 (4)字段拆分(一個字段可拆分為兩…

[藍橋杯歷屆試題] 歐拉與雞蛋

大數學家歐拉在集市上遇到了本村的兩個農婦,每人跨著個空籃子。她們和歐拉打招呼說兩人剛剛賣完了所有的雞蛋。 歐拉隨便問:“賣了多少雞蛋呢?” 不料一個說:“我們兩人自己賣自己的,一共賣了150個雞蛋,雖然…

Python元組練習

Here, we are covering following Python tuple exercises, 在這里,我們將介紹以下Python元組練習 , Creating & printing a tuple 創建和打印元組 Unpacking the tuple into strings 將元組解包成字符串 Create a tuple containing the letters of…

傻瓜教你看清MVC內部執行流程之ViewData數據傳輸,輕松學MVC--①目了然篇(待續)

1.首先在執行到Controller里面的action(方法)時,執行到最后會調用一個View()-->此方法是Controller的一個方法 源代碼: View Code protected internal ViewResult View(){return View(null /* viewName */, null /* masterName */, null /* model */);} 2.然后繼續調用自己…

《MySQL——count()邏輯》

count()用法 count()語義:該函數為一個聚合函數,對于返回的結果集一行行地判斷,如果count函數地參數不是NULL,累計值就加1,否則不加。最后返回累計值。 所以count(*),count(主鍵id)和count(1)都表示返回滿足條件地結果…