i.MX6 裸機 彙編 | LED燈硬體原理分析

“逛丟一隻鞋”發表於2020-11-16


本人原使用平臺為STM32F407,對於i.MX6平臺的使用,通過STM32的對照來進行學習。

有了Linux為什麼還需要寫彙編?

首先是帶來一個疑問,既然平臺使用i.MX6,有了Liunx作業系統,按理來說我們應該更多的精力放在上層的設計。

我們在學習 STM32的時候幾乎沒有用到過彙編,可能在學習 UCOS、 FreeRTOS等 RTOS類作業系統移植的時候可能會接觸到一點彙編。

但是我們在進行嵌入式 Linux開發的時候是絕對要掌握基本的 ARM彙編,因為 Cortex-A晶片一上電 SP指標還沒初始化, C環境還沒準備好,所以肯定不能執行 C程式碼,必須先用匯編語言設定好 C環境,比如初始化 DDR、設定 SP指標等等,當彙編把 C環境設定好了以後才可以執行 C程式碼。

所以 Cortex-A一開始肯定是彙編程式碼,其實 STM32也一樣的,一開始也是彙編,以 STM32F103為例,啟動檔案startup_stm32f10x_hd.s就是彙編檔案,只是這個檔案 ST已經寫好了,我們根本不用去修改,所以大部分學習者都沒有深入的去研究。

對於 Cortex-A晶片來講,大部分晶片在上電以後 C語言環境還沒準備好,所以第一行程式肯定是彙編的,至於要寫多少彙編程式,那就看你能在哪一步把 C語言環境準備好。

所謂的 C語言環境就是保證 C語言能夠正常執行。 C語言中的函式呼叫涉及到出棧入棧,出棧入棧就要對堆疊進行操作,所謂的堆疊其實就是 一段記憶體,這段記憶體比較特殊,由 SP指標訪問, SP指標指向棧頂。

晶片一上電 SP指標還沒有初始化,所以 C語言沒法執行,對於有些晶片還需要初始化 DDR,因為晶片本身沒有 RAM,或者內部 RAM不開放給使用者使用,使用者程式碼需要在DDR中執行,因此一開始要用匯編來初始化 DDR控制器。後面學習 Uboot和 Linux 核心的時候彙編是必須要會的。

STM32 IO初始化流程

  • 使能GPIO時鐘
  • 設定IO複用,將其複用為GPIO
  • 配置GPIO的電氣屬性
  • 使用GPIO,輸出高/低電平

I.MX6Q IO初始化流程

使能時鐘

  • 使能時鐘,CCGRO-CCGR6這7個暫存器控制著所有外設的使能, 為了簡單,設定CCGRO-CCGR6這7個暫存器全部為0xFFFFFFFF,相當於使能所有外設時鐘。

在這裡插入圖片描述

IO複用

IO命名

STM32中的 IO都是 PA0~15、 PB0~15這樣命名的, I.MX6U的 IO是怎麼命名的呢?開啟I.MX6UL參考手冊的“IOMUX Controller(IOMUXC)”,如圖
在這裡插入圖片描述
圖中的形如“ IOMUXC_SW_MUC_CTL_PAD_GPIO1_IO00”的就是 GPIO命名,命
名形式就是“ IOMUXC_SW_MUC_CTL_PAD_XX_XX”,後面的 XX_XX”就是 GPIO命名,比如: GPIO1_IO01、 UART1_TX_DATA、 JTAG_MOD、 SNVS_TAMPER1等等。 I.MX6U的 GPIO並不像 STM32一樣以 PA0~15這樣命名,他是根據某個 IO所擁有的功能來命名的。比如我們一看到 GPIO1_IO01就知道這個肯定能做 GPIO,看到 UART1_TX_DATA肯定就知道這個 IO肯定能做為 UART1的傳送引腳。“ IOMUX Controller(IOMUXC)”這一章列出了I.MX6U的所有 IO,如果你找遍第 30章的書籤,你會發現貌似 GPIO只有GPIO1_IO00~GPIO1_IO09,難道 I.MX6U的 GPIO只有這 10個?

顯然不是的, 我們知道 STM32的很多 IO是可以複用為其它功能的,那麼 I.MX6U的其它 IO也是可以複用為 GPIO功能。同樣的,GPIO1_IO00~GPIO_IO09也是可以複用為其它外設引腳的,接下來就是 I.MX6U IO複用。

