恩智浦針對I.MX6ULL編寫了一個SDK包,這個包類似STM32的標准庫或者HAL庫,這個SDK包含了Windows和Linux兩種版本。下載鏈接可以點擊下載,鏈接失效了還可以從這下:
https://pan.baidu.com/s/1L4OgqBiejZJFOmOxTVjtBw
提取碼:slhm
我是用的Ubuntu20.04。修改完權限以后用./執行run文件即可,安裝路徑為主目錄下。
定義數據類型
SDK包里會有很多數據類型,我們要先定義數據類型。
移植文件
SDK安裝完成后,我們主要用到文件是
- fsl_common.h——公共庫文件
- fsl_iomuxc.h
- MCIMX6Y2.h
這幾個文件的路徑是在我們安裝的SDK文件夾下。要對這三個文件做一些修改,過程不再贅述,把文件放在最后。這樣就可以使用了。這里着重講一個函數,先看下原來對GPIO進行初始化的方法
/*初始化LED*/ void led_init(void) { // 復用、電氣屬性寄存器初始化 IOMUX_SW_MUX->GPIO1_IO03 = 0x5; IOMUX_SW_PAD->GPIO1_IO03 = 0x10B0; // GPIO1方向寄存器, GPIO1->GDIR = 0x8; }
是通過指針直接對寄存器賦值,而NXP提供的方法是定義了個宏
void led_init(void) { // 復用、電氣屬性寄存器初始化 IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0); IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0x10B0); // GPIO1方向寄存器, GPIO1->GDIR = 0x8;
和原來的方法不一樣,下面着重講一下這兩個函數,后面用到的概率比較大。
SetPinMux
我們先看下庫文件對函數的定義
/*! * @brief Sets the IOMUXC pin mux mode. * @note The first five parameters can be filled with the pin function ID macros. * * This is an example to set the ENET1_RX_DATA0 Pad as FLEXCAN1_TX: * @code * IOMUXC_SetPinMux(IOMUXC_ENET1_RX_DATA0_FLEXCAN1_TX, 0); * @endcode * * This is an example to set the GPIO1_IO02 Pad as I2C1_SCL: * @code * IOMUXC_SetPinMux(IOMUXC_GPIO1_IO02_I2C1_SCL, 0); * @endcode * * @param muxRegister The pin mux register. * @param muxMode The pin mux mode. * @param inputRegister The select input register. * @param inputDaisy The input daisy. * @param configRegister The config register. * @param inputOnfield Software input on field. */ static inline void IOMUXC_SetPinMux(uint32_t muxRegister, uint32_t muxMode, uint32_t inputRegister, uint32_t inputDaisy, uint32_t configRegister, uint32_t inputOnfield) { *((volatile uint32_t *)muxRegister) = IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(muxMode) | IOMUXC_SW_MUX_CTL_PAD_SION(inputOnfield); if (inputRegister) { *((volatile uint32_t *)inputRegister) = IOMUXC_SELECT_INPUT_DAISY(inputDaisy); } }
注釋很清楚,該函數是對IO引腳做復用設置的。函數形參有6個,看下傳的參數IOMUXC_GPIO01_IO03_GFPIO1_IO03這個值。
#define IOMUXC_GPIO1_IO03_GPIO1_IO03 0x020E0068U, 0x5U, 0x00000000U, 0x0U, 0x020E02F4U
muxRegister 0x020E0068U muxMode 0x5U inputRegister 0x00000000U inputDaisy 0x0U configRegister 0x020E02F4U input Onfield 0
有三個寄存器,其中兩個地址已經在宏里定義好了,查手冊可以發現,muxRegister是復用設置,設置的值就是muxMode,和原先設置的值是一樣的
所以下面的函數我們都不用看
*((volatile uint32_t *)muxRegister) = IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(muxMode) | IOMUXC_SW_MUX_CTL_PAD_SION(inputOnfield);
我們都知道他是將復用的模式設置給復用寄存器的。后面或了個inputOnfield是因為復用模式muxMode只是后3個bit,第4位還有個sion位,設置個0把他關閉掉。
configRegister是電氣屬性設置
這個參數在函數中實際是沒有使用的。 原因下面會說到
IOMUXC_SetPinConfig
先看下函數的源代碼
/*! * @brief Sets the IOMUXC pin configuration. * @note The previous five parameters can be filled with the pin function ID macros. * * This is an example to set pin configuration for IOMUXC_GPIO1_IO02_I2C1_SCL: * @code * IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO02_I2C1_SCL, IOMUXC_SW_PAD_CTL_PAD_PUE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(2U)); * @endcode * * @param muxRegister The pin mux register. * @param muxMode The pin mux mode. * @param inputRegister The select input register. * @param inputDaisy The input daisy. * @param configRegister The config register. * @param configValue The pin config value. */ static inline void IOMUXC_SetPinConfig(uint32_t muxRegister, uint32_t muxMode, uint32_t inputRegister, uint32_t inputDaisy, uint32_t configRegister, uint32_t configValue) { if (configRegister) { *((volatile uint32_t *)configRegister) = configValue; } }
我們會發現,函數的形參和前面講復用配置的參數是一樣的,並且我們傳參的第一個宏也和前面一樣。所以兩個函數用到一個定義的宏。唯一的區別就是傳入的第二個值(函數第6個形參)是0x10B0,看下函數里調用的方法,也是個傳參,就是把configValue的值傳遞給configRegister寄存器里。和我們前面幾張那個配置電氣性能的賦值語句效果是一樣的。
這兩個方法要熟練掌握,后面我們做裸機驅動的時候回經常用到。用的多了就熟練了。