精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

分析Linux內核中的SPI驅動源碼

系統 Linux
本文分析了Linux內核中的SPI驅動源碼,介紹了SPI驅動框架的基本結構、Spi.c的結構和作用以及SPI驅動中的重要數據結構和函數。

本文將對Linux內核中的SPI驅動源碼進行分析,包括SPI驅動框架的基本結構、各文件的作用、重要的數據結構和函數等。

SPI(Serial Peripheral Interface)是一種串行通信接口,常常用于與數字外設進行通信,如傳感器、存儲器、網卡等。Linux內核提供了SPI驅動框架,用于向上層應用程序提供SPI接口。本文將對該框架進行深入分析。

一、SPI驅動框架的基本結構

在Linux內核中,SPI驅動框架的代碼位于/drivers/spi目錄下。該目錄下的源文件主要包括以下幾個:

  • spi.c:SPI總線設備驅動程序。
  • spi-bitbang.c:位壓縮SPI驅動程序。
  • spi-dw-dma.c:SPI DMA驅動程序。
  • spi-dw-mmio.c:SPI MMIO驅動程序。
  • spi-fsl-dspi.c:FSL DSPI驅動程序。
  • spi-imx.c:i.MX SPI驅動程序。
  • spi-pl022.c:ARM PrimeCell PL022 SPI驅動程序。
  • spi-s3c24xx.c:Samsung S3C24xx SPI驅動程序。
  • spi-tegra20-sflash.c:Nvidia SPI Flash驅動程序。
  • spi-ti-qspi.c:TI Quad SPI驅動程序。

這些驅動程序分別對應不同的SPI控制器。其中,spi.c是SPI驅動的核心文件,提供了SPI驅動框架的基本結構和主要函數。

二、spi.c的結構和作用

1、SPI驅動框架的初始化

SPI驅動框架的初始化主要在spi_init()函數中完成。該函數首先調用spi_bus_type_init()函數,注冊SPI設備總線,然后向/sys/class下的spi_master目錄中創建spi設備目錄,最后調用probe_master()函數,搜索當前系統中的SPI設備并添加到bus層中。該函數的代碼如下:

static int __init spi_init(void)
{
int status;
status = spi_bus_type_init();
if (status)
goto out;
status = class_register(&spi_master_class);
if (status)
goto bus_unregister;
status = spi_proc_init();
if (status)
goto class_unregister;
status = spi_gpio_register_board_info(NULL, 0);
if (status)
goto proc_cleanup;
status = spi_read_configfile();
if (status)
goto board_cleanup;
status = spi_master_probe_devices();
if (status)
goto board_cleanup;
printk(KERN_INFO "%s\n", spi_revision);
return 0;
board_cleanup:
spi_board_cleanup();
proc_cleanup:
spi_proc_cleanup();
class_unregister:
class_unregister(&spi_master_class);
bus_unregister:
spi_bus_type_exit();
out:
return status;
}

2、SPI總線設備的添加和刪除

當SPI總線設備(spi_master)被發現并添加到bus層時,會自動調用spi_master_add()函數,該函數會為SPI總線設備創建一個spi_master結構體,并將其添加到bus層中。

