野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 4540|回复: 1

[经验\资料] i.mx6ull 官方SDK学习与移植(1)

[复制链接]
发表于 2023-2-5 21:11:43 | 显示全部楼层 |阅读模式
近期在某鱼上入手了一个野火的I.MX6ULL的开发板,EBF6ULL Pro S1。

网上查了下,最火的教程是正点原子、百问网、野火的,就结合三家教程开始了学习。目前正在学习祼板开发,在裸板开发教程上,正点原子最好,教程最全;百问网的次之;野火的最少,只介绍了基本的一些IO口、中断、定时器等,进阶一点的,例如LCD驱动、I2C连接传感器基本没有。

记录一下前期遇到的几个“大坑”,以利于提醒。

编译器版本。一开始没有注意到编译器版本,利用arm-none-eabi-gcc 9编译,LED灯可以点亮;结果在做按键中断试验时,中断无论如何也不产生。一度怀疑是程序中的BUG,检查良久也没有发现问题。几天后在野火还是原子论坛上才看到一句“使用arm-none-eabi-gcc 7以上版本编译器会导致中断不发生”才明白过来,后来所有的裸机试验全部使用gcc 6版本。至于为什么7以上版本会导致中断不发生,原因还不清楚,也没有找到具体原因。如果有知道的,请评论告知解惑,谢谢!

官方SDK学习。上述三家(原子、百问、野火)的教程都是从空白编写讲起,当然里面对官方提供的例程进行了删减、修改。但在我看来,还是应该结合板子,以官方SDK为主线来讲解。一方面,官方SDK是可以在项目中直接引用的(对于一般应用,不追求性能及内存空间极致的,肯定还是以官方为主)。另一方面,官方SDK对于初学者也是比较友好的,封装了很多的细节,提供了详细操作接口。一面听原子哥的原理,一面看官方SDK源码,一面对照原子哥的例程对比,一面利用SDK做操作。

集成开发环境。官方SDK提供了MDK及GCC两种编译集成例子,当然现在官方是建议使用NXP的MCUXpresso IDE ,但是MCUXpresso IDE 目前不支持IMX6ULL。。。。

CMake。官方的跨平台是使用CMake进行的,这一点对初学者其实也很友好。因为可以在Windows下编写源码、编译,然后在虚拟机下利用野火的mkimg工具写入到SD卡中。

0、官方SDK介绍
NPX提供了imx6ulSDK包:
其中,boards为官方开发板的例程,也是学习的重点。CMSIS、CORTEXA为官方提供的接口文件。middleware为第三方开发库。RTOS为操作系统的源码移植。tools为交叉编译器、映像文件生成工具、官方烧写下载工具。devices为不同型号的imx6ull芯片文件。
其中,野火、正点等的开发板都是使用红框中的芯片型号,在开发板移植时应使用MCIMX6Y2目录的芯片文件。

官方SDK测试
(1)下载arm-none-eabi-gcc 6版本,可以用官方的,也可以使用linaro的。
下载地址:https://releases.linaro.org/comp ... w32_arm-eabi.tar.xz
https://developer.arm.com/-/medi ... 5?product=Downloads,64-bit,,Linux,6-2017-q2-update
安装完毕后,Windows下要设置环境变量ARMGCC_DIR ,linux下要设置$ARMGCC_DIR 临时变量
参考官方SDK说明文档。

Ubuntu下如果系统版本过高,不容易降级。可将下载的arm-none-eabi-gcc 6 解压至指定目录,例如/opt/armgcc6目录中(armgcc6为新建的),然后在后面编译器中指定$ARMGCC_DIR参数。

(2)安装CMake。
https://github.com/Kitware/CMake ... -windows-x86_64.msi

Linux下可以用sudo apt install cmake 安装,可参考博文《ubuntu20.04安装cmake详细教程》进行安装。

环境变量设置正确后,可以选择官方例子,例如demo目录 (SDK_2.2_MCIM6ULL\boards\evkmcimx6ull\demo_apps\hello_world)的armgcc下,Windows下运行Build_debug.bat,Ubuntu运行 ./build_debug,如果编译器、环境变量设置正常,就可以正常编译,并且不报任何错误了。

如果能正常编译,并且在armgcc/debug目录相应的bin文件,说明环境变量、编译器设置没有错误了,可以进行下一步学习了。

工欲善其事,必先利其器!

这也减少后面分析错误产生的原因。

官方SDK移植
以最简单的Hello Word 为例,把官方例程完全移植到野火的板子上。

首先,我们要理解一下官方例程的结构,我使用Source Insight创建源码工程。

如何使用Source Insight,参考Source Insight使用教程。

在SI工程中添加SDK_2.2_MCIM6ULL\boards\evkmcimx6ull\demo_apps\hello_world目录,这是工程的主目录。



将hello_world目录中的所有文件都添加。


选择子递归添加子目录下的文件。


添加CMSIS、CORTEXA目录的头文件,全部添加。


