Linux標頭檔案中s3c2410 GPIO的巨集

2021-06-06 10:51:06 字數 4124 閱讀 9356

一、gpio暫存器定義

1.#define gpcon(x)   __reg2(0x56000000, (x) * 0x10)

gpcon(1) ------ port a  0x56000000

gpcon(2) ------ port b  0x56000010

gpcon(3) ------ port c  0x56000020

……gpcon(8) ------ port h  0x56000070

2.#define gpdat(x)   __reg2(0x56000004, (x) * 0x10)

這句是定義2410的gpio的資料暫存器,定義方法同gpcon巨集。

gpdat(1) ------ port a  0x56000004

gpdat(2) ------ port b  0x56000014

gpdat(3) ------ port c  0x56000024

……gpdat(8) ------ port h  0x56000074

3.#define gpup(x)      __reg2(0x56000008, (x) * 0x10)

這句是定義2410的gpio的上拉電阻遮蔽/啟用暫存器,定義方法同gpcon巨集。

gpup(1) ------ port a  0x56000008

gpup(2) ------ port b  0x56000018

gpup(3) ------ port c  0x56000028

……gpup(8) ------ port h  0x56000078

二、gpio埠號定義

以gpio_g12來說明在核心標頭檔案$(kernel_include)/asm-arm/arch/s3c2410.h中是如何來定義io port的埠號的。定義gpio埠主要涉及到以下幾個巨集:

#define make_gpio_num(p, o)         ( (p << gpio_port_shiftt) |  (o << gpio_ofs_shift))

#define gpio_g12               make_gpio_num(portg_ofs, 12)

gpio_port_shiftt值為8,代表gpio組號在整個gpio埠號(如gpio_g12)欄位中的位移

gpio_ofs_shift值為0,代表gpio組內偏移號在整個gpio埠號(如gpio_g12)欄位中的位移

s3c2410有117個多功能input/output port pins。分為以下八組:

— port a (gpa): 23-output port                    #define porta_ofs                 0

— port b (gpb): 11-input/output port         #define portb_ofs                 1

— port c (gpc): 16-input/output port        #define portc_ofs                 2

— port d (gpd): 16-input/output port        #define portd_ofs                 3

— port e (gpe): 16-input/output port         #define porte_ofs                 4

— port f (gpf): 8-input/output port            #define portf_ofs                 5

— port g (gpg): 16-input/output port         #define portg_ofs                6

— port h (gph): 11-input/output port         #define porth_ofs                7 

gpg12屬於g組,組內偏移為12,從上述兩個巨集定義中,我們可以很清楚地看出gpio_g12結構:

圖1  gpio埠號結構圖

埠一共有8組,從上面的巨集定義可以看出,埠組號p的範圍:0~7。而組內偏移各組不盡相同,port a有23個輸出口,因此它的組內偏移o為0~22,port g有16個io口,它的組內偏移o為0~15,其他組的gpio以此類推。

三、write_gpio_bit(x,v)巨集分析

write_gpio_bit巨集傳入兩個引數,第乙個為gpio埠號,如gpio_g12;第二個引數為1或0,為相應io口設定高電平或低電平輸出。具體巨集展開如下:**

#define write_gpio_bit(x, v) 

()  

grab_port巨集的引數是gpio埠號,功能是從gpio埠號中解析出組號,具體定義如下:

#define grab_port(x)              (((x) & gpio_port_mask) >> gpio_port_shiftt)

其中gpio_port_mask是組號的掩碼,值為0x0000ff00,從圖1中也可看出。

grab_ofs巨集和grab_port類似,它的功能是從gpio埠號中解析出組內偏移:

#define grab_ofs(x)            (((x) & gpio_ofs_mask) >> gpio_ofs_shift)

其中偏移值掩碼gpio_ofs_mask=0x000000ff。

現在我們結合上述說明來分析write_gpio_bit(gpio_g12,1)這條語句:由gpio_g12的巨集定義可計算出其值為0x0000060c,grab_port(gpio_g12)解析得到所操作的io屬於g組,組號為6;grab_ofs(gpio_g12)解析得到此io口為g組的第12個引腳(從0開始算起),為gpg12,表示式值為12。則write_gpio_bit(gpio_g12,1)等價於下面兩條語句:

gpdat(6) &= ~(0x1<<12);  //gpgdat暫存器第12位清零

gpdat(6) | = 1<<12;       // 向gpgdat暫存器第12位寫入『1』

到此,我們知道了write_gpio_bit(gpio_g12,1)這條語句是將gpg12這個引腳拉成高電平。

四、set_gpio_ctrl(x)巨集分析完成了對write_gpio_bit巨集的分析,現在來看set_gpio_ctrl就很簡單了!在它的巨集展開中只多了grab_mode(x)和 grab_pullup(x)分別表示從引數x中解析出io口的模式和使能/遮蔽此埠的上拉電阻。值得注意的是set_gpio_ctrl的引數x不僅僅表示gpio埠號,其高16位還帶有模式狀態和上拉電阻控制資訊,引數x的結構如下圖:

圖2 set_gpio_ctrl的引數字段結構圖

低16位即為前面所述的gpio的埠號,高16位中的r欄位用來遮蔽/使能io口的上拉電阻功能。r=0,上拉電阻使能;r=1,上拉電阻失效。m欄位用來設定io口的工作模式,m=0,io口為輸入埠;m=1,io口為輸出埠;m=2,可選功能1;m=3,可選功能2。

set_gpio_ctrl巨集就是通過寫相應gpio所在組的gpxcon(x為a~h)的相應位來設定io口模式(gpacon每乙個位控制乙個io口,而gpbcon~gphcon都是兩個位控制乙個io口的模式),通過寫gpxup(x為a~h)來決定是否啟用上拉電阻。典型的set_gpio_ctrl呼叫方式如下:

set_gpio_ctrl(gpio_mode_out | gpio_pullup_dis | gpio_g12); **

#define set_gpio_ctrl(x) 

()  

這條語句是將gpg12設定成輸出模式,並且不使用埠的上拉電阻。

五、結束

以上主要結合《s3c2410x 32-bit risc microprocessor user's manual》分析了$(linux_kernel_include)/asm-arm/arch/s3c2410.h中所定義的對2410gpio進行操作的幾個巨集,除了文中提及的幾個巨集,除此還有read_gpio_bit(x)、read_gpio_reg(x) 、write_gpio_reg(x, v)等,實現方法和上述類似,在此不再一一贅述!

c 中algorithm標頭檔案

包含了stl中的許多泛型演算法 可以呼叫一些函式,如 int count i being,i end,t x 使用非自己定義的泛型演算法,則要包含該標頭檔案,裡面定義了一些泛型演算法,比如說排序之類的stl的演算法部分,裡邊定義了各種演算法,比如sort之類的。加上algorithm就可以使用stl...

C 中的標頭檔案

通常每乙個.cpp檔案都有乙個對應的.h檔案,但是也有例外如main函式所在的.cpp檔案。c 標準庫中除了定義c 語言特有的功能外,還相容了c語言的標準庫。c語言的標頭檔案形如 name.h,而c 中將這些檔案命名為cname,去掉了.h字尾,在前面新增了字母c,c的含義表示這是乙個屬於c語言標準...

C 中的標頭檔案

標頭檔案的字尾在c 的不同實現中是不同,所以標準c 也沒指定標頭檔案字尾,c 的標頭檔案包含一般不指明字尾,例如 include 而在c語言中.h是指定的標頭檔案字尾 如果你直接 include 將直接應用c的標頭檔案庫的指定檔案,這個時候你可以直接使用對應的檔案中的函式等,而如果使用了 inclu...