国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

書白的個(gè)人空間 http://www.qingdxww.cn/space-uid-134862.html [收藏] [復(fù)制] [RSS]

博客

學(xué)習(xí)嵌入式-迅為4412開發(fā)板的GPIO是怎么操作的?

已有 1690 次閱讀2017-4-11 10:30 |個(gè)人分類:4412| 嵌入式開發(fā)板, 迅為開發(fā)板, 4412開發(fā)板

Exynos4412所有的GPIO都有固定的地址,為了方便操作這些GPIO,Linux內(nèi)核在gpio-exynos4.h里面定義了一些GPIO的宏

詳情了解:http://topeetboard.com 更多了解:https://arm-board.taobao.com

例如: 
#define EXYNOS4_GPA0(_nr) (EXYNOS4_GPIO_A0_START + (_nr)) 
#define EXYNOS4_GPA1(_nr) (EXYNOS4_GPIO_A1_START + (_nr)) 
#define EXYNOS4_GPB(_nr) (EXYNOS4_GPIO_B_START + (_nr)) 
..................................... 
#define EXYNOS4_GPY5(_nr) (EXYNOS4_GPIO_Y5_START + (_nr)) 
#define EXYNOS4_GPY6(_nr) (EXYNOS4_GPIO_Y6_START + (_nr)) 
#define EXYNOS4_GPZ(_nr) (EXYNOS4_GPIO_Z_START + (_nr)) 
這些宏就是把每個(gè)GPIO的地址做了一下封裝,它的好處就是方便我們使用并且根據(jù)宏的名字就能直觀的知道是在操作哪個(gè)GPIO。 
Linux內(nèi)核中關(guān)于GPIO的驅(qū)動(dòng)在driver/gpio/gpio-exynos4.c文件里面,在這個(gè)文件中GPIO驅(qū)動(dòng)初始化入口函數(shù)是exynos4_gpiolib_init,因?yàn)檫@個(gè)文件同時(shí)也支持4210的GPIO,所以開始先初始化了一些通用的GPIO(4412和4210都有的GPIO),代碼如下: 
chip = exynos4_gpio_common_4bit; 
nr_chips = ARRAY_SIZE(exynos4_gpio_common_4bit); 
for (i = 0; i < nr_chips; i++, chip++) { 
if (chip->config == NULL) 
chip->config = &gpio_cfg; 
if (chip->base == NULL) 
pr_err("No allocation of base address for [common gpio]"); 

samsung_gpiolib_add_4bit_chips(exynos4_gpio_common_4bit, nr_chips); 
變量exynos4_gpio_common_4bit是一個(gè)數(shù)組,定義了一些通用的GPIO,nr_chips是記錄的exynos4_gpio_common_4bit數(shù)組里面元素個(gè)數(shù)。 
首先使用for循環(huán)遍歷exynos4_gpio_common_4bit所有的元素,為每個(gè)元素的config結(jié)構(gòu)賦值: 
if (chip->config == NULL) 
chip->config = &gpio_cfg; 
gpio_cfg是類型為s3c_gpio_cfg的結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體的定義如下: 
struct s3c_gpio_cfg { 
unsigned int cfg_eint; 
s3c_gpio_pull_t (*get_pull)(struct s3c_gpio_chip *chip, unsigned offs); 
int (*set_pull)(struct s3c_gpio_chip *chip, unsigned offs, 
s3c_gpio_pull_t pull); 
unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs); 
int (*set_config)(struct s3c_gpio_chip *chip, unsigned offs, 
unsigned config); 
}; 
通過上面的代碼我們可以看到這個(gè)結(jié)構(gòu)體里主要是一些函數(shù)指針,get_pull是獲取GPIO的上拉狀態(tài),set_pull是設(shè)置GPIO上拉或下拉的,set_config是設(shè)置GPIO的工作模式,例如:輸出/輸入/其他功能。下面我們來看看gpio_cfg變量的定義,如下: 
static struct s3c_gpio_cfg gpio_cfg = { 
.set_config = s3c_gpio_setcfg_s3c64xx_4bit, 
.set_pull = s3c_gpio_setpull_exynos4, 
.get_pull = s3c_gpio_getpull_exynos4, 
}; 
通過上面的代碼,可以看到分別對gpio_cfg結(jié)構(gòu)的三個(gè)函數(shù)指針賦值,這三個(gè)函數(shù)的定義是在gpio-config.c里面實(shí)現(xiàn)的,這個(gè)文件在內(nèi)核源碼arch/arm/plat-samsung目錄下,這三個(gè)函數(shù)的作用就是根據(jù)傳進(jìn)來的參數(shù),配置GPIO相應(yīng)的寄存器,從而實(shí)現(xiàn)對GPIO的操作。 
然后我們回到gpio-exynos4.c,接著看下面的代碼,完成了exynos4_gpio_common_4bit中每個(gè)元素的config結(jié)構(gòu)賦值后,接著會(huì)調(diào)用函數(shù)samsung_gpiolib_add_4bit_chips(exynos4_gpio_common_4bit, 
nr_chips)來向系統(tǒng)注冊GPIO結(jié)構(gòu)體。代碼如下: 
void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip, 
int nr_chips) 