IO複用

  • IO複用,將暫存器IOMUXC_SW_MUX_CTL_PAD_GPIO03的bit2-0設定為 101 = 5,這樣IO口就複用為GPIO1_IO03。

在這裡插入圖片描述
"IOMUX Controller(IOMUXC)”的書籤中,每一個 IO會出現兩次,它們的名字差別很小,不仔細看就看不出來,比如 GPIO1_IO00有如下兩個書籤:

在這裡插入圖片描述

電氣屬性

電氣屬性

  • 電器屬性,暫存器IOMUXC_SW_PAD_CTL_PAD_GPIO03.

    這也是個 32位暫存器,但是隻用到了其中的低 17位,在看這寫位的具體含義之前,先來看一下圖 8.1.4.2所示的 GPIO功能圖:

在這裡插入圖片描述

GPIO功能圖:

在這裡插入圖片描述
HYS(bit16):對應圖中 HYS,用來使能遲滯比較器,當 IO作為輸入功能的時候有效,用於設定輸入接收器的施密特觸發器是否使能。如果需要對輸入波形進行整形的話可以使能此位。此位為 0的時候禁止遲滯比較器,為 1的時候使能遲滯比較器。PUS(bit15: 對應圖中的 PUS,用來設定上下拉電阻的,一共有四種選項可以 選擇,如表所示:

在這裡插入圖片描述
PUE( 圖沒有給出來,當 IO作為輸入的時候,這個位用來設定 IO使用上下拉還是狀態保持器。當為 0的時候使用狀態保持器,當為 1的時候使用上下拉。狀態保持器在IO作為輸入的時候才有用,顧名思義,就是當外部電路斷電以後此 IO口可以保持住以前的狀態。

PKE( 對應圖中的 PKE,此為用來使能或者禁止上下拉 /狀態保持器功能,為0時禁止上下拉 /狀態保持器,為 1時使能上下拉和狀態保持器。ODE(bit11):對應圖中的 ODE,當 IO作為輸出的時候,此位用來禁止或者使能開路輸出,此位為 0的時候禁止開路輸出,當此位為 1的時候就使能開路輸出功能。

SPEED(bit7: 對應圖中的 SPEED,當 IO用作輸出的時候,此位用來設定 IO速度,設定如表所示:

在這裡插入圖片描述
DSE(bit5:3):對應圖中的 DSE,當 IO用作輸出的時候用來設定 IO的驅動能力,總共有 8個可選選項,如表所示:

在這裡插入圖片描述

SRE( 對應圖中的 SRE,設定壓擺率,當此位為 0的時候是低壓擺率,當為 1的時候是高壓擺率。這裡的壓擺率就是 IO電平跳變所需要的時間,比如從 0到 1需要多少時間,時間越小波形就越陡,說明壓擺率越高;反之,時間越多波形就越緩,壓擺率就越低。如果你的產品要過 EMC的話那就可以使用小的壓擺率,因為波形緩和,如果你當前所使用的 IO做高速通訊的話就可以使用高壓擺率。

GPIO配置

IOMUXC_SW_MUX_CTL_PAD_XX_XX

 IOMUXC_SW_PAD_CTL_PAD_XX_XX

這兩種暫存器都是配置 IO的,注意是 IO!不是 GPIO GPIO是一個 IO眾多複用功能中的一種。比如 GPIO1_IO00這個 IO可以複用為: I2C2_SCL、 GPT1_CAPTURE1、 ANATOP_OTG1_ID、ENET1_REF_CLK、 MQS_RIGHT、 GPIO1_IO00、 ENET1_1588_EVENT0_IN、SRC_SYSTEM_RESET和 WDOG3_WDOG_B這 9個功能, GPIO1_IO00是其中的一種,我們想要把 GPIO1_IO00用作哪個外設就複用為哪個外設功能即可。如果我們要用 GPIO1_IO00來點個燈、作為按鍵輸入啥的就是使用其 GPIO(通用輸入輸出 )的功能。將其複用為 GPIO以後還需要對其 GPIO的功能進行配置,關於 I.MX6的 GPIO請參考

《 IMX6晶片手冊》

的第 28章“ Chapter 28 General Purpose Input/Ouput( GPIO結構如圖所示:

在這裡插入圖片描述

相關文章