當前位置:首頁 » 操作系統 » linuxiic驅動

linuxiic驅動

發布時間: 2022-06-23 00:20:38

1. linux下怎麼直接使用iic介面

利用Linux中IIC設備子系統移植IIC設備驅動

背景描述

IIC匯流排在嵌入式系統中應用十分廣泛,常見的有eeprom,rtc。一般的處理器會包含IIC的控制器,用來完成IIC時序的控制;另外一方面,由於IIC的時序簡單,使用GPIO口來模擬時序也是常見的做法。面對不同的IIC控制器,各種各樣的晶元以及linux源碼,如何更快做好IIC設備驅動。

問題描述

在我們的方案中,我們會用到eeprom,rtc以及tw2865。由於Hi3520的IIC控制器設計有問題,無法正常使用。而IIC控制器的SDA和SCL管腳正好是和兩個GPIO管腳復用的。Hisi將控制gpio來實現IIC的時序,從而對IIC設備進行操作。這種設計方式簡單明了,但使用IIC子系統,可以更方便的移植和維護其他的設備驅動。

問題分析

Hisi對於gpio口,rtc晶元以及tw2865的處理方式如下:將gpio口做成一個模塊化的驅動,該驅動模擬IIC時序,並向外提供一些函數介面,比如:EXPORT_SYMBOL(gpio_i2c_read_tw2815);等。對於具體的rtc晶元,將其注冊為一個misc設備,並利用gpio模塊導出的函數進行rtc晶元的配置操作。

其實對於linux-2.6.24\drivers\i2c目錄下代碼,我們可以加以利用。

Linux的IIC字結構分為三個組成部分:

IIC核心

IIC核心提供了IIC匯流排驅動和設備驅動的注冊、注銷方法,IICalgorithm上層的、與具體適配器無關的代碼以及探測設備、檢測設備地址的上層代碼。

IIC匯流排驅動

IIC匯流排驅動是對IIC硬體體系結構中適配器端的實現。

IIC設備驅動

IIC設備驅動是對IIC硬體體系總設備端的實現。

我們查看下該目錄下的makefile和kconfig:

obj-$(CONFIG_I2C_BOARDINFO) +=i2c-boardinfo.o

obj-$(CONFIG_I2C) += i2c-core.o

obj-$(CONFIG_I2C_CHARDEV) +=i2c-dev.o

obj-y +=busses/ chips/ algos/

i2c-core.c就是IIC核心,buses中的文件是主流處理器中IIC匯流排的匯流排驅動,而chips中的文件就是常用晶元的驅動,algos中的文件實現了一些匯流排適配器的algorithm,其中就包括我們要用到的i2c-algo-bit.c文件。

我們首先利用i2c-gpio.c和i2c-algo-bit.c做好匯流排驅動。

在i2c-gpio.c中,mole_initi2c_gpio_initplatform_driver_probe(&i2c_gpio_driver,i2c_gpio_probe);

將其注冊為platform虛擬匯流排的驅動。

在staticint __init i2c_gpio_probe(struct platform_device *pdev)中,

定義了如下三個結構體:

structi2c_gpio_platform_data *pdata;//平台相關的gpio的設置

structi2c_algo_bit_data *bit_data;//包含algorithm的具體函數,setor
get SDA和SCL

structi2c_adapter *adap;//適配器

i2c_gpio_probe主要做了下面幾件事:

填充bit_data結構的各個函數指針,關聯到具體的操作SDA和SCl函數。

填充adap結構,adap->algo_data= bit_data;

pdata= pdev->dev.platform_data;

bit_data->data= pdata;

pdev->dev->driver_data= adap;

在i2c-core中注冊適配器類型。

inti2c_bit_add_numbered_bus(struct i2c_adapter *adap)

在staticint i2c_bit_prepare_bus(struct i2c_adapter *adap)中

adap->algo= &i2c_bit_algo;

將i2c_bit_algo與adap關聯上。

static const structi2c_algorithm i2c_bit_algo = {

.master_xfer = bit_xfer,

.functionality = bit_func,

};

其中,master_xfer函數指針就是IIC傳輸函數指針。

I2c-algo-bit.c還實現了IIC開始條件,結束條件的模擬,發送位元組,接收位元組以及應答位的處理。

i2c-gpio.c中的i2c_gpio_setsda_val等函數是與具體平台gpio相關的。

