精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

少妇人妻无码专区视频| 国产精品美女www| 艳妇乳肉豪妇荡乳xxx| 天堂在线中文网官网| 久久久国际精品| 91亚洲精华国产精华| 日韩毛片在线播放| 色综合咪咪久久网| 亚洲第一av网站| 天美星空大象mv在线观看视频| 羞羞的视频在线观看| 久久婷婷综合激情| 91嫩草免费看| 日本视频www色| 亚洲无线一线二线三线区别av| 亚洲性线免费观看视频成熟| 欧美熟妇精品一区二区| 性欧美18一19sex性欧美| 一区二区三区小说| 亚洲一区二区在线看| 亚洲乱码在线观看| 日本v片在线高清不卡在线观看| 欧美激情视频在线| 婷婷激情四射网| 精品国产一区二区三区噜噜噜 | 欧美综合激情网| 五月天婷婷色综合| 成人羞羞网站| 亚洲美女又黄又爽在线观看| 中文字幕在线观看91| 91成人短视频在线观看| 在线视频国内自拍亚洲视频| 国产深夜男女无套内射| 女子免费在线观看视频www| 国产精品久久久久久久久免费丝袜 | 一区二区三区www| 中国xxxx性xxxx产国| 久久天堂久久| 91精品国产91久久久久久最新毛片| 国产亚洲天堂网| 91福利区在线观看| 亚洲图片有声小说| 国产一区二区四区| 免费电影网站在线视频观看福利| 亚洲欧洲另类国产综合| 亚洲制服欧美久久| 日本中文字幕视频在线| 国产精品久久久久aaaa樱花 | 在线电影一区二区| 日韩一区二区精品视频| 中文字幕第20页| 精品一区毛片| 亚洲精选一区二区| 免费看污片的网站| 日韩av免费大片| 中文字幕成人在线| 小泽玛利亚一区| 欧美一区综合| 欧美激情一级欧美精品| 国产在线观看免费av| 亚洲激情另类| 欧美在线视频免费观看| 久久国产乱子伦精品| 肉色丝袜一区二区| 成人久久久久爱| jlzzjlzz亚洲女人18| 国产成人在线免费| 欧美二区三区在线| 高清av在线| 日韩一区欧美小说| 黄网站色视频免费观看| а√天堂8资源中文在线| 欧美天堂在线观看| 成人午夜电影网站| 99免费在线视频观看| 刘亦菲久久免费一区二区| av在线综合网| 四虎影院一区二区三区 | 国产精品视频在线观看免费| 精品在线视频一区| 国产精品99久久久久久久 | 最新日韩中文字幕| 少妇影院在线观看| 久久动漫亚洲| 亚洲自拍偷拍区| 无码精品一区二区三区在线| 日本一区二区免费在线观看视频 | 18禁裸乳无遮挡啪啪无码免费| 久久97视频| 久久久国产视频| 自拍偷拍欧美亚洲| 麻豆91在线播放免费| 国产成人亚洲欧美| 涩爱av在线播放一区二区| 国产精品网站在线| 国产精品国三级国产av| 欧美日韩精品一区二区三区视频| 日韩欧美国产一区在线观看| 伊人网在线视频观看| 亚洲精品在线观看91| 97视频在线观看免费| 91欧美日韩麻豆精品| 成人精品国产一区二区4080| 色涩成人影视在线播放| 国产探花在线观看| 精品视频在线看| 国产在线不卡av| 99精品全国免费观看视频软件| 久久久久久亚洲| 亚洲天天综合网| 99久久久免费精品国产一区二区| gogogo免费高清日本写真| 欧美男女交配| 亚洲黄页网在线观看| 国产真实乱在线更新| 久久精品一区| 国产区一区二区| 精产国品自在线www| 色悠悠久久综合| 亚洲一区二区在线免费| 欧美在线看片| 国产欧美久久一区二区| 国产主播福利在线| 婷婷开心久久网| 国产白袜脚足j棉袜在线观看| 97人人精品| 国产精品精品久久久| 嫩草在线播放| 精品福利视频导航| chinese麻豆新拍video| 激情综合中文娱乐网| 91大片在线观看| 拍真实国产伦偷精品| 日本韩国欧美三级| 素人fc2av清纯18岁| 亚洲黄色成人| 国产伦精品一区二区三区视频黑人| 超碰免费在线播放| 91 com成人网| 日韩在线中文字幕视频| 精品一区二区三区日韩| 亚洲自拍偷拍二区| 激情久久99| 日韩天堂在线视频| 136福利视频导航| 国产精品国产三级国产普通话三级 | 9999在线观看| 亚洲我射av| 久久精品国产精品| 99久久久无码国产精品免费| 亚洲色大成网站www久久九九| 在线免费观看视频黄| 成人3d动漫在线观看| 国产在线精品成人一区二区三区| 一广人看www在线观看免费视频| 欧美在线免费观看视频| xxxx日本黄色| 久久精品国产成人一区二区三区 | 久久久av水蜜桃| 成人午夜视屏| 在线观看免费高清视频97| 中文字幕日韩经典| 18涩涩午夜精品.www| 性鲍视频在线观看| 影音先锋亚洲电影| 欧美精品123| 日韩毛片在线| 欧美xxxx14xxxxx性爽| 亚洲欧美黄色片| 精品久久久久久亚洲国产300| 在线观看福利片| 精品综合久久久久久8888| 精品视频在线观看一区二区| 精品嫩草影院| 国产成人中文字幕| av电影高清在线观看| 日韩精品高清在线观看| 久久久久久久久久一级| 亚洲女厕所小便bbb| 香蕉久久久久久av成人| 中文在线一区| 亚洲欧美日韩精品在线| 亚洲国产视频二区| 情事1991在线| www.欧美日本韩国| 日韩精品小视频| 一级片免费观看视频| 亚洲一区成人在线| 国产综合精品久久久久成人av| 国产一区二区按摩在线观看| 欧美 日本 亚洲| 99国产**精品****| 开心色怡人综合网站| 青青在线精品| 欧美一级视频免费在线观看| 免费av网站在线观看| 亚洲韩国青草视频| 国产精品特级毛片一区二区三区| 午夜av一区二区三区| 精品在线观看一区| 91捆绑美女网站| 人妻换人妻仑乱| 日韩av电影免费观看高清完整版| www插插插无码免费视频网站| 欧美日韩精品在线一区| 国产精品久久久久av福利动漫| 成人精品高清在线视频| 97av在线影院| 2024最新电影免费在线观看| 一区二区在线视频| 头脑特工队2免费完整版在线观看| 欧美精品视频www在线观看| 亚洲天堂视频网站| 亚洲韩国精品一区| 午夜少妇久久久久久久久 | 久久精品亚洲无码| 国产精品久久久久久久久快鸭| 久久久久9999| 国产成a人亚洲精| 亚洲黄色av片| 男男视频亚洲欧美| 日韩精品无码一区二区三区免费| 亚洲二区在线| 精品人妻人人做人人爽| 91tv官网精品成人亚洲| 亚洲精品9999| 精品日本12videosex| 免费在线观看一区二区| 噜噜噜天天躁狠狠躁夜夜精品 | 国产91在线播放| 中文字幕乱码在线播放| 91av在线网站| 欧美一级鲁丝片| 91精品国产99久久久久久| 丁香花电影在线观看完整版| 欧美大片免费看| 手机电影在线观看| 欧美老肥婆性猛交视频| 综合久久2019| 蜜臀久久99精品久久久无需会员 | 69亚洲乱人伦| 成人免费高清视频| 国产精品一区二区人妻喷水| 不卡的av在线播放| 中文乱码人妻一区二区三区视频| 成人国产一区二区三区精品| 在线免费看黄色片| 91视频一区二区| 小早川怜子久久精品中文字幕| 2014亚洲片线观看视频免费| 右手影院亚洲欧美| 国产情人综合久久777777| 亚洲色图第四色| 成人免费小视频| 久草国产在线视频| 天天综合天天综合色| 亚洲另类欧美日韩| 日本黄色一区二区| 在线观看亚洲国产| 91精品国产手机| 亚洲国产成人精品一区二区三区| 精品久久久久久久久久久久包黑料| 丰满肉肉bbwwbbww| 亚洲精品视频免费| 北条麻妃在线| 欧美成aaa人片免费看| www.九色在线| 国产精品极品尤物在线观看| 国色天香久久精品国产一区| 国产精品xxxx| 一本色道久久综合亚洲精品酒店| 欧洲高清一区二区| 婷婷中文字幕一区| 久艹在线免费观看| 日韩高清在线观看| 免费国偷自产拍精品视频| 99久久免费精品高清特色大片| www在线观看免费视频| 最新中文字幕一区二区三区 | 久久99精品久久久久久水蜜桃| 亚洲福利网站| 天堂av免费看| 亚洲少妇自拍| 九一精品久久久| youjizz久久| 四虎影视一区二区| 天涯成人国产亚洲精品一区av| 久久这里只有精品9| 日韩一区二区麻豆国产| 男女视频在线观看免费| 乱亲女秽乱长久久久| 制服丝袜专区在线| 亚洲va码欧洲m码| 久久综合亚洲| 欧美一区二区三区综合| 日韩 欧美一区二区三区| 乱码一区二区三区| 中文字幕一区二区日韩精品绯色| 国产黄色片视频| 欧美精品粉嫩高潮一区二区| 午夜视频免费在线| 欧美精品一区在线播放| www成人在线视频| 国产亚洲自拍偷拍| 亚洲成人精选| 无码人妻精品一区二区三区66| 国产凹凸在线观看一区二区| 2019男人天堂| 日韩欧美在线看| 欧美77777| 操人视频在线观看欧美| 一区在线影院| 免费国产一区二区| 伊人久久大香线蕉av超碰演员| 五月天av在线播放| 国产亚洲精品中文字幕| 久久草视频在线| 欧美白人最猛性xxxxx69交| 理论片午午伦夜理片在线播放| 国产97在线|亚洲| 日韩最新在线| 国产一区二区四区| 国产成人自拍网| 欧美大片xxxx| 欧美日韩成人综合天天影院 | 成人黄色免费视频| 精品精品国产国产自在线| 国产成人精品一区二三区在线观看 | 国产一区二区小视频| 这里只有精品在线播放| 色豆豆成人网| 欧美午夜精品理论片a级大开眼界 欧美午夜精品久久久久免费视 | 日韩精品一区二区av| 精品国产区一区| 黄页网站大全在线免费观看| 91青青草免费观看| 午夜日本精品| 国产a级片视频| 亚洲电影中文字幕在线观看| 性生交生活影碟片| 欧美日韩xxx| 99亚洲乱人伦aⅴ精品| 国产精品视频一二三四区| 国产99久久久国产精品潘金 | 成人国产精品久久久网站| 狠狠躁18三区二区一区| 天天射天天操天天干| 9.1国产丝袜在线观看| 天海翼精品一区二区三区| 人妻有码中文字幕| 国产欧美精品区一区二区三区| 中文字幕永久在线| 这里只有精品久久| 高清不卡一区| 国产美女永久无遮挡| 91亚洲永久精品| 无码人妻av免费一区二区三区 | 国内精品**久久毛片app| 亚洲精品美女| 男生草女生视频| 欧美日韩第一区日日骚| caoporn免费在线视频| 国产精品成人一区二区三区| 亚洲精品婷婷| 91成人在线免费视频| 欧美日韩精品欧美日韩精品| 黄视频在线观看网站| 成人动漫视频在线观看免费| 妖精视频成人观看www| 欧美多人猛交狂配| 3atv在线一区二区三区| 波多野结衣久久| 日韩精品无码一区二区三区| 激情综合网激情| 日本一级淫片色费放| 亚洲天堂av女优| 久久99成人| 91视频最新入口| 国产精品第一页第二页第三页| 丰满人妻一区二区三区免费视频| 欧美综合在线观看| 天天影视天天精品| 亚洲の无码国产の无码步美| 欧洲色大大久久| 91精选在线| 日韩精品av一区二区三区| 国产精品91一区二区| 免费视频久久久| 欧美老肥婆性猛交视频| 在线一级成人| 亚洲911精品成人18网站| 色哟哟欧美精品| 国产激情小视频在线| 久久资源av| 国产精品白丝av| 国产午夜麻豆影院在线观看| 欧美www在线| 日本一区二区免费高清| 性活交片大全免费看| 欧美日韩日日夜夜|