日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ARM(IMX6U)裸机官方SDK包使用

發(fā)布時(shí)間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ARM(IMX6U)裸机官方SDK包使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

參考:Linux之ARM(IMX6U)裸機(jī)C語言LED驅(qū)動實(shí)驗(yàn)–驅(qū)動編寫,編譯
作者:一只青木呀
發(fā)布時(shí)間: 2020-08-11 11:20:17
網(wǎng)址:https://blog.csdn.net/weixin_45309916/article/details/107930284

目錄

  • 1、I.MX6ULL 官方 SDK 包簡介
  • 2、實(shí)驗(yàn)程序的編寫
    • 2.1、SDK文件的移植
    • 2.2、創(chuàng)建cc.h文件
    • 2.3、編寫實(shí)驗(yàn)代碼
      • 2.3.1、main.c
      • 2.3.2、start.s
      • 2.3.3、編寫鏈接腳本
      • 2.3.4、編寫Makefile
  • 3.編譯下載

1、I.MX6ULL 官方 SDK 包簡介

NXP 針對 I.MX6ULL 編寫了一個(gè) SDK 包,這個(gè) SDK 包就類似于 STM32 的 STD 庫或者HAL 庫,這個(gè) SDK 包提供了 Windows 和 Linux 兩種版本,分別針對主機(jī)系統(tǒng)是 Windows 和Linux。因?yàn)槲覀兪窃?Windows 下使用 Source Insight 來編寫代碼的,因此我們使用的是 Windows版本的。 Windows 版本 SDK 里面的例程提供了 IAR 版本。

肯定有人會問既然 NXP 提供了 IAR版本的 SDK,那我們為什么不用 IAR 來完成裸機(jī)試驗(yàn),偏偏要用復(fù)雜的 GCC?因?yàn)槲覀円獜暮唵蔚穆銠C(jī)開始掌握 Linux 下的 GCC 開發(fā)方法,包括 Ubuntu 操作系統(tǒng)的使用、 Makefile 的編寫、 shell 等等。如果為了偷懶而使用 IAR 開發(fā)裸機(jī)的話,那么后續(xù)學(xué)習(xí) Uboot 移植、 Linux 移植和 Linux 驅(qū)動開發(fā)就會很難上手,因?yàn)殚_發(fā)環(huán)境都不熟悉!再者,不是所有的半導(dǎo)體廠商都會為 Cortex-A 架構(gòu)的芯片編寫裸機(jī) SDK 包,我使用過那么多的 Cotex-A 系列芯片,也就發(fā)現(xiàn)了 NXP 給 I.MX6ULL 編寫了裸機(jī) SDK 包。而且去 NXP 官網(wǎng)看一下,會發(fā)現(xiàn)只有 I.MX6ULL這一款 Cotex-A 內(nèi)核的芯片有裸機(jī) SDK 包, NXP 的其它 Cotex-A 芯片都沒有。

說明在 NXP 的定位里面, I.MX6ULL 就是一個(gè) Cotex-A 內(nèi)核的高端單片機(jī),定位類似 ST 的 STM32H7。說這么多的目的就是想告訴大家,使用 Cortex-A 內(nèi)核芯片的時(shí)候不要想著有類似 STM32 庫一樣的東西, I.MX6ULL 是一個(gè)特例,基本所有的 Cortex-A 內(nèi)核的芯片都不會提供裸機(jī) SDK 包。因此在使用 STM32 的時(shí)候那些用起來很順手的庫文件,在 Cotex-A 芯片下基本都需要我們自行編寫,比如.s 啟動文件、寄存器定義等等

學(xué)習(xí)裸機(jī)目的就是為了后面的驅(qū)動做準(zhǔn)備的(高端芯片肯定要跑操作系統(tǒng)的,不可能像STM32那樣跑純裸機(jī)),所以我們盡可能的自己原生態(tài)的操作寄存器,少用這些庫,這里只是了解一下恩智浦公司開發(fā)的這些庫以及如何使用。

下載地址:
1.官方下載:https://www.nxp.com/
2.網(wǎng)盤:https://pan.baidu.com/s/17jrT_DhMZof4_KYHjgWOWg
提取碼:8hdo

下載后安裝,安裝后SDK包如圖:

我們不是講解 SDK 包如何開發(fā)的,我們只是需要 SDK 包里面的幾個(gè)文件,所以就不去詳細(xì)的講解這個(gè) SDK 包了,感興趣的可以看一下,所有的例程都在 boards 這個(gè)文件夾里面。我們重點(diǎn)是需要 SDK 包里面與寄存器定義相關(guān)的文件,一共需要如下三個(gè)文件:

fsl_common.h:位置為 SDK_2.2_MCIM6ULL\devices\MCIMX6Y2\drivers\fsl_common.h。
fsl_iomuxc.h: 位置為 SDK_2.2_MCIM6ULL\devices\MCIMX6Y2\drivers\fsl_iomuxc.h。
MCIMX6Y2.h: 位置為 SDK_2.2_MCIM6ULL\devices\MCIMX6Y2\MCIMX6YH2.h。

整個(gè) SDK 包我們就需要上面這三個(gè)文件,把這三個(gè)文件準(zhǔn)備好,我們后面移植要用。

2、實(shí)驗(yàn)程序的編寫

2.1、SDK文件的移植

使用 VSCode 新建工程,將 fsl_common.h、 fsl_iomuxc.h 和 MCIMX6Y2.h 這三個(gè)文件拷貝到工程中,這三個(gè)文件直接編譯的話肯定會出錯(cuò)的!需要對其做刪減,因?yàn)檫@三個(gè)文件里面的代碼都比較大,所以就不詳細(xì)列出這三個(gè)文件刪減以后的內(nèi)容了。

刪減后的資源下載地址:

鏈接:https://pan.baidu.com/s/1FTyJe-AZUtjjXAlgUcHbIw
提取碼:y2r4

2.2、創(chuàng)建cc.h文件

新建一個(gè)名為 cc.h 的頭文件, cc.h 里面存放一些 SDK 庫文件需要使用到的數(shù)據(jù)類型,不定義的話編譯是會出錯(cuò)的。在cc.h 里面輸入如下代碼:

#ifndef __CC_H #define __CC_H/** 自定義一些數(shù)據(jù)類型供庫文件使用*/ #define __I volatile #define __O volatile #define __IO volatiletypedef signed char int8_t; typedef signed short int int16_t; typedef signed int int32_t; typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; typedef signed char s8; typedef signed short int s16; typedef signed int s32; typedef signed long long int s64; typedef unsigned char u8; typedef unsigned short int u16; typedef unsigned int u32; typedef unsigned long long int u64;#endif

2.3、編寫實(shí)驗(yàn)代碼

新建 start.S 和 main.c 這兩個(gè)文件

2.3.1、main.c

#include "fsl_common.h" #include "fsl_iomuxc.h" #include "MCIMX6Y2.h"/*使能外設(shè)時(shí)鐘*/ void clk_enable(void) {CCM->CCGR0 =0xFFFFFFFF;CCM->CCGR1 =0xFFFFFFFF;CCM->CCGR2 =0xFFFFFFFF;CCM->CCGR3 =0xFFFFFFFF;CCM->CCGR4 =0xFFFFFFFF;CCM->CCGR5 =0xFFFFFFFF;CCM->CCGR6 =0xFFFFFFFF;}/*初始化LED燈*/ void led_init(void) {IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0); /*復(fù)用為GPIO--IO03 */IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0x10B0);/*設(shè)置GPIO__IO03電器屬性*/GPIO1->GDIR=0x8;//設(shè)置為輸出GPIO1->DR=0x0; //設(shè)置為低電平,打開LED燈} /*短延時(shí)*/ void delay_short(volatile unsigned int n) {while(n--){}} /** 延時(shí) 一次循環(huán)大概是1ms 在主頻396MHz* n:延時(shí)ms數(shù) */ void delay(volatile unsigned int n) {while (n--){delay_short(0x7ff);}} /*打開LED燈*/ void led_on(void) {GPIO1->DR&= ~(1<<3); //bit3清零} /*關(guān)閉LED燈*/ void led_off(void ) {GPIO1->DR |= (1<<3); //bit3置1 } int main() {clk_enable(); //使能外設(shè)時(shí)鐘led_init(); //初始化LEDwhile(1){led_off(); delay(1000);led_on();delay(1000);}return 0; }

我們重點(diǎn)來看一下 led_init 函數(shù)中的第 22 行和第 25 行,這兩行的內(nèi)容如下:

IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0); IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0X10B0);