static int spi_master_add(struct spi_master *master)
{
struct device *dev = master->dev.parent;
struct spi_controller *ctlr = master->controller;
mutex_lock(&spi_mutex);
/*
? Implementation restriction: each SPI MASTER talks with other
? devices at constant signal levels, which don't change once
? operation starts. We don't provide any synchronization
? primitives that would be necessary for anything else.
*/
if (master->num_chipselect)
dev_warn(dev, "num_chipselect should == 1 when !is_slave\n");
if (!ctlr) {
ctlr = kzalloc(sizeof(struct spi_controller), GFP_KERNEL);
if (!ctlr) {
mutex_unlock(&spi_mutex);
return -ENOMEM;
}
ctlr->master = master;
master->controller = ctlr;
master->bits_per_word_mask = 0xFFFF;
if (!spi_controller_is_slave(master)) {
ctlr->max_speed_hz = spi_max_speed_hz(&ctlr->dev, master);
ctlr->setup = spi_master_setup;
ctlr->transfer_one = spi_transfer_one;
} else {
ctlr->max_speed_hz = master->max_speed_hz;
ctlr->setup = spi_slave_setup;
ctlr->transfer_one = spi_transfer_one_slave;
}
ctlr->bits_per_word_mask = master->bits_per_word_mask;
ctlr->flags = 0;
ctlr->mode_bits = master->mode_bits;
if (spi_controller_is_slave(master)) {
ctlr->mode_bits = 0;
ctlr->flags = SPI_CONTROLLER_SLAVE;
ctlr->bus_num = spi_slave_controller_id++;
idr_init(&ctlr->idr);
} else {
ctlr->mode_bits &= ctlr->controller_ops->get_mode_bits;
ctlr->flags |= SPI_CONTROLLER_MASTER;
ctlr->bus_num = spi_master_controller_id++;
}
dev_set_drvdata(dev, master);
dev_info(dev, "registered, %s%s%s%s%s\n",
ctlr->flags & SPI_CONTROLLER_MASTER ? "master" : "",
ctlr->flags & SPI_CONTROLLER_SLAVE ? "slave" : "",
ctlr->flags & SPI_CONTROLLER_CS_WORD ? "cs-high" : "",
ctlr->flags & SPI_CONTROLLER_NEEDS_POLL ? ", polling" : "",
ctlr->mode_bits ? ", mode " : "");
list_add_tail(&ctlr->list, &ctlr_list);
}
mutex_unlock(&spi_mutex);
return 0;
}

當SPI總線設備從bus層中刪除時,會自動調用spi_master_del()函數,該函數會刪除spi_master結構體并釋放相關資源。

static int spi_master_del(struct spi_master *master)
{
int my_bus_num = master->controller->bus_num;
mutex_lock(&spi_mutex);
if (my_bus_num < 0) { /* not yet attached */
mutex_unlock(&spi_mutex);
return -EINVAL;
}
if (!spi_controller_is_slave(master)) {
if (spi_master_get(master)) {
mutex_unlock(&spi_mutex);
return -EINVAL;
}
}
dev_info(&master->dev, "removed\n");
spi_controller_cleanup(master->controller);
kfree(master->controller);
return 0;
}

三、重要的數據結構和函數

1、spi_device

spi_device結構體表示一個SPI設備,包含了設備的名稱、片選信號、總線速率、數據位數、SPI傳輸設置等信息。該結構體被定義在include/linux/spi/spi.h頭文件中,其定義如下:

struct spi_device {
struct device dev;
spinlock_t regs_lock;
const struct spi_device *next;
u32 max_speed_hz;
u8 chip_select;
u8 mode;
u8 bit_order;
u16 flags;
u32 irq;
struct mutex io_mutex;
/* RT signal stuff */
struct rt_mutex rt;
struct spi_controller *controller;
};

spi_transfer結構體表示一次SPI傳輸,包含了傳輸的緩沖區、字節長度、傳輸設置等信息以及一個回調函數,用于在傳輸完成時通知上層應用程序。該結構體被定義在include/linux/spi/spi.h頭文件中,其定義如下:

struct spi_transfer {
const void *tx_buf;
void *rx_buf;
unsigned len;
u32 speed_hz;
u16 delay_usecs;
u8 bits_per_word;
/* Used internally, by spi_sync() and the SPI core code */
u8 cs_change:1;
u8 do_read:1;
u8 tx_nbits:6; /* internal, for packing only */
u8 rx_nbits:6; /* internal, for packing only */
u16 rdy_for_tx:1;
u16 rdy_for_rx:1;
u16 cs_change_delay:14;
u16 large_buf:1;
u8 *tx_buf_wr;
u8 *rx_buf_wr;
void *private_data;
void (*complete)(void *private_data);
};

3、spi_sync()

spi_sync()函數用于同步傳輸數據,該函數會等待傳輸完成并返回傳輸結果。該函數的代碼如下:

int spi_sync(struct spi_device *spi, struct spi_transfer *t)
{
DECLARE_COMPLETION_ONSTACK(done);
int status;
t->complete = spi_complete;
t->private_data = &done;
t->rdy_for_tx = t->rdy_for_rx = 0;
t->cs_change = spi->controller->cs_gpiod ? 1 : 0;
status = spi_async(spi, t);
if (status == 0) {
wait_for_completion(&done);
status = t->status;
if (status == -ETIMEDOUT)
status = -EIO;
}
return status;
}

