【linux】驅動-4-LED晶片手冊分析

李柱明發表於2021-03-28


前言

4. LED晶片手冊分析

本章節記錄實現LED暫存器配置,晶片手冊分析。

4.1 記憶體管理單元MMU

簡單介紹一下MMU。

4.1.1 MMU的功能

功能:

  • 虛擬地址翻譯為實體地址
  • 管理、保護記憶體。

不同的程式有各自的虛擬地址空間,某個程式中的程式不能修改另外一個程式所使用的實體地址,以此使得程式之間互不干擾,相互隔離。

作用:
* 保護記憶體:MMU給一些指定的記憶體設定了讀寫許可權。存在於頁表中。當有程式操作該記憶體時,MMU會查詢頁表中的許可權繼續匹配。
* 實現虛擬地址到實體地址的轉換:CPU可以執行在虛擬的記憶體當中,虛擬記憶體一般要比實際記憶體大很多,使得CPU可以執行比較大的應用程式。(原理可百度

4.1.2 TLB的作用

TLB(Translation Lookaside Buffer)。

問題:當只有一級頁表進行地址轉換的時候,CPU每次讀寫資料都需要訪問兩次記憶體, 第一次是訪問記憶體中的頁表,第二次是根據頁表找到真正需要讀寫資料的記憶體地址; 如果使用兩級了表,那麼CPU每次讀寫資料都需要訪問3次記憶體。。。這樣就很繁瑣。
解決:MMU最先訪問TLB,假設TLB中包含可以直接轉換此虛擬地址的地址描述符, 則會直接使用這個地址描述符檢查許可權和地址轉換,如果TLB中沒有這個地址描述符, MMU才會去訪問頁表並找到地址描述符之後進行許可權檢查和地址轉換, 然後再將這個描述符填入到TLB中以便下次使用。

4.2 地址轉換函式

對映函式:ioremap()
取消對映函式:iounmap()

4.2.1 ioremap函式

函式原型:void __iomem *ioremap(phys_addr_t paddr, unsigned long size)

  • 引數:
    • paddr:被對映的 IO 起始地址(實體地址)。
    • size:需要對映的空間大小,以位元組為單位。
  • 返回值:
    • 一個指向 __iomem 型別的指標,當對映成功後便返回一段虛擬地址空間的起始地址。

通過返回的虛擬空間起始地址可以對記憶體進行讀寫。為了提高平臺的可移植性,建議使用以下讀寫函式:

unsigned int ioread8(void __iomem *addr)
unsigned int ioread16(void __iomem *addr)
unsigned int ioread32(void __iomem *addr)

void iowrite8(u8 b, void __iomem *addr)
void iowrite16(u16 b, void __iomem *addr)
void iowrite32(u32 b, void __iomem *addr)

與以上函式相似的函式:writeb、writew、writel、readb、readw、readl
注意:其中 writexiowritex 的區別是,writex 不進行端序檢查。

4.2.2 iounmap函式

函式原型:void iounmap(void *addr)

  • 引數:
    • addr:需要取消 ioremap 對映之後的起始地址(虛擬地址)。

4.3 LED驅動

已知:

  • 以 IMX6 為例。
  • RGB引腳分別為 GPIO1_IO04、GPIO4_IO20、GPIO4_19
    簡要步驟:
  1. 檢視原理圖,分析出 LED 是低電平亮還是高電平亮。找出對應的 GPIO
  2. GPIO 暫存器進行操作:(暫存器表在 《IMX6ULLRM(6ULL使用者手冊).pdf》 中查詢)
    1. 使能時鐘:使能 GPIO 對應的時鐘;
    2. 引腳複用:設定引腳複用為 GPIO
    3. 引腳屬性:配置引腳屬性(上下拉、速率、驅動能力);
    4. 控制引腳:控制GPIO引腳,輸出高低電平。
  3. 分層、分離:
    1. 上層為系統,模組的出入口函式。
    2. 下層為硬體:分離:
      1. 各種板卡, 提供不同的引腳資料。
      2. 驅動實現。

4.3.1 配置GPIO時鐘

暫存器表在 《IMX6ULLRM(6ULL使用者手冊).pdf》 中查詢。

由圖可知,GPIO1 的時鐘是由暫存器 CCM_CCGR1 中的 [27-26] bit控制。
該暫存器地址為:Address: 20C_4000h base + 6Ch offset = 20C_406Ch

暫存器值配置參考上圖。
使能 GPIO1時鐘:暫存器 CCM_CCGR1 中的 [27-26] bit 配置為 [27-26]: 0b11

4.3.2 配置引腳複用

配置引腳複用為 GPIO
檢視手冊 IOMUX 章節。

由上圖可以看出,暫存器 IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO04 [3-0] 設定為 0b0101 時。GPIO1_IO04 就配置為 GPIO1 模式。

4.3.3 引腳屬性

配置引腳屬性。

由上圖得,暫存器為 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO04。地址為 Address: 20E_0000h base + 2F8h offset = 20E_02F8h
分析:

  • HYS(bit16):用來使能遲滯比較器 。
  • PUS(bit15-bit14):用來設定上下拉電阻大小。
  • PUE(bit13):當 IO 作為輸入的時候,這個位用來設定 IO 使用上下拉還是狀態保持器。
  • PKE(bit12):用來使能或者禁止上下拉/狀態保持器功能。
  • ODE(bit11):IO 作為輸出的時候,此位用來禁止或者使能開漏輸出。
  • SPEED(bit7-bit6):當 IO 用作輸出的時候,此位用來設定 IO 速度。
  • DSE(bit5-bit3):當 IO 用作輸出的時候用來設定 IO 的驅動能力。
  • SRE(bit0):設定壓擺率。

把該暫存器配置為:0x1F838,即為 1 1111 1000 0011 1000

4.3.4 引腳控制

參考 《IMX6ULLRM(6ULL使用者手冊).pdf》 中的 28.5 GPIO Memory Map/Register Definition 章節。

控制引腳輸入還是輸出。

由上圖可知,GPIO1的資料基地址為 Base address = 0x0209C000
GPIOx_GDIR 地址為 Base address + 4h = 0x0209C004

輸出高低電平。

地址為 Base address = 0x0209C000
當該引腳配置為 GPIO OUTPUT MODE 時,即可通過設定該引腳來輸出高低電平。
同時,該引腳在 GPIO 模式時,不管 OUTPUT 還是 INPUT。都可以通過讀該暫存器值來判斷該引腳的高低電平。

相關文章