野火、正点等的板子都是采用I.MX6ULL系列的MCU,但I.MX6ULL系列中又包含了若干分类,可参见《i.MX 6ULL Applications Processors for Consumer Products 》


野火、正点的板子采用的是MCIMX6Y2CVM05AB(工业级)或 MCIMX6Y2CVM08AB(工业级),主频分别 为528MHz 和 800MHz(实际为 792MHz),所以选择MCIMX6Y2目录下的头文件及驱动文件。

下面开始分析官方HelloWorld。

hello_world.c是例子的主入口文件。

#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "board.h"

#include "pin_mux.h"
#include "clock_config.h"
/*******************************************************************************
* Definitions
******************************************************************************/


/*******************************************************************************
* Prototypes
******************************************************************************/

/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief Main function
*/
int main(void)
{
    char ch;

    /* Init board hardware. */
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitMemory();
    BOARD_InitDebugConsole();

    PRINTF("hello world.\r\n");

    while (1)
    {
        ch = GETCHAR();
        PUTCHAR(ch);
    }
}

很简单,初始化引脚,打开运行时钟,初始化内存,打开调试口,打印HelloWorld,然后等待串口输入,并输出每一个字符。

void BOARD_InitPins(void) {                                /*!< Function assigned for the core: Cortex-A7[ca7] */
    IOMUXC_SetPinMux(IOMUXC_UART1_RX_DATA_UART1_RX, 0U);
    IOMUXC_SetPinConfig(IOMUXC_UART1_RX_DATA_UART1_RX,
                        IOMUXC_SW_PAD_CTL_PAD_DSE(2U) |
                        IOMUXC_SW_PAD_CTL_PAD_SPEED(2U) |
                        IOMUXC_SW_PAD_CTL_PAD_PKE_MASK);
    IOMUXC_SetPinMux(IOMUXC_UART1_TX_DATA_UART1_TX, 0U);
    IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_TX,
                        IOMUXC_SW_PAD_CTL_PAD_DSE(2U) |
                        IOMUXC_SW_PAD_CTL_PAD_SPEED(2U) |
                        IOMUXC_SW_PAD_CTL_PAD_PKE_MASK);
}
BOARD_InitPins初始化串口引脚。

在这里,官方的evkmcimx6ull开发板与野火EBF6ULLPro的板子用的引脚都是一样的,使用串口1输出。这里面不需要移植修改。

void BOARD_BootClockRUN(void)和BOARD_InitMemory()同样也不用理会,不需要修改。

void BOARD_InitDebugConsole(void)
{
    uint32_t uartClkSrcFreq;

    uartClkSrcFreq = BOARD_DebugConsoleSrcFreq();

#ifdef FSL_RTOS_FREE_RTOS
    GIC_SetPriority(BOARD_UART_IRQ, 25);
#endif

    DbgConsole_Init(BOARD_DEBUG_UART_BASEADDR, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, uartClkSrcFreq);
}
BOARD_InitDebugConsole()这个函数也不用修改,中间是条件编译的,不用理会。

下面就是针对编译选项的修改了,这个才是重点。

官方SDK在使用gcc交叉编译时,使用了CMake。

CMake的文件是hello_world\armgcc目录下的CMakeLists.txt文件。

但是因为是采用了ARM交叉编译器,需要设置交叉编译器的路径,而这些配置是在SDK_2.2_MCIM6ULL\tools\cmake_toolchain_files\armgcc文件中。

INCLUDE(CMakeForceCompiler)

# TOOLCHAIN EXTENSION
IF(WIN32)
    SET(TOOLCHAIN_EXT ".exe")
ELSE()
    SET(TOOLCHAIN_EXT "")
ENDIF()

# EXECUTABLE EXTENSION
SET (CMAKE_EXECUTABLE_SUFFIX ".elf")

# TOOLCHAIN_DIR AND NANO LIBRARY
SET(TOOLCHAIN_DIR $ENV{ARMGCC_DIR})
STRING(REGEX REPLACE "\\\\" "/" TOOLCHAIN_DIR "${TOOLCHAIN_DIR}")

IF(NOT TOOLCHAIN_DIR)
    MESSAGE(FATAL_ERROR "***Please set ARMGCC_DIR in envionment variables***")
ENDIF()

MESSAGE(STATUS "TOOLCHAIN_DIR: " ${TOOLCHAIN_DIR})

# TARGET_TRIPLET
SET(TARGET_TRIPLET "arm-none-eabi")

SET(TOOLCHAIN_BIN_DIR ${TOOLCHAIN_DIR}/bin)
SET(TOOLCHAIN_INC_DIR ${TOOLCHAIN_DIR}/${TARGET_TRIPLET}/include)
SET(TOOLCHAIN_LIB_DIR ${TOOLCHAIN_DIR}/${TARGET_TRIPLET}/lib)

SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_PROCESSOR arm)