4、spi_async()

spi_async()函數用于異步傳輸數據,該函數會啟動SPI傳輸,并立即返回,不等待傳輸完成。該函數的代碼如下:

int spi_async(struct spi_device *spi, struct spi_transfer *t)
{
struct spi_message msg;
int status;
memset(&msg, 0, sizeof(msg));
msg.spi = spi;
msg.complete = spi_complete;
msg.context = t;
msg.state = NULL;
msg.is_dma_mapped = false;
spi_prepare_message(&msg, t);
status = spi_async_locked(spi_get_parent_master(spi), &msg);
if (status == -EBUSY)
return -EAGAIN;
t->status = status;
if (msg.is_dma_mapped)
dma_unmap_sg(&spi->dev, msg.sgbuf, msg.nents, msg.direction);
if (msg.is_dma_mapped && msg.context && spi_need_dma_clean_up_on_error()) {
struct spi_controller *ctlr = spi->controller;
struct spi_transfer *xfer = msg.contexte
if (xfer->tx_buf && ctlr->dma_tx && ctlr->dma_tx->device->dev) {
dma_sync_sg_for_device(ctlr->dma_tx->device->dev,
msg.sgbuf,
msg.nents,
(ctlr->dma_tx_dir == DMA_MEM_TO_DEV) ?
DMA_TO_DEVICE : DMA_FROM_DEVICE);
dma_unmap_sg(ctlr->dma_tx->device->dev,
msg.sgbuf,
msg.nents,
ctlr->dma_tx_dir);
}
if (xfer->rx_buf && ctlr->dma_rx && ctlr->dma_rx->device->dev) {
dma_sync_sg_for_device(ctlr->dma_rx->device->dev,
msg.sgbuf,
msg.nents,
(ctlr->dma_rx_dir == DMA_MEM_TO_DEV) ?
DMA_TO_DEVICE : DMA_FROM_DEVICE);
dma_unmap_sg(ctlr->dma_rx->device->dev,
msg.sgbuf,
msg.nents,
ctlr->dma_rx_dir);
}
}
if (status == -EINPROGRESS || status == -EBUSY) {
status = 0;
} else if (unlikely(status)) {
dev_err(spi->dev.parent, "%s: spi_sync failed with status %d\n",
func, status);
}
return status;
}

四、總結

本文分析了Linux內核中的SPI驅動源碼,介紹了SPI驅動框架的基本結構、spi.c的結構和作用以及SPI驅動中的重要數據結構和函數。通讀本文后,讀者應該了解了SPI設備的工作原理和Linux內核中提供的SPI驅動框架的實現方式,理解了相關代碼的運行過程和涉及的系統調用,有助于讀者熟練掌握SPI驅動的編寫技巧。

責任編輯:姜華 來源: 今日頭條
相關推薦

2023-05-15 08:58:41

塊設備驅動Linux

2023-05-12 07:27:24

Linux內核網絡設備驅動

2017-08-01 17:34:47

Linux內核驅動文件讀寫

2017-03-17 15:05:05

Linux內核源碼do_fork

2021-03-05 11:52:50

LinuxSPI驅動詳解

2011-08-16 16:20:33

Linuxkconfigmakefile

2009-12-11 09:47:23

Linux內核源碼進程調度

2009-12-11 09:42:54

Linux內核源碼進程調度

2015-07-20 10:00:28

Linux內核編碼風格

2017-03-23 14:30:13

Linux內核驅動編碼風格

2014-07-29 15:44:33

Linux內核Crash

2021-12-15 15:03:51

Linux內核調度

2015-08-03 10:43:58

Linux內核驅動

2013-10-31 16:29:10

Linux內核

2009-12-11 15:10:22

2022-10-08 11:57:30

Linux內核架構

2023-05-08 07:41:07

Linux內核ELF文件

2021-04-08 09:32:17

鴻蒙HarmonyOS應用

2021-12-15 10:02:25

鴻蒙HarmonyOS應用

2015-07-31 10:31:20

Linux 內核編碼規范
點贊
收藏