修改對應arch-hi3520v100目錄下的gpio.h中的各個函數,這些函數是通過操作寄存器來控制gpio的方向和值。

在對應mach-hi3520v100中的platform-devices.c中添加如下:

static structi2c_gpio_platform_data pdata = {

.sda_pin = 1<<0,

.sda_is_open_drain = 1,

.scl_pin = 1<<1,

.scl_is_open_drain = 1,

.udelay = 4, /* ~100 kHz */

};

static struct platform_devicehisilicon_i2c_gpio_device = {

.name = "i2c-gpio",

.id = -1,

.dev.platform_data = &pdata,

};

static struct platform_device*hisilicon_plat_devs[] __initdata = {

&hisilicon_i2c_gpio_device,

};

int __inithisilicon_register_platform_devices(void)

{

platform_add_devices(hisilicon_plat_devs,ARRAY_SIZE (hisilicon_plat_devs));

return 0;

}

通過platform添加devices和driver,使得pdev->dev.platform_data=pdata

綜合上面的過程,我們完成了adapter的注冊,並將用gpio口模擬的algorithm與adapter完成了關聯。

這樣,在rtc-x1205.c中,x1205_attach函數利用i2c核心完成client和adap的關聯。

在x1205_probe函數中填充i2c_client結構體,並調用i2c_attach_client通知iic核心。

接著注冊rtc驅動。

最後我們要讀取時間,就需要構造i2c_msg結構體,如下所示:

struct i2c_msg msgs[] = {

{ client->addr, 0, 2,dt_addr }, /* setup read ptr */

{ client->addr, I2C_M_RD,8, buf }, /* read date */

};

/* read date registers */