CMAKE_FORCE_C_COMPILER(${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-gcc${TOOLCHAIN_EXT} GNU)
CMAKE_FORCE_CXX_COMPILER(${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-g++${TOOLCHAIN_EXT} GNU)
SET(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-gcc${TOOLCHAIN_EXT})

SET(CMAKE_OBJCOPY ${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-objcopy CACHE INTERNAL "objcopy tool")
SET(CMAKE_OBJDUMP ${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-objdump CACHE INTERNAL "objdump tool")

SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g" CACHE INTERNAL "c compiler flags debug")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g" CACHE INTERNAL "cxx compiler flags debug")
SET(CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -g" CACHE INTERNAL "asm compiler flags debug")
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "linker flags debug")

SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 " CACHE INTERNAL "c compiler flags release")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 " CACHE INTERNAL "cxx compiler flags release")
SET(CMAKE_ASM_FLAGS_RELEASE "${CMAKE_ASM_FLAGS_RELEASE}" CACHE INTERNAL "asm compiler flags release")
SET(CMAKE_EXE_LINKER_FLAGS_RELESE "${CMAKE_EXE_LINKER_FLAGS_RELESE}" CACHE INTERNAL "linker flags release")

SET(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_DIR}/${TARGET_TRIPLET} ${EXTRA_FIND_PATH})
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/${CMAKE_BUILD_TYPE})
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/${CMAKE_BUILD_TYPE})

MESSAGE(STATUS "BUILD_TYPE: " ${CMAKE_BUILD_TYPE})

这个ARMGCC可以跨平台使用,所以首先判断是Windows平台还是Linux平台。

CMakeLists.txt文件比较大,内容较多。

INCLUDE(CMakeForceCompiler)
# CROSS COMPILER SETTING SET(CMAKE_SYSTEM_NAME Generic) CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
# THE VERSION NUMBER SET (Tutorial_VERSION_MAJOR 1) SET (Tutorial_VERSION_MINOR 0)
# ENABLE ASM ENABLE_LANGUAGE(ASM)
SET(CMAKE_STATIC_LIBRARY_PREFIX) SET(CMAKE_STATIC_LIBRARY_SUFFIX)
SET(CMAKE_EXECUTABLE_LIBRARY_PREFIX) SET(CMAKE_EXECUTABLE_LIBRARY_SUFFIX)
# CURRENT DIRECTORY SET(ProjDirPath ${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -DDEBUG")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -D__STARTUP_CLEAR_BSS")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -D__STARTUP_INITIALIZE_NONCACHEDATA")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -g")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -flto")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -march=armv7-a")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -Wall")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -mfloat-abi=hard")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -mfpu=vfpv4")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -fno-common")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -ffunction-sections")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -fdata-sections")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -ffreestanding")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -fno-builtin")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -mthumb")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -mapcs")
SET(CMAKE_ASM_FLAGS_DDR_DEBUG "${CMAKE_ASM_FLAGS_DDR_DEBUG} -std=gnu99")

上面指定了CMAKE_ASM_FLAGS_DDR_DEBUG的参数,就是gcc在编译.s汇编文件时使用的。CMakeLists.txt中的CMAKE_C_FLAGS_DEBUG、CMAKE_EXE_LINKER_FLAGS_DEBUG等类似。

其中带DDR是指编译、链接出内存中运行的文件,不带DDR的是可以在SD卡中运行的。DEBUG、RELEASE是CMake约定的调试、发布版本。

重点是修改相关的参数。

SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DCPU_MCIMX6Y2DVM05")

其中,这个-DCPU_MCIMX6Y2DVM05参数要修改,野火的板子是-DCPU_MCIMX6Y2CVM08。

在CMakeLists.txt文件末尾,

set(CMAKE_EXE_LINKER_FLAGS_DDR_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DDR_DEBUG} -T${ProjDirPath}/MCIMX6Y2xxx05_ram.ld -static")
set(CMAKE_EXE_LINKER_FLAGS_DDR_RELEASE "${CMAKE_EXE_LINKER_FLAGS_DDR_RELEASE} -T${ProjDirPath}/MCIMX6Y2xxx05_ram.ld -static")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -T${ProjDirPath}/MCIMX6Y2xxx05_flash.ld -static")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -T${ProjDirPath}/MCIMX6Y2xxx05_flash.ld -static")
其中,这里面使用的MCIMX6Y2xxx05_ram.ld是链接文件。因为上文中已经更改为MCIMX6Y2CVM08型号的MCU,所以这里的链接文件同样要修改为MCIMX6Y2xxx08_ram.ld、MCIMX6Y2xxx08_flash.ld。

这些就是需要对官方SDK进行修改的文件。


有些图片没有上传,详细的可以参考我的博客:https://blog.csdn.net/xingzhecumt/article/details/128878905


回复

使用道具 举报

发表于 2023-2-6 08:53:19 | 显示全部楼层
感谢分享!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-3-28 18:30 , Processed in 0.033252 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表