51CTO技術棧公眾號

成人动漫在线播放| 精品少妇爆乳无码av无码专区| 五月天国产在线| 2021中文字幕一区亚洲| 国产精品色视频| 免费在线观看一级片| 国产一级成人av| 在线视频综合导航| 超级碰在线观看| 日韩欧美在线番号| 久久成人久久爱| 97色在线视频| a一级免费视频| 日韩欧美美女在线观看| 欧美日韩国产免费一区二区| 国产在线视频综合| 日韩在线免费看| 国产成人在线观看免费网站| 日韩美女免费观看| 久久久久久久久久久97| 成人精品影院| 亚洲第一色在线| 成人黄色一级大片| 欧美人体一区二区三区| 一区二区三区中文字幕在线观看| 快播亚洲色图| а√天堂资源在线| 日本中文字幕一区二区视频| 午夜免费久久久久| 波多野结衣在线网址| 伊人春色之综合网| 亚洲成人国产精品| 国产高清av片| 丁香久久综合| 日本乱人伦一区| 精品少妇人妻av免费久久洗澡| 免费网站免费进入在线| 久久视频一区二区| 国产一区免费在线观看| 亚洲精选一区二区三区| 久久超级碰视频| 精品久久97| 91福利社在线观看| 欧美色图色综合| 成人福利电影| 一区二区三区中文字幕精品精品 | 91小视频在线观看| 91原创国产| 91在线公开视频| 蜜桃视频在线观看一区| 国产va免费精品高清在线观看| 国产一级在线播放| 欧美日韩一卡| 欧美激情xxxx性bbbb| 91在线播放观看| 久久精品久久久| 久久精品人人做人人爽| 日本 欧美 国产| 欧美a级片视频| 中文字幕亚洲精品| 欧美日韩国产黄色| 日韩系列欧美系列| 久久精品视频99| 欧美精品一区二区蜜桃| 欧美先锋影音| 久久久欧美精品| 亚洲男人的天堂在线视频| 国产日韩精品视频一区二区三区 | 日韩三级小视频| 国产一区二区精品| 国产精品xxx视频| 亚洲图片小说视频| 国产高清一区日本| 国产精品亚洲不卡a| 无码精品一区二区三区在线 | 天天做天天摸天天爽国产一区| 在线观看av的网址| 人妖欧美1区| 精品国产乱码久久久久久虫虫漫画 | 欧美色图麻豆| 98精品国产自产在线观看| 久久精品一二区| 日韩专区一卡二卡| 国产视频福利一区| 亚洲不卡免费视频| 久久婷婷久久一区二区三区| 亚洲午夜精品国产| 欧美韩日亚洲| 色哟哟精品一区| 亚洲三级在线观看视频| 国产福利资源一区| 亚洲欧美在线一区二区| 黄色录像一级片| 亚洲美女毛片| 国产精品网址在线| 噜噜噜久久,亚洲精品国产品| 久久综合久久久久88| 一区二区三区四区国产| 波多野结衣精品| 欧美在线观看禁18| 丰满少妇一区二区三区专区| 日韩精品免费一区二区夜夜嗨| 日日骚久久av| 五月天综合激情网| 国产一区二区精品久久99| 国产伦精品一区二区三区视频孕妇| 久久99久久| 亚洲精品视频一区| 91n.com在线观看| 成人h动漫精品一区二区器材| 亚洲美女av网站| 男女性高潮免费网站| 小嫩嫩精品导航| 91网站免费观看| 黄网在线观看| 亚洲国产精品一区二区久久| 在线观看亚洲色图| 日韩av中文字幕一区| 最新国产精品亚洲| 五月婷婷中文字幕| 国产98色在线|日韩| 亚洲精品在线观看免费| 成人影院大全| 亚洲国产精品女人久久久| 欧美乱大交做爰xxxⅹ小说| 久久av最新网址| 精品无人区一区二区三区竹菊| 免费大片黄在线观看视频网站| 一本久道久久综合中文字幕 | 中文无码日韩欧| 日韩在线观看免费av| 国产精品xxxx喷水欧美| 国产91在线观看| 波多野结衣 作品| **日韩最新| 在线观看国产欧美| 中文字幕一区二区人妻视频| 97久久精品人人做人人爽| 韩国无码av片在线观看网站| 全球中文成人在线| 色琪琪综合男人的天堂aⅴ视频| 日韩视频在线观看一区| 91视频一区二区| 欧美 丝袜 自拍 制服 另类| 成人动漫视频| 久久免费少妇高潮久久精品99| 精品人妻一区二区三区三区四区 | 91啪亚洲精品| 日本一本二本在线观看| 欧美日韩破处| 91精品国产91久久久| 凸凹人妻人人澡人人添| 午夜精品福利视频网站| 欧美熟妇精品一区二区蜜桃视频 | 丝袜老师办公室里做好紧好爽| 国产精品一线| 69av在线视频| 久草在线青青草| 在线国产电影不卡| 99久久99久久精品免费看小说.| 视频一区视频二区中文字幕| 欧美在线激情| 不卡亚洲精品| 日韩视频免费在线| av中文字幕播放| 亚洲国产欧美一区二区三区丁香婷| 欧美一级片在线免费观看| 影音先锋久久资源网| 国产欧美丝袜| 国产精品伦理| 久久精品色欧美aⅴ一区二区| 99国产精品99| 亚洲成人一区在线| 色婷婷在线影院| 蜜臀国产一区二区三区在线播放| 自拍偷拍亚洲色图欧美| 18国产精品| 日本欧美一级片| 精产国品自在线www| 精品少妇一区二区| 毛片视频网站在线观看| 国产精品美女久久久久久2018| 国产精品久久久久久久av福利| 欧美日韩国产一区精品一区| 精品在线观看一区二区| 日本一区二区电影| 久久国产加勒比精品无码| 天天摸天天干天天操| 欧美视频第二页| 久草资源在线视频| 久久精品人人爽人人爽| 手机精品视频在线| 亚洲永久网站| 99热这里只有精品7| 精品成人自拍视频| 国产免费久久av| 91福利在线尤物| 日韩中文字幕在线| 污污网站免费在线观看| 3d动漫精品啪啪1区2区免费 | 国产精品入口| 日本三级福利片| 香蕉久久夜色精品国产使用方法| 国产一区香蕉久久| 日本三级一区| 欧美大片免费观看| 爱久久·www| 亚洲精品suv精品一区二区| 国产精品高潮呻吟av| 动漫精品一区二区| 久久久久久久久久91| 国产精品美女久久久久av爽李琼| 制服丝袜第一页在线观看| 久久精品久久99精品久久| 激情综合在线观看| 好看不卡的中文字幕| 香蕉精品视频在线| 深夜福利久久| 九色视频成人porny| 精品国产一区二区三区2021| 国产精品99蜜臀久久不卡二区| 波多野在线观看| 九九九久久久久久| 91网在线播放| 亚洲欧美色图片| 天天操天天操天天| 欧美大片国产精品| 国产美女精品视频国产| 欧美性色综合网| 天天干天天色综合| 午夜精品福利一区二区三区av| 欧美人妻精品一区二区免费看| 国产精品私人影院| 国产亚洲精品熟女国产成人| 99re在线精品| 999精品免费视频| 豆国产96在线|亚洲| 91视频福利网| 激情综合亚洲精品| 性生活免费在线观看| 蜜芽一区二区三区| www.com黄色片| 蜜臀av一区二区在线免费观看| 欧美伦理片在线看| 日韩成人一级片| 国产视频一区二区三区在线播放| 亚洲欧美bt| 成人综合视频在线| 午夜亚洲激情| 国产成人av影视| 日本伊人色综合网| 2025韩国理伦片在线观看| 日韩电影免费一区| 日本黄色的视频| 久久激五月天综合精品| 中文字幕亚洲影院| 国产精品亚洲一区二区三区在线 | 欧美xxxx18性欧美| 羞羞污视频在线观看| 久久777国产线看观看精品| 色呦呦在线观看视频| 欧美激情免费看| 麻豆视频在线看| 国产v综合ⅴ日韩v欧美大片| 日本一区二区三区视频在线| 国产精品视频免费观看www| 亚洲男人在线| 国产98在线|日韩| 色天下一区二区三区| 欧美最大成人综合网| 日本一区二区高清不卡| 亚洲小说欧美另类激情| 激情久久一区| 红桃av在线播放| 久久成人综合网| www.黄色网| 久久理论电影网| 182在线观看视频| 亚洲超碰精品一区二区| 潘金莲一级淫片aaaaaa播放| 精品视频123区在线观看| 国产福利小视频| 日韩精品小视频| 欧洲日本在线| 视频精品国内| 91性高湖久久久久久久久_久久99| 精品国产伦一区二区三区观看说明 | 久久久国产精华液999999| 国产精品v欧美精品v日本精品动漫| 亚洲 高清 成人 动漫| 久久精品国产精品青草| av在线播放网址| 中文字幕 久热精品 视频在线 | 日本在线观看| 97精品一区二区视频在线观看| 91tv亚洲精品香蕉国产一区| 99se婷婷在线视频观看| 国产欧美日韩影院| 日韩精品一区二区在线视频| 视频一区在线视频| 黄色av电影网站| 国产精品九色蝌蚪自拍| 欧美激情亚洲综合| 日韩欧美二区三区| 成人免费黄色网页| 亚洲3p在线观看| 精品国产乱码一区二区三区| 欧美日韩亚洲免费| 亚洲无线一线二线三线区别av| 五月天婷婷激情视频| 成人av动漫在线| 午夜国产福利一区二区| 欧美性色黄大片手机版| 亚洲欧美自偷自拍| 免费99精品国产自在在线| 深夜成人福利| 国产欧美欧洲| 激情偷拍久久| 亚洲高清av一区二区三区| 国产日韩欧美一区二区三区综合| 欧美成人aaaaⅴ片在线看| 欧美日本国产视频| 国产精品一级伦理| 欧美在线免费视频| 精品国产一区二区三区不卡蜜臂| 亚洲一区二区三区精品动漫| 亚洲欧美日韩国产一区| 久久性爱视频网站| 亚洲国产中文字幕| av中文字幕观看| 久久久91精品国产| 老司机精品视频网| 天堂社区 天堂综合网 天堂资源最新版 | 欧美精品在欧美一区二区| 韩日av一区二区| 91精品国产闺蜜国产在线闺蜜| 欧美日韩亚洲综合在线 | 九九热这里只有精品免费看| 日本一区二区三区视频在线| 免费精品视频一区| 亚洲综合国产| 91精品国产自产| 欧美性猛交xxxx富婆| 香蕉视频免费在线看| 97久久精品在线| 亚洲国产国产| 久草综合在线观看| 欧美韩日一区二区三区| 色婷婷久久综合中文久久蜜桃av| 国产午夜精品全部视频在线播放 | 麻豆视频在线观看免费网站| 国产精品视频白浆免费视频| 第一页在线视频| 国产日韩高清在线| 这里只有久久精品视频| 中日韩美女免费视频网站在线观看 | 午夜性色福利影院| 欧洲成人免费视频| 欧美美乳视频| 久久婷婷综合色| 亚洲另类在线制服丝袜| 亚洲成a人片在线| 91精品国产一区| 国产成人1区| 中文字幕66页| 亚洲国产精品自拍| 九色蝌蚪在线| 成人网在线观看| 午夜视频一区| 黄色国产在线观看| 欧美中文字幕亚洲一区二区va在线 | 男人天堂网站在线| av在线一区二区三区| 国产字幕在线观看| 美女视频黄免费的亚洲男人天堂| 91成人噜噜噜在线播放| 99热成人精品热久久66| 国产精品天天看| 国 产 黄 色 大 片| 青青草成人在线| 久久精品不卡| 亚洲高清无码久久| 欧美在线视频日韩| 青春草在线免费视频| 久久一区二区三区av| 蜜桃视频在线观看一区| 国产一级片免费| 夜夜嗨av一区二区三区免费区 | 黄色一级视频在线观看| 亚洲精品久久久久久久久久久 | 91在线观看网站| 欧美亚洲在线| 污污的视频在线免费观看| 亚洲国产高清自拍| 成人综合日日夜夜| 免费无码av片在线观看| 五月激情综合| 亚洲精品成人无码熟妇在线| 日韩一区二区在线观看视频播放| 男人的天堂免费在线视频|