for (; nr_chips > 0; nr_chips--, chip++) { 
samsung_gpiolib_add_4bit(chip); 
s3c_gpiolib_add(chip); 


上面的代碼主要有兩個(gè)函數(shù)組成分別是samsung_gpiolib_add_4bit(chip)和s3c_gpiolib_add(chip),首先我們來看下samsung_gpiolib_add_4bit(chip)函數(shù)的實(shí)現(xiàn): 
void __init samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip) 

chip->chip.direction_input = samsung_gpiolib_4bit_input; 
chip->chip.direction_output = samsung_gpiolib_4bit_output; 
chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); 

這個(gè)函數(shù)也是為函數(shù)指針賦值,direction_input是設(shè)置GPIO為輸入模式,direction_output是設(shè)置GPIO為輸出。 
s3c_gpiolib_add(chip)函數(shù)主要作用是給一些函數(shù)指針賦值,然后根據(jù)傳進(jìn)來的參數(shù)把對應(yīng)的GPIO的信息保存到gpio_desc結(jié)構(gòu)里,gpio_desc是內(nèi)核里面定義的一個(gè)全局變量,用來保存每個(gè)GPIO的信息。至此GPIO的驅(qū)動(dòng)初始化就完成了,其他它主要完成的功能就是為每個(gè)GPIO的結(jié)構(gòu)體里面的函數(shù)指針賦值,最后把每個(gè)GPIO結(jié)構(gòu)信息保存到全局變量gpio_desc里面。
上面已經(jīng)完成了一些通用的GPIO驅(qū)動(dòng)的初始化,我們在回到gpio-exynos4.c,下面是根據(jù)CPU的型號(hào)初始化CPU特定的GPIO了,代碼如下: 
/* Only 4210 GPIO part */ 
if (soc_is_exynos4210()) { 
chip = exynos4210_gpio_4bit; 
nr_chips = ARRAY_SIZE(exynos4210_gpio_4bit); 
for (i = 0; i < nr_chips; i++, chip++) { 
if (chip->config == NULL) 
chip->config = &gpio_cfg; 
if (chip->base == NULL) 
pr_err("No allocation of base address [4210 gpio]"); 

samsung_gpiolib_add_4bit_chips(exynos4210_gpio_4bit, nr_chips); 
} else { 
/* Only 4212/4412 GPIO part */ 
chip = exynos4212_gpio_4bit; 
nr_chips = ARRAY_SIZE(exynos4212_gpio_4bit); 
for (i = 0; i < nr_chips; i++, chip++) { 
if (chip->config == NULL) 
chip->config = &gpio_cfg; 
if (chip->base == NULL) 
pr_err("No allocation of base address [4212 gpio]"); 

samsung_gpiolib_add_4bit_chips(exynos4212_gpio_4bit, nr_chips); 

通過看上面的代碼,初始化過程與前面介紹的初始化通用GPIO原理是一樣的,這里我們不在詳細(xì)介紹。對所有GPIO的初始化完成以后內(nèi)核中的其他驅(qū)動(dòng)模塊就可以方便的使用我們注冊到gpio_desc里面的GPIO了。內(nèi)核提供了幾個(gè)全局函數(shù)來操作這些GPIO: 
int gpio_request(unsigned gpio, const char *label) 
void gpio_free(unsigned gpio) 
int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) 
int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) 
int gpio_direction_input(unsigned gpio) 
int gpio_direction_output(unsigned gpio, int value) 
gpio_request函數(shù)是申請GPIO操作,根據(jù)傳遞進(jìn)來的參數(shù)gpio,會(huì)去全局變量gpio_desc里面找到對應(yīng)的GPIO結(jié)構(gòu),判斷desc的標(biāo)志位flag有沒有被設(shè)置FLAG_REQUESTED,如果有設(shè)置說明其他地方在使用這個(gè)GPIO,程序返回-EBUSY錯(cuò)誤,如果沒有設(shè)置就設(shè)置flags的標(biāo)記為FLAG_REQUESTED。 
gpio_free函數(shù)是釋放GPIO操作,根據(jù)傳遞進(jìn)來的參數(shù),在gpio_desc全局變量找到對應(yīng)的GPIO結(jié)構(gòu),清除掉desc的flag標(biāo)志變量的FLAG_REQUESTED位。 
s3c_gpio_setpull函數(shù)是設(shè)置GPIO的上拉或下拉的,變量pull的取值范圍如下定義: 
#define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00) 
#define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01) 
#define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x02) 
S3C_GPIO_PULL_NONE是懸空 
S3C_GPIO_PULL_DOWN是下拉 
S3C_GPIO_PULL_UP是上拉 
s3c_gpio_cfgpin函數(shù)是設(shè)置GPIO的功能:輸入/輸出/其他功能,第二個(gè)參數(shù)config取值范圍如下: 
#define S3C_GPIO_INPUT (S3C_GPIO_SPECIAL(0)) 
#define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1)) 
#define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x)) 
S3C_GPIO_INPUT是輸入模式,S3C_GPIO_OUTPUT是輸出模式,S3C_GPIO_SFN(x)是其他模式,例如中斷模式等。 
gpio_direction_input函數(shù)設(shè)置GPIO是輸入功能。 
gpio_direction_output設(shè)置GPIO輸出,第二個(gè)參數(shù)value取值0或1,0代表輸出低電平,1代表輸出高電平。 
下面我們來看幾個(gè)GPIO操作的例子: 
if (gpio_request(EXYNOS4_GPX3(3), "MPU6050 INT")) 
printk(KERN_WARNING "MPU6050 INT(GPX3.3) Port request error!!!\n"); 
else{ 
s3c_gpio_setpull(EXYNOS4_GPX3(3), S3C_GPIO_PULL_NONE); 
s3c_gpio_cfgpin(EXYNOS4_GPX3(3), S3C_GPIO_SFN(0)); 
gpio_direction_input(EXYNOS4_GPX3(3)); 
gpio_free(EXYNOS4_GPX3(3)); 

上面的代碼是設(shè)置GPIO引腳GPX3_3為輸入模式,懸空。 
err = gpio_request_one(EXYNOS4_GPX0(0), GPIOF_IN, "mcp251x_INT"); 
if (err) { 
printk(KERN_ERR "failed to request mcp251x_INT\n"); 
return -1; 

s3c_gpio_cfgpin(EXYNOS4_GPX0(0), S3C_GPIO_SFN(0xf)); 
s3c_gpio_setpull(EXYNOS4_GPX0(0), S3C_GPIO_PULL_NONE); 
gpio_free(EXYNOS4_GPX0(0)); 
上面的代碼設(shè)置GPIO引腳GPX0_0為中斷模式。 
if(gpio_request(EXYNOS4_GPK1(0), "GPK1_0")) 

printk(KERN_ERR "failed to request GPK1_0 for " 
"USI control\n"); 
return err; 

gpio_direction_output(EXYNOS4_GPK1(0), 1); 
s3c_gpio_cfgpin(EXYNOS4_GPK1(0), S3C_GPIO_OUTPUT); 
gpio_free(EXYNOS4_GPK1(0)); 
上面的代碼設(shè)置GPIO引腳GPK1_0為輸出模式,并且輸出高電平。 
iTOP-4412的GPIO驅(qū)動(dòng)就介紹到這里,大家有興趣的話可以去內(nèi)核里面詳細(xì)的查看一下整個(gè)驅(qū)動(dòng)的詳細(xì)實(shí)現(xiàn)。


路過

雞蛋

鮮花

握手

雷人

評(píng)論 (0 個(gè)評(píng)論)

facelist

您需要登錄后才可以評(píng)論 登錄 | 立即注冊

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號(hào) | 京公網(wǎng)安備11010502021702
返回頂部
主站蜘蛛池模板: 今野由爱毛片在线播放 | h日本动漫无删减在线观看免 | 欧美成人精品在线 | 欧美乱妇高清无乱码视频在线 | 青青操免费| 4438x全国最大成人网 | 午夜久久久久久网站 | 国产精品嫩草影院在线看 | 欧美日本免费 | 色狠狠一区二区三区香蕉蜜桃 | 国产精品自拍第一页 | 好莱污下载 | 69av视频| 欧美一区二区三区高清不卡tv | 国产在线综合一区二区三区 | 一区免费| 日本成人免费在线视频 | 高h全肉动漫在线观看免费 高h大街上羞耻露出调教 | 国产啪爱视频精品免视 | 欧美成人 一区二区三区 | 国产欧美精品区一区二区三区 | haodiaokan| 王者荣耀之白丝玉足榨精 | 麻豆小视频 | 日韩免费视频一区 | 亚洲天堂999 | 国产理论自拍 | 国产人成精品综合欧美成人 | 落跑甜心电视剧全集免费观看在线 | 国产欧美日韩精品a在线观看 | 在线视频日本 | 狠狠亚洲丁香综合久久 | 成年人午夜视频 | 91精品国产综合久 | 久九九久福利精品视频视频 | 欧美精品区 | 国产特级全黄一级毛片不卡 | 香蕉久久成人网 | 色老二精品视频在线观看 | 亚洲第一天堂网 | 国产福利在线观看 |