這 里 使 用 了 兩 個(gè) 函 數(shù) IOMUXC_SetPinMux 和 IOMUXC_SetPinConfig , 其 中 函 數(shù)IOMUXC_SetPinMux 是 用 來 設(shè) 置 IO 復(fù) 用 功 能 的 , 最 終 肯 定 設(shè) 置 的 是 寄 存 器“IOMUXC_SW_MUX_CTL_PAD_XX”。函數(shù) IOMUXC_SetPinConfig 設(shè)置的是 IO 的上下拉、速度等的,也就是寄存器“IOMUXC_SW_PAD_CTL_PAD_XX”,所以上面兩個(gè)函數(shù)其實(shí)就是上一章中的:

IOMUX_SW_MUX->GPIO1_IO03 = 0X5; IOMUX_SW_PAD->GPIO1_IO03 = 0X10B0;

函數(shù) IOMUXC_SetPinMux 在文件 fsl_iomuxc.h 中定義,函數(shù)源碼如下:

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);} }

函數(shù) IOMUXC_SetPinMux 有 6 個(gè)參數(shù),這 6 個(gè)參數(shù)的函數(shù)如下:

  • muxRegister : IO 的 復(fù) 用 寄 存 器 地 址 , 比 如 GPIO1_IO03 的 IO 復(fù) 用 寄 存 SW_MUX_CTL_PAD_GPIO1_IO03 的地址為 0X020E0068。
  • muxMode: IO 復(fù)用值,也就是 ALT0~ALT8,對應(yīng)數(shù)字 0~8,比如要將 GPIO1_IO03 設(shè)置為 GPIO 功能的話此參數(shù)就要設(shè)置為 5。
  • inputRegister: 外設(shè)輸入 IO 選擇寄存器地址,有些 IO 在設(shè)置為其他的復(fù)用功能以后還需要設(shè)置 IO 輸入寄存器,比如 GPIO1_IO03 要復(fù)用為 UART1_RX 的話還需要設(shè)置寄存器UART1_RX_DATA_SELECT_INPUT,此寄存器地址為0X020E0624。
  • inputDaisy: 寄存器 inputRegister 的值,比如 GPIO1_IO03 要作為 UART1_RX 引腳的話此參數(shù)就是 1。
  • configRegister:未使用,函數(shù) IOMUXC_SetPinConfig 會使用這個(gè)寄存器。
  • inputOnfield : IO 軟 件 輸 入 使 能 , 以 GPIO1_IO03 為 例 就 是 寄 存 器SW_MUX_CTL_PAD_GPIO1_IO03 的 SION 位(bit4)。如果需要使能 GPIO1_IO03 的軟件輸入功能的話此參數(shù)應(yīng)該為 1,否則的話就為 0。

第一次看到上面代碼的時(shí)候肯定會奇怪,為何只有兩個(gè)參數(shù)?不是應(yīng)該 6 個(gè)參數(shù)的嗎?不要著急,先看一個(gè) IOMUXC_GPIO1_IO03_GPIO1_IO03 是個(gè)什么玩意。這是個(gè)宏,在文件fsl_iomuxc.h 中有定義, NXP 的 SDK 庫將一個(gè) IO 的所有復(fù)用功能都定義了一個(gè)宏,比如GPIO1_IO03 就有如下 9 個(gè)宏定義:

IOMUXC_GPIO1_IO03_I2C1_SDA IOMUXC_GPIO1_IO03_GPT1_COMPARE3 IOMUXC_GPIO1_IO03_USB_OTG2_OC IOMUXC_GPIO1_IO03_USDHC1_CD_B IOMUXC_GPIO1_IO03_GPIO1_IO03 IOMUXC_GPIO1_IO03_CCM_DI0_EXT_CLK IOMUXC_GPIO1_IO03_SRC_TESTER_ACK IOMUXC_GPIO1_IO03_UART1_RX IOMUXC_GPIO1_IO03_UART1_TX

上面 9 個(gè)宏定義分別對應(yīng)著 GPIO1_IO03 的九種復(fù)用功能,比如復(fù)用為 GPIO 的宏定義就是:

#define IOMUXC_GPIO1_IO03_GPIO1_IO03 0x020E0068U, 0x5U, 0x00000000U, 0x0U, 0x020E02F4U

將這個(gè)宏帶入到“示例代碼 22 行以后就是

IOMUXC_SetPinMux (0x020E0068U, 0x5U, 0x00000000U, 0x0U, 0x020E02F4U, 0);

