天天看點

NXP iMX7 M4核心PWM驅動開發

By Toradex秦海

1). 簡介

在早先的一篇文章已經介紹過基于NXP iMX7 異構多核架構進行開發調試,本文就延續這一篇文章的介紹,以PWM功能為示例着重介紹在iMX7 多核架構裡面的M4核心上面開發驅動的方式。

而本文所示範的ARM平台同樣來自于Toradex 基于NXP iMX7 ARM處理器的Colibri iMX7 ARM嵌入式平台。

2. 準備

a). Colibri iMX7S ARM核心版配合Colibri Evaluation Board,分别連接配接A7核心預設調試序列槽UART1(載闆X27)和M4核心預設調試序列槽UART2(載闆X25上)到開發主機友善調試,另外由于iMX7S隻支援一個USB接口,需要通過載闆X30連接配接一個USB Hub後來擴充鍵盤滑鼠外設。更多關于Colibri iMX7的說明請參考Datasheet和Linux開發上手指南。

b). Colibri iMX7 A7核心系統使用Toradex官方釋出的Embedded Linux,更新方法請參考這裡。

c). 另外,由于本文示範示例使用到了載闆上面PWM驅動LED和按鍵資源,需要連接配接如下:

X10 SODIMM-28 -> X21 LED1

X10 SODIMM-133 -> X21 SW6

d). SEGGER J-Link 仿真器,USB一端連接配接開發主機,JTAG一端連接配接載闆X13。

3). Colibri iMX7 M4核心FreeRTOS基本資料

a). Colibri iMX7 架構基本說明請參考如下:

   https://developer.toradex.cn/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7

b). 本示例中M4核心運作FreeRTOS v8系統,相關的源代碼和sample程式請從下面git下載下傳:

http://git.toradex.cn/cgit/freertos-toradex.git/

c). 基本的SDK配置和編譯請參考如下:

https://developer.toradex.cn/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7#Linux_support

d). 編譯好的M4 firmware如何在Colibri iMX7上面加載運作請參考如下:

https://developer.toradex.cn/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7#Running_a_Firmware_on_CortexM4

e). 幾個自帶的sample代碼簡單說明請參考如下:

https://developer.toradex.com/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7#Examples

4). Colibri iMX7 M4核心FreeRTOS PWM驅動開發

a). 在上一章節中提到的iMX7 M4 FreeRTOS源代碼中,已經包含了一些接口的驅動示例,比如GPIO,UART,I2C,Flexcan等,但并沒有包含PWM部分,是以我們需要手動添加PWM驅動。

b). 首先我們要找到提供iMX7晶片核心寄存器定義的macro code檔案,擷取PWM相關寄存器定義以及做細微調整。

./ 檔案為 platform/devices/MCIMX7D/include/MCIMX7D_M4.h

這個檔案是整個iMX7 M4 FreeRTOS代碼最核心的檔案之一,裡面定義了所有晶片寄存器macro code,具體的寄存器功能說明需要參照 NXP iMX7 Reference Manual文檔。

./ 在這個檔案裡面,如下 ”PWM Peripheral Access Layer”開始的部分定義了PWM相關的寄存器,是最關鍵的部分。

-----------------------------

   -- PWM Peripheral Access Layer

typedef struct {

  __IO  uint32_t PWMCR;                                 

  __IO  uint32_t PWMSR;                                 

  __IO  uint32_t PWMIR;                                 

  __IO  uint32_t PWMSAR;                                 

  __IO  uint32_t PWMPR;                                 

  __I   uint32_t PWMCNR;                                

} PWM_Type, *PWM_MemMapPtr;

-----------------------------

./ 在這裡,為了後面PWM驅動配置友善,我們做了如下patch

https://github.com/simonqin09/iMX7_M4_PWM_Driver/blob/master/MCIMX7D_M4.patch

c). 然後是關于CCM(Clock Control Module)驅動配置頭檔案,添加PWM所需要的clock源

./ 檔案為 - platform/drivers/inc/ccm_imx7d.h

./ 如下patch,增加PWM所需clock gate

https://github.com/simonqin09/iMX7_M4_PWM_Driver/blob/master/ccm_imx7d.patch

d). 接下來就是在 ”plaftform/drivers/inc” 和 ”platform/drivers/src” 下分别增加PWM驅動頭檔案 ”pwm_imx.h” 和源檔案 ”pwm_imx.c”,完成PWM相關基本寄存器的讀寫操作等基本功能函數的實作。

./ pwm_imx.h 檔案代碼如下

