<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統 > 設計應用 > Linux SDIO總線驅動

          Linux SDIO總線驅動

          作者: 時間:2016-12-15 來源:網絡 收藏

          CMD53命令:

          CMD52每次只能讀寫一個字節(jié),因為有了CMD53對讀寫進行了擴展,CMD53允許每次讀寫多個字節(jié)或者多個塊(BLOCK)。CMD53的命令格式如下:

          第一位是1,為開始位,然后是一位方向位,總是1,代表方向為HOST向DEVICE設備傳送,其后6位為命令號,這里是110101b,用十進制表示為53,CMD53的名字也由此而來。

          然后是1位的讀寫標志。接著是3位功能號,這個同CMD52都是相同的。BlockMode如果1代表是塊傳輸模式,否則為字節(jié)傳輸模式。

          OP Code為操作位,如果是0,代表數據往固定的位置讀寫,如果1代表是地質增量讀寫。例如,對地址0固定讀寫16個字節(jié),相當于16次讀寫的地址0,而對地址0增量讀寫16個字節(jié),相當于讀寫0~15地址的數據。

          然后是17位的地址寄存器,可以尋址到128K字節(jié)的地址,然后是9位的讀寫的計數,對于字節(jié)讀取,讀寫大小就是這個計數,而對于塊讀寫,讀寫的大小是計數乘以塊的大小。

          隨后的7位為CRC校驗碼。最后一位為1。

          當讀寫操作是塊操作的時候,塊的大小是可以通過設置FBR中的相關寄存器來設置。

          同CMD52命令不同的是,CMD53沒有返回的命令的,這里判斷是否DEVICE設備讀寫完畢是需要驅動里面自己判斷的,一般有2個方法,1.設置相應的讀寫完畢中斷。如果DEVICE設備讀寫完畢,則對HOST設備發(fā)送中斷。2.HOST設備主動查詢DEVICE設備是否讀寫完畢,可以通過CMD命令是否有返回來判斷是否DEVICE是否讀寫完畢。

          驅動:

          以SDIO為例其會采用mmc_attach_sdio來實現驅動和設備的匹配,其本質還是根據sdio_bus的匹配規(guī)則來實現匹配。在mmc_attach_sdio中首先是mmc匹配一個bus,即采用何種bus來進行mmc bus來處理host。在這里需要理解一點就是在SDIO中,對于SD卡存儲器mmc為實體設備,而對于非SD卡存儲器,如SDIO接口的設備,則mmc則表征為bus,這個比較重要。除了mmc bus外還存在SDIO_BUS。

          int mmc_attach_sdio(struct mmc_host *host,u32 ocr)

          {

          interr;

          inti, funcs;

          structmmc_card *card;

          mmc_attach_bus(host,&mmc_sdio_ops); --host匹配一條mmc bus

          card= mmc_alloc_card(host, NULL); --申請一個card實體,類似于總線設備。

          card->type= MMC_TYPE_SDIO;

          card->sdio_funcs= funcs;

          host->card= card;

          for(i = 0;i < funcs;i++) {

          sdio_init_func(host->card,i + 1);

          }

          mmc_release_host(host);

          mmc_add_card(host->card);

          for(i = 0;i < funcs;i++) {

          sdio_add_func(host->card->sdio_func[i]);

          }

          return0;

          }

          比較難以理解的是func,這個東東其實是一個實體設備的封裝,可以認為其是一個設備。

          struct sdio_func *sdio_alloc_func(structmmc_card *card)

          {

          structsdio_func *func;

          func= kzalloc(sizeof(struct sdio_func), GFP_KERNEL);

          func->card= card;

          device_initialize(&func->dev);

          func->dev.parent= &card->dev; --很明顯card設備為sdio設備的父設備。

          func->dev.bus= &sdio_bus_type;

          func->dev.release= sdio_release_func;

          returnfunc;

          }

          上面的code一目了然,其就是具體設備實體的封裝,其bus類型為sdio_bus. sdio_init_func僅僅是初始化一個設備,而并沒有register。在sdio_add_func實現設備的register,同理就是card實體,在mmc_add_card之前并沒有注冊,在mmc_add_card函數中才實現設備的注冊。

          到此設備注冊也就完成了,其實sdio總線在形式上類似于usb bus,為什么呢?編寫過usb驅動的童鞋們應該知道,編寫usb驅動僅僅是編寫驅動的加載,并沒有具體加載設備實體,導致很多童鞋的困惑,為什么沒有設備的加載,其實在usb設備插入時,會動態(tài)的創(chuàng)建一個usb設備實體,在usb設備實體創(chuàng)建完成后,根據不同設備id調用相匹配的驅動。而SDIO設備設備也是一樣的。上面的code比較混亂,總是讓人看不出具體的設備的加載。其實在上面的code中,其中包括了mmc host的驅動。



          關鍵詞: LinuxSDIO總線驅

          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();