這樣就與函數(shù) IOMUXC_SetPinMux 的 6 個(gè)參數(shù)對應(yīng)起來了,如果我們要將 GPIO1_IO03 復(fù)用為 I2C1_SDA 的話就可以使用如下代碼:

IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_I2C1_SDA, 0);

函數(shù) IOMUXC_SetPinConfig,此函數(shù)同樣在文件 fsl_iomuxc.h 中有定義,函數(shù)源碼如下:

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; } }

函數(shù) IOMUXC_SetPinConfig 有 6 個(gè)參數(shù),其中前五個(gè)參數(shù)和函數(shù) IOMUXC_SetPinMux 一樣,但是此函數(shù)只使用了參數(shù) configRegister 和 configValue, cofigRegister 參數(shù)是 IO 配置寄存器地址,比如 GPIO1_IO03 的 IO 配置寄存器為 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03,其地址為 0X020E02F4,參數(shù) configValue 就是要寫入到寄存器 configRegister 的值。同理,25 行展開以后就是:

IOMUXC_SetPinConfig(0x020E0068U, 0x5U, 0x00000000U, 0x0U, 0x020E02F4U, 0X10B0);

根據(jù)函數(shù) IOMUXC_SetPinConfig 的源碼可以知道,上面函數(shù)就是將寄存器 0x020E02F4 的值設(shè)置為 0X10B0。函數(shù) IOMUXC_SetPinMux 和 IOMUXC_SetPinConfig 就講解到這里,我們以后就可以使用這兩個(gè)函數(shù)來方便的配置 IO 的復(fù)用功能和 IO 配置。

2.3.2、start.s

.global _start .global _bss_start _bss_start:.word __bss_start .global _bss_end _bss_end:.word __bss_end_start:/*設(shè)置處理器進(jìn)入SVC模式 */mrs r0,cpsr /*讀取cpsr到r0 */bic r0,r0,#0x1f /*清除cpsr的bit4--0 */orr r0,r0,#0x13 /*使用SVC模式 */msr cpsr,r0 /*將r0寫入到cpsr中去 *//*清除bss段 */ldr r0, _bss_startldr r1, _bss_endmov r2, #0bss_loop:stmia r0!, {r2}cmp r0, r1ble bss_loop/*設(shè)置SP指針 */ldr sp,=0x80200000b main /*跳轉(zhuǎn)到C語言main函數(shù) */

2.3.3、編寫鏈接腳本

SECTIONS {. = 0x87800000;.text :{start.o*(.text)}.rodata ALIGN(4) : {*(.rodata*)}.data ALIGN(4) : {*(.data)}__bss_start = .;.bss ALIGN(4) : { *(.bss) *(COMMON)}__bss_end = .; }

2.3.4、編寫Makefile

CROSS_COMPILE ?= arm-linux-gnueabihf- NAME ?= ledcCC := $(CROSS_COMPILE)gcc LD := $(CROSS_COMPILE)ld OBJCOPY := $(CROSS_COMPILE)objcopy OBJDUMP := $(CROSS_COMPILE)objdumpOBJS := start.o main.o$(NAME).bin : $(OBJS)$(LD) -Timx6ul.lds -o $(NAME).elf $^$(OBJCOPY) -O binary -S $(NAME).elf $@$(OBJDUMP) -D -m arm $(NAME).elf > $(NAME).dis%.o : %.c $(CC) -Wall -nostdlib -c -O2 -o $@ $<%.o : %.s$(CC) -Wall -nostdlib -c -O2 -o $@ $<clean:rm -rf *.o $(NAME).elf $(NAME).bin $(NAME).dis

3.編譯下載

使用 Make 命令編譯代碼,編譯成功以后使用軟件 imxdownload 將編譯完成的 ledc.bin 文件下載到 SD 卡中,命令如下:

chmod 777 imxdownload //給予 imxdownload 可執(zhí)行權(quán)限,一次即可 ./imxdownload ledc.bin /dev/sdd //燒寫到 SD 卡中

燒寫成功以后將 SD 卡插到開發(fā)板的 SD 卡槽中,然后復(fù)位開發(fā)板,如果代碼運(yùn)行正常的話 LED0 就會以1000ms 的時(shí)間間隔亮滅

具體參考前面幾篇博文

總結(jié)

以上是生活随笔為你收集整理的ARM(IMX6U)裸机官方SDK包使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。