https://github.com/simonqin09/iMX7_M4_PWM_Driver/blob/master/pwm_imx.h

./ pwm_imx.c 檔案代碼如下

https://github.com/simonqin09/iMX7_M4_PWM_Driver/blob/master/pwm_imx.c

5). Colibri iMX7 M4核心FreeRTOS PWM驅動應用示例

a). 在上面章節基本驅動配置好之後,我們就可以調用驅動進行示例開發了。本文就簡單示範通過一個GPIO按鍵來動态調整PWM輸出占空比的示例。本示例所使用的GPIO Key為examples裡面已經配置的 ” BOARD_GPIO_KEY_CONFIG”,PWM使用為PWM2。

b). 首先進入 “examples/imx7_colibri_m4” 目錄,對幾個基本檔案進行修改适配

./ board.h – 這個檔案定義了目前examples下所有示例所涉及到的接口,中斷,clock等定義,是以需要将PWM2相關定義添加進來,如下面patch。

https://github.com/simonqin09/iMX7_M4_PWM_Driver/blob/master/board.patch

./ pin_mux.h 和pin_mux.c – 定義了除了GPIO之外的所有示例所涉及的接口功能的對應管腳的Pin Mux配置,這裡我們将PWM2的管腳配置添加進來,如下面patch。GPIO管腳的Pin Mux配置在gpio_pins.h/gpio_pins.c 中定義。

https://github.com/simonqin09/iMX7_M4_PWM_Driver/blob/master/pin_mux.patch

c). 然後再建立 ”pwm_imx” 目錄,為了友善,可以複制同一目錄下的 gpio_imx目錄後進行修改。

./ hardware_init.c – 硬體初始化,board,GPIO/PWM RDC/Clock 等,代碼如下

https://github.com/simonqin09/iMX7_M4_PWM_Driver/blob/master/pwm_imx/hardware_init.c

./ main.c – 主程式檔案,包含三個子程式和main主程式,三個子程式分别負責GPIO初始化,GPIO Key按鍵響應處理以及PWM中斷Handler,main主程式完成了對GPIO和PWM初始化配置後,在每次按鍵的時候将PWM輸出占空比從25%-50%-75%之間循環,具體代碼如下:

https://github.com/simonqin09/iMX7_M4_PWM_Driver/blob/master/pwm_imx/main.c

./ 最後修改 “armgcc/CMakeLists.txt” 檔案,将所有新建立的檔案包含進去,然後進行編譯,具體内容如下:

https://github.com/simonqin09/iMX7_M4_PWM_Driver/blob/master/pwm_imx/armgcc/CMakeLists.txt

./ 對iMX7 M4 FreeRTOS代碼進行debug的方法請參考這裡,本文就不再贅述。

6). Colibri iMX7 M4 PWM驅動示例部署

a). 在部署之前,首先需要確定将本文所使用的 PWM2 從 iMX7 A7 核心 Linux device tree中disable,以免發生資源沖突。有兩種方法如下:

./ 參考這裡下載下傳A7 Linux kernel源代碼,再參考這裡修改device tree後重新編譯部署。

./ 可以直接在uboot中通過 ”fdt_fixup” 環境變量來臨時禁止某個外設

-----------------------------

# ubi part ubi

# ubi read ${fdt_addr_r} dtb

# fdt addr ${fdt_addr_r}

# fdt list

# fdt list /soc/[email protected]/[email protected]

# setenv fdt_fixup ‘fdt addr ${fdt_addr_r} && fdt rm /soc/[email protected]/[email protected]/[email protected] && fdt rm /soc/[email protected]/[email protected]’

-----------------------------

b). 然後就可以參考上面的相關文檔或者之前的文章進行加載M4 firmware運作了

./ 程式開始運作,如下示波器測量資料所示,PWM2輸出周期為500ms(周期來自main主函數檔案裡面的配置),占空比為25%,從LED等可以看到亮的時間比滅的時間較短。

NXP iMX7 M4核心PWM驅動開發

./ 然後按動載闆按鍵 SW6一次,PWM2 輸出周期不變,占空比會變成50%。

NXP iMX7 M4核心PWM驅動開發

./ 再次按動載闆按鍵 SW6一次,PWM2 輸出周期不變,占空比會變成75%。

NXP iMX7 M4核心PWM驅動開發

./ 以後每次按鍵都會循環上述過程。

7). 總結

如上述示例,iMX7 M4 核心可以非常友善的開發外設驅動并進行調用,尤其是基于FreeRTOS,相對于直接配置寄存器就更直覺寫,代碼也更具備靈活性和重用性。