if((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {

dev_err(&client->dev,"%s: read error\n", __FUNCTION__);

return -EIO;

}

dt_addr是寄存器的地址,I2C_M_RD表示iicread。

2. 在linux上怎樣增加一個i2c設備

假設手上有一塊從淘寶上買來的開發板,我要在開發板的I2C匯流排上增加一個從設備(如at24c08),那麼我要怎樣寫這個「I2C設備驅動」,讓

應用程序可以訪問at24c08呢?

先來看一個最簡單的i2c設備驅動:
static struct i2c_board_info at24cxx_info = { //所支持的i2c設備的列表
I2C_BOARD_INFO("at24c08", 0x50), //一項代表一個支持的設備,它的名字叫做「at24c08」,器件地址是0x50
};
static struct i2c_client *at24cxx_client;
static int at24cxx_dev_init(void)
{
struct i2c_adapter *i2c_adap; //分配一個適配器的指針
i2c_adap = i2c_get_adapter(0); //調用core層的函數,獲得一個i2c匯流排。這里我們已經知道新增的器件掛接在編號為0的i2c匯流排上
at24cxx_client = i2c_new_device(i2c_adap, &at24cxx_info); // 把i2c適配器和新增的I2C器件關聯起來,這個用了i2c匯流排0,地址是0x50。這就組成了一個客戶端
at24cxx_client i2c_put_adapter(i2c_adap);
return 0;
}
static void at24cxx_dev_exit(void)
{
i2c_unregister_device(at24cxx_client);
}
mole_init(at24cxx_dev_init);
mole_exit(at24cxx_dev_exit);

從上面的程序可以看到,寫一個i2c設備驅動程序,與寫普通的字元驅動基本一樣。特別之處是它調用了i2c的core層的函數,以獲得對i2c匯流排的控制。因為用的是開發板,板上的與soc晶元(一般來說就是arm的晶元)i2c匯流排驅動一般都做好了,直接調用core層的函數就可以控制soc的i2c模塊了。也就是說,寫i2c設備驅動不需要關注arm內部的i2c模塊的寄存器,我們需要關注的是設備(at24c08)的寄存器以及它的datasheet對時序的要求。

其實,添加i2c設備的方法很靈活。根據Linux的官方文檔《linux-3.4.2\Documentation\i2c\instantiating-devices》,添加i2c設備的方法總結有4種:

1. i2c_register_board_info:根據匯流排編號、設備名字(「at24c08」)、設備地址(0x50)注冊一個字元驅動。這種方法最簡單、最粗暴,最貼近平時在開片機上開發i2c器件的。

2. i2c_new_device:根據i2c匯流排的編號,聲明一個i2c設備:這種方法就是上面例子用的方法。這種方法也簡單,但是需要事先知道器件掛接在哪條匯流排上。對於設備,還實現知道了設備地址0x50,匯流排適配器也支持名字為「at24c08」的設備

3. i2c_new_probed_device:

4.從用戶空間實例化一個器件:這個方法相當智能快速,如下輸入指令,即可增加一個i2c設備,同時增加了對應的設備文件。

# echo eeprom 0x50 > /sys/bus/i2c/devices/i2c-3/new_device

根據英文文檔的標題,添加i2c設備有稱之為「i2c設備的實例化」。

從上述可以知道,在實例化一個i2c設備之前,除了有對應的驅動支持匯流排外(這里是匯流排0),還需要有一個驅動使用了匯流排0發送時序,支持名字為"at24c08"的器件。這個驅動用匯流排驅動的函數,配置了at24c08的寄存器。

3. linux 怎麼載入i2c驅動

假設手上有一塊從淘寶上買來的開發板,我要在開發板的I2C匯流排上增加一個從設備(如at24c08),那麼我要怎樣寫這個「I2C設備驅動」,讓

應用程序可以訪問at24c08呢?

先來看一個最簡單的i2c設備驅動:
static struct i2c_board_info at24cxx_info = { //所支持的i2c設備的列表
I2C_BOARD_INFO("at24c08", 0x50), //一項代表一個支持的設備,它的名字叫做「at24c08」,器件地址是0x50
};
static struct i2c_client *at24cxx_client;
static int at24cxx_dev_init(void)
{
struct i2c_adapter *i2c_adap; //分配一個適配器的指針
i2c_adap = i2c_get_adapter(0); //調用core層的函數,獲得一個i2c匯流排。這里我們已經知道新增的器件掛接在編號為0的i2c匯流排上
at24cxx_client = i2c_new_device(i2c_adap, &at24cxx_info); // 把i2c適配器和新增的I2C器件關聯起來,這個用了i2c匯流排0,地址是0x50。這就組成了一個客戶端
at24cxx_client i2c_put_adapter(i2c_adap);
return 0;
}
static void at24cxx_dev_exit(void)
{
i2c_unregister_device(at24cxx_client);
}
mole_init(at24cxx_dev_init);
mole_exit(at24cxx_dev_exit);

4. linux 下的I2C驅動怎麼管理多個相同的設備,設備地址不同

驅動程序可能不需要做太多工作。
三個設備接入系統之後,I2C匯流排會創建3個不同的Node,然後,你的驅動程序就會被載入。最後結果是,每個設備都有自己的驅動程序實例,互相之間不會有干擾和依賴。
參考:http://bbs.csdn.net/topics/390847077

5. linux i2c設備驅動移植問題 請大師們賜教啊

linux下驅動代碼分為兩個層次,一個是設備抽象,一個是真實設備
像i2c-dev.c屬於設備抽象,你沒有它,所有char設備的i2c機制都失效
像ad7417.c屬於真實設備,沒有它只是影響ad7417對應的具體設備。

所以你想使用ad7417的對應設備,這兩個文件必須都得有
i2c-dev.c是核心代碼,它的輸出產物是個k-object:
MODULE_DESCRIPTION("I2C /dev entries driver");

至於你的ad7417.c是否有用到i2c-dev.c的代碼,我就不知道了,如果有則需要聯編

6. 請教:linux 字元設備驅動IIC進不了中斷

如何編寫Linux設備驅動程序回想學習Linux操作系統已經有近一年的時間了,前前後後,零零碎碎的一路學習過來,也該試著寫的東西了。也算是給自己能留下一點記憶和回憶吧!由於完全是自學的,以下內容若有不當之處,還請大家多指教。Linux是Unix操作系統的一種變種,在Linux下編寫驅動程序的原理和思想完全類似於其他的Unix系統,但它dos或window環境下的驅動程序有很大的區別。在Linux環境下設計驅動程序,思想簡潔,操作方便,功能也很強大,但是支持函數少,只能依賴kernel中的函數,有些常用的操作要自己來編寫,而且調試也不方便。以下的一些文字主要來源於khg,johnsonm的Writelinuxdevicedriver,Brennan'sGuidetoInlineAssembly,TheLinuxA-Z,還有清華BBS上的有關devicedriver的一些資料。一、Linuxdevicedriver的概念系統調用是操作系統內核和應用程序之間的介面,設備驅動程序是操作系統內核和機器硬體之間的介面。設備驅動程序為應用程序屏蔽了硬體的細節,這樣在應用程序看來,硬體設備只是一個設備文件,應用程序可以象操作普通文件一樣對硬體設備進行操作。設備驅動程序是內核的一部分,它完成以下的功能:1、對設備初始化和釋放。2、把數據從內核傳送到硬體和從硬體讀取數據。3、讀取應用程序傳送給設備文件的數據和回送應用程序請求的數據。4、檢測和處理設備出現的錯誤。在Linux操作系統下有三類主要的設備文件類型,一是字元設備,二是塊設備,三是網路設備。字元設備和塊設備的主要區別是:在對字元設備發出讀/寫請求時,實際的硬體I/O一般就緊接著發生了,塊設備則不然,它利用一塊系統內存作緩沖區,當用戶進程對設備請求能滿足用戶的要求,就返回請求的數據,如果不能,就調用請求函數來進行實際的I/O操作。塊設備是主要針對磁碟等慢速設備設計的,以免耗費過多的CPU時間來等待。已經提到,用戶進程是通過設備文件來與實際的硬體打交道。每個設備文件都都有其文件屬性(c/b),表示是字元設備還是塊設備?另外每個文件都有兩個設備號,第一個是主設備號,標識驅動程序,第二個是從設備號,標識使用同一個設備驅動程序的不同的硬體設備,比如有兩個軟盤,就可以用從設備號來區分他們。設備文件的的主設備號必須與設備驅動程序在登記時申請的主設備號一致,否則用戶進程將無法訪問到驅動程序。最後必須提到的是,在用戶進程調用驅動程序時,系統進入核心態,這時不再是搶先式調度。也就是說,系統必須在你的驅動程序的子函數返回後才能進行其他的工作。如果你的驅動程序陷入死循環,不幸的是你只有重新啟動機器了,然後就是漫長的fsck。讀/寫時,它首先察看緩沖區的內容,如果緩沖區的數據未被處理,則先處理其中的內容。如何編寫Linux操作系統下的設備驅動程序二、實例剖析我們來寫一個最簡單的字元設備驅動程序。雖然它什麼也不做,但是通過它可以了解Linux的設備驅動程序的工作原理。把下面的C代碼輸入機器,你就會獲得一個真正的設備驅動程序。#define__NO_VERSION__#include#includecharkernel_version[]=UTS_RELEASE;這一段定義了一些版本信息,雖然用處不是很大,但也必不可少。Johnsonm說所有的驅動程序的開頭都要包含,一般來講最好使用。由於用戶進程是通過設備文件同硬體打交道,對設備文件的操作方式不外乎就是一些系統調用,如open,read,write,close…,注意,不是fopen,fread,但是如何把系統調用和驅動程序關聯起來呢?這需要了解一個非常關鍵的數據結構:structfile_operations{int(*seek)(structinode*,structfile*,off_t,int);int(*read)(structinode*,structfile*,char,int);int(*write)(structinode*,structfile*,off_t,int);int(*readdir)(structinode*,structfile*,structdirent*,int);int(*select)(structinode*,structfile*,int,select_table*);int(*ioctl)(structinode*,structfile*,unsinedint,unsignedlong);int(*mmap)(structinode*,structfile*,structvm_area_struct*);int(*open)(structinode*,structfile*);int(*release)(structinode*,structfile*);int(*fsync)(structinode*,structfile*);int(*fasync)(structinode*,structfile*,int);int(*check_media_change)(structinode*,structfile*);int(*revalidate)(dev_tdev);}這個結構的每一個成員的名字都對應著一個系統調用。用戶進程利用系統調用在對設備文件進行諸如read/write操作時,系統調用通過設備文件的主設備號找到相應的設備驅動程序,然後讀取這個數據結構相應的函數指針,接著把控制權交給該函數。這是linux的設備驅動程序工作的基本原理。既然是這樣,則編寫設備驅動程序的主要工作就是編寫子函數,並填充file_operations的各個域。下面就開始寫子程序。#include#include#include#include#include#includeunsignedinttest_major=0;staticintread_test(structinode*node,structfile*file,char*buf,intcount){intleft;if(verify_area(VERIFY_WRITE,buf,count)==-EFAULT)return-EFAULT;for(left=count;left>0;left--){__put_user(1,buf,1);buf++;}returncount;}這個函數是為read調用准備的。當調用read時,read_test()被調用,它把用戶的緩沖區全部寫1。buf是read調用的一個參數。它是用戶進程空間的一個地址。但是在read_test被調用時,系統進入核心態。所以不能使用buf這個地址,必須用__put_user(),這是kernel提供的一個函數,用於向用戶傳送數據。另外還有很多類似功能的函數。請參考Robert著的《Linux內核設計與實現》(第二版)。然而,在向用戶空間拷貝數據之前,必須驗證buf是否可用。這就用到函數verify_area。staticintwrite_tibet(structinode*inode,structfile*file,constchar*buf,intcount){returncount;}staticintopen_tibet(structinode*inode,structfile*file){MOD_INC_USE_COUNT;return0;}staticvoidrelease_tibet(structinode*inode,structfile*file){MOD_DEC_USE_COUNT;}這幾個函數都是空操作。實際調用發生時什麼也不做,他們僅僅為下面的結構提供函數指針。structfile_operationstest_fops={NULL,read_test,write_test,NULL,/*test_readdir*/NULL,NULL,/*test_ioctl*/NULL,/*test_mmap*/open_test,release_test,NULL,/*test_fsync*/NULL,/*test_fasync*//*nothingmore,fillwithNULLs*/};這樣,設備驅動程序的主體可以說是寫好了。現在要把驅動程序嵌入內核。驅動程序可以按照兩種方式編譯。一種是編譯進kernel,另一種是編譯成模塊(moles),如果編譯進內核的話,會增加內核的大小,還要改動內核的源文件,而且不能動態的卸載,不利於調試,所以推薦使用模塊方式。intinit_mole(void){intresult;result=register_chrdev(0,"test",&test_fops);if(result#include#include#includemain(){inttestdev;inti;charbuf[10];testdev=open("/dev/test",O_RDWR);if(testdev==-1){printf("Cann'topenfile\n");exit(0);}read(testdev,buf,10);for(i=0;i<10;i++)printf("%d\n",buf[i]);close(testdev);}編譯運行,看看是不是列印出全1?以上只是一個簡單的演示。真正實用的驅動程序要復雜的多,要處理如中斷,DMA,I/Oport等問題。這些才是真正的難點。請看下節,實際情況的處理。如何編寫Linux操作系統下的設備驅動程序三、設備驅動程序中的一些具體問題1。I/OPort。和硬體打交道離不開I/OPort,老的ISA設備經常是佔用實際的I/O埠,在linux下,操作系統沒有對I/O口屏蔽,也就是說,任何驅動程序都可對任意的I/O口操作,這樣就很容易引起混亂。每個驅動程序應該自己避免誤用埠。有兩個重要的kernel函數可以保證驅動程序做到這一點。1)check_region(intio_port,intoff_set)這個函數察看系統的I/O表,看是否有別的驅動程序佔用某一段I/O口。參數1:I/O埠的基地址,參數2:I/O埠佔用的范圍。返回值:0沒有佔用,非0,已經被佔用。2)request_region(intio_port,intoff_set,char*devname)如果這段I/O埠沒有被佔用,在我們的驅動程序中就可以使用它。在使用之前,必須向系統登記,以防止被其他程序佔用。登記後,在/proc/ioports文件中可以看到你登記的I/O口。參數1:io埠的基地址。參數2:io埠佔用的范圍。參數3:使用這段io地址的設備名。在對I/O口登記後,就可以放心地用inb(),outb()之類的函來訪問了。在一些pci設備中,I/O埠被映射到一段內存中去,要訪問這些埠就相當於訪問一段內存。經常性的,我們要獲得一塊內存的物理地址。2。內存操作在設備驅動程序中動態開辟內存,不是用malloc,而是kmalloc,或者用get_free_pages直接申請頁。釋放內存用的是kfree,或free_pages。請注意,kmalloc等函數返回的是物理地址!注意,kmalloc最大隻能開辟128k-16,16個位元組是被頁描述符結構佔用了。內存映射的I/O口,寄存器或者是硬體設備的RAM(如顯存)一般佔用F0000000以上的地址空間。在驅動程序中不能直接訪問,要通過kernel函數vremap獲得重新映射以後的地址。另外,很多硬體需要一塊比較大的連續內存用作DMA傳送。這塊程序需要一直駐留在內存,不能被交換到文件中去。但是kmalloc最多隻能開辟128k的內存。這可以通過犧牲一些系統內存的方法來解決。3。中斷處理同處理I/O埠一樣,要使用一個中斷,必須先向系統登記。intrequest_irq(unsignedintirq,void(*handle)(int,void*,structpt_regs*),unsignedintlongflags,constchar*device);irq:是要申請的中斷。handle:中斷處理函數指針。flags:SA_INTERRUPT請求一個快速中斷,0正常中斷。device:設備名。如果登記成功,返回0,這時在/proc/interrupts文件中可以看你請求的中斷。4。一些常見的問題。對硬體操作,有時時序很重要(關於時序的具體問題就要參考具體的設備晶元手冊啦!比如網卡晶元RTL8139)。但是如果用C語言寫一些低級的硬體操作的話,gcc往往會對你的程序進行優化,這樣時序會發生錯誤。如果用匯編寫呢,gcc同樣會對匯編代碼進行優化,除非用volatile關鍵字修飾。最保險的法是禁止優化。這當然只能對一部分你自己編寫的代碼。如果對所有的代碼都不優化,你會發現驅動程序根本無法裝載。這是因為在編譯驅動程序時要用到gcc的一些擴展特性,而這些擴展特性必須在加了優化選項之後才能體現出來。寫在後面:學習Linux確實不是一件容易的事情,因為要付出很多精力,也必須具備很好的C語言基礎;但是,學習Linux也是一件非常有趣的事情,它裡麵包含了許多高手的智慧和「幽默」,這些都需要自己親自動手才能體會到,O(∩_∩)O~哈哈!

7. linux i2c的設備和驅動是怎樣匹配的

linux下驅動代碼分為兩個層次,一個是設備抽象,一個是真實設備
像i2c-dev.c屬於設備抽象,你沒有它,所有char設備的i2c機制都失效
像ad7417.c屬於真實設備,沒有它只是影響ad7417對應的具體設備。
所以你想使用ad7417的對應設備,這兩個文件必...

8. Linux系統IIC驅動的設計與開發,這個是讓我寫驅動程序嗎

是的,具體要看你是用自帶的IIC單元還是用IO口模擬IIC了。

9. 如何在linux下實現一個I2C與SPI的從機驅動

最簡情況下:
I2C:SDA數據線、SCL時鍾線。
SPI:DI輸入線、DO輸出線、CS片選先、CLK時鍾線。
可能不能寫到一個驅動中。

但是好在一般很少用到這么簡單的情況,廠家會對其擴展和改進。

比如 W25Q128FB/W25R128FV 系列快閃記憶體,支持 SPI、Dual SPI、Quad SPI 和 QPI。就拿 Quad SPI 來說,有 6 個引腳:

Quad SPI:D0-D3 輸入輸出線、CS片選先、CLK時鍾線。

其中 輸入為一位串列輸入 D0,輸出為四位串列輸出 D0-D3。(四位仍少於一個位元組,可姑且稱為串列)

Winbond華邦 這么做是為了加快快閃記憶體讀取速度(四位串列相比一位串列提高了四倍)。

因此關鍵在於 要進行怎樣的 IO。至於是否將二者寫到一個驅動看來並不重要。

10. linux i2c驅動怎麼寫

1、使用linux系統i2c體系,包括設備驅動,匯流排驅動,一般匯流排驅動已經寫好了,需要你寫一個設備驅動
2、使用gpio模擬i2c協議
3、望採納
4、謝謝

熱點內容
k線公式源碼 發布:2024-11-09 00:35:24 瀏覽:784
國際編程大賽 發布:2024-11-09 00:35:23 瀏覽:856
全志編譯內核驅動 發布:2024-11-09 00:30:59 瀏覽:55
phpphpfpm 發布:2024-11-09 00:27:54 瀏覽:981
機車新手怎麼看配置 發布:2024-11-09 00:12:20 瀏覽:193
關鍵行動安卓如何下載 發布:2024-11-08 23:56:59 瀏覽:59
大便壓縮小 發布:2024-11-08 23:52:37 瀏覽:293
墨刀資料庫 發布:2024-11-08 23:51:10 瀏覽:307
javaget亂碼 發布:2024-11-08 23:41:56 瀏覽:82
空文件python 發布:2024-11-08 23:38:08 瀏覽:488