使用GCC开发RT1064
对我来说,使用像keil这样的远古开发环境是一种折磨。如今,各大单片机厂商都发布了GCC适配的SDK,使在linux下的开发更为方便快捷。但在智能车竞赛领域,似乎没有人研究Cmake作为单片机构建系统,本篇博客详细地介绍了智能车逐飞开源库的移植使用,发挥其简单易用的优势,同时为各位车友带来更为舒适的开发体验。
0-获取SDK及工具链
SDK
去NXP SDK Builder
搜索芯片型号,点击BUILD SDK
选择开发平台及工具链,这里选择Linux和ARM GCC
点击BUILD SDK后,直接下载或去SDK Dashboard下载
工具链
GCC ARM下载此链接为直链下载,若失效请自行搜索arm gcc官网下载即可。
逐飞开源库
命令行下载1
git clone https://gitee.com/seekfree/RT1064_Library
创建工作空间rt1064,按如下路径解压两个压缩包1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27rt1064
├── Car-RT1064 <- 这个目录放项目源码
├── sdk
│ ├── boards
│ ├── CMSIS
│ ├── components
│ ├── COPYING-BSD-3
│ ├── devices
│ ├── docs
│ ├── LA_OPT_NXP_Software_License.txt
│ ├── middleware
│ ├── MIMXRT1064xxxxB_manifest_v3_14.xml
│ ├── rtos
│ ├── SDK_2_16_000_MIMXRT1064xxxxB.tar.gz
│ ├── SW-Content-Register.txt
│ └── tools
├── RT1064_Library
│ ├── Example
│ ├── Example-utf8
│ ├── LICENSE
│ ├── README.md
│ ├── SeekFree_RT1064_Opensource_Library
│ ├── SeekFree-utf8
│ ├── 【封装】核心板整体原理图封装+PCB封装
│ └── 【文档】说明书 芯片手册等
└── toolchain
└── gcc-arm-none-eabi-10.3-2021.10
至此,官方SDK以及编译工具链准备完成。
1-创建项目文件
从示例项目构建工程,复制1
sdk/boards/evkmimxrt1064/demo_apps/led_blinky
到工作空间,将其重命名为Car-RT1064。
删除不需要的文件,保留目录结构如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19led_blinky
├── armgcc <- 重命名为build
│ ├── build_flexspi_nor_debug.sh
│ ├── build_flexspi_nor_release.sh
│ ├── CMakeLists.txt
│ ├── config.cmake
│ ├── flags.cmake
│ ├── MIMXRT1064xxxxx_flexspi_nor.ld
│ ├── MIMXRT1064xxxxx_ram.ld
│ └── MIMXRT1064xxxxx_sdram.ld
├── board.c
├── board.h
├── clock_config.c
├── clock_config.h
├── dcd.c
├── dcd.h
├── led_blinky.c
├── pin_mux.c
└── pin_mux.h
按照个人习惯,build目录常作为编译中间文件临时目录,更改目录结构如下。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21led_blinky
├── build
├── build_flexspi_nor_debug.sh
├── build_flexspi_nor_release.sh
├── CMakeLists.txt
├── config.cmake
├── flags.cmake
├── include
│ ├── board.h
│ ├── clock_config.h
│ ├── dcd.h
│ └── pin_mux.h
├── MIMXRT1064xxxxx_flexspi_nor.ld
├── MIMXRT1064xxxxx_ram.ld
├── MIMXRT1064xxxxx_sdram.ld
└── src
├── board.c
├── clock_config.c
├── dcd.c
├── led_blinky.c
└── pin_mux.c
依次修改文件:
build_flexspi_nor_debug.sh1
2
3
4
5
6
7
8
9
10
11!/bin/bash
添加以下两行设置编译器和SDK路径,按需修改
export ARMGCC_DIR=/home/user/rt1064/toolchain/gcc-arm-none-eabi-10.3-2021.10/
export SDK_DIR=/home/user/rt1064/sdk
cd build/
注意cmake命令变化,无需修改,build release调用频率较低参照此文件按需修改
cmake -DSdkRootDirPath=${SDK_DIR} -DCMAKE_TOOLCHAIN_FILE=${SDK_DIR}"/tools/cmake_toolchain_files/armgcc.cmake" -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=flexspi_nor_debug ..
make -j 2>&1 | tee build_log.txt
cd -
增加flash参数,使用pyocd烧录程序,自行搜索pyocd如何安装
if [[ $# -gt 0 && $1 == "flash" ]];then pyocd flash --erase chip --target mimxrt1064 flexspi_nor_debug/blink.elf; fi
CMakeLists.txt1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16# 增加此行导出编译命令,供clangd等语言服务器使用
set(CMAKE_EXPORT_COMPILE_COMMANDS on)
# 修改输出固件文件名称,自定义烧录和调试时会用到
set(MCUX_SDK_PROJECT_NAME blink.elf)
add_executable(${MCUX_SDK_PROJECT_NAME}
"${ProjDirPath}/src/led_blinky.c"
"${ProjDirPath}/src/board.c"
"${ProjDirPath}/src/clock_config.c"
"${ProjDirPath}/src/pin_mux.c"
"${ProjDirPath}/src/dcd.c"
)
# 添加包含目录
target_include_directories(${MCUX_SDK_PROJECT_NAME} PRIVATE
${ProjDirPath}/include
$ENV{ARMGCC_DIR}/arm-none-eabi/include
)
执行1
./build_flexspi_nor_debug.sh flash
稍等片刻,完成后核心板上的led会闪烁。
至此,一个官方库的项目就创建好了。
2-增加逐飞开源库
项目整合
官方代码适配keil且在windows下编写,在linux打开会乱码,因此将其转换为utf-8编码方便查阅注释文档。
转换工具仓库:GBK2UTF8
下载最新Release,解压缩,以绝对路径执行。1
2cd RT1064_Library/
~/Downloads/gbk2utf8_v1.0.4_Linux_x86_64/gbk2utf8 --from GBK --to UTF8 --src SeekFree_RT1064_Opensource_Library --dst Seekfree-utf8 --pattern "*.*"
复制RT1064_Library/SeekFree-utf8/libraries下zf_前缀的三个文件夹到之前创建的项目文件夹的lib目录下。
在lib中创建files.cmake1
2
3
4
5
6
7
8
9
10
11
12set(zfLibDir ${ProjDirPath}/lib/)
target_include_directories(${MCUX_SDK_PROJECT_NAME} PUBLIC
${zfLibDir}/zf_common
${zfLibDir}/zf_components
${zfLibDir}/zf_device
${zfLibDir}/zf_driver
)
file(GLOB_RECURSE ZF_SRCS ${zfLibDir}/*.c)
target_sources(${MCUX_SDK_PROJECT_NAME} PRIVATE
${ZF_SRCS}
)
修改项目目录CMakeLists.txt,在约60行的位置增加1
include(${ProjDirPath}/lib/files.cmake)
修复编译错误
1、fputc类型冲突
打开zf_common_debug.c,在353行将两个int32_t修改为int。
2、找不到DTCM区域对齐宏函数
修改对应行为。但此内容暂时没有深究,因为个人不使用单片机上的摄像头,并且也没有找到GCC编译器下将图像缓冲区放到DTCM区并对齐的办法。这里仅声明对齐,对性能的影响未知。1
2uint8 ALIGN(64) mt9v03x_image1[MT9V03X_H][MT9V03X_W];
uint8 ALIGN(64) mt9v03x_image2[MT9V03X_H][MT9V03X_W];
所有有关摄像头的头文件均有类似的报错,请自行修改,修改时注意对齐大小。
3、找不到头文件
在对应文件找到报错这行,大写字母全部改为小写字母即可。
4、找不到头文件x2
基本不用sd卡,删除zf_driver_sdio.c/.h即可。若想使用需自己配置config.cmake,我试过了各种组合均因配置之间的依赖问题无法成功,请自行尝试。
注意: 头文件时请同步删除zf_common_headfile.h中对应行,不然会再次报错。
5、找不到头文件x3
同上,若无法解决,删!!!
放一份自用config.cmake,当遇到可解决的问题后会随时更新。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42# config to select component, the format is CONFIG_USE_${component}
# Please refer to cmake files below to get available components:
# ${SdkRootDirPath}/devices/MIMXRT1064/all_lib_device.cmake
set(CONFIG_COMPILER gcc)
set(CONFIG_TOOLCHAIN armgcc)
set(CONFIG_USE_COMPONENT_CONFIGURATION false)
set(CONFIG_USE_driver_igpio true)
set(CONFIG_USE_driver_clock true)
set(CONFIG_USE_driver_common true)
set(CONFIG_USE_driver_gpt true)
set(CONFIG_USE_driver_pwm true)
set(CONFIG_USE_device_MIMXRT1064_CMSIS true)
set(CONFIG_USE_utility_debug_console true)
set(CONFIG_USE_component_lpuart_adapter true)
set(CONFIG_USE_component_serial_manager_uart true)
set(CONFIG_USE_component_serial_manager true)
set(CONFIG_USE_driver_lpuart true)
set(CONFIG_USE_component_lists true)
set(CONFIG_USE_device_MIMXRT1064_startup true)
set(CONFIG_USE_driver_iomuxc true)
set(CONFIG_USE_utility_assert true)
set(CONFIG_USE_driver_xip_device true)
set(CONFIG_USE_driver_xip_board_evkmimxrt1064 true)
set(CONFIG_USE_utilities_misc_utilities true)
set(CONFIG_USE_CMSIS_Include_core_cm true)
set(CONFIG_USE_utility_str true)
set(CONFIG_USE_device_MIMXRT1064_system true)
set(CONFIG_USE_driver_adc_12b1msps_sar true)
set(CONFIG_USE_driver_qtmr_1 true)
# Freertos
set(CONFIG_USE_middleware_freertos-kernel_heap_4 true)
set(CONFIG_USE_middleware_freertos-kernel true)
set(CONFIG_USE_middleware_freertos-kernel_template true)
set(CONFIG_USE_middleware_freertos-kernel_extension true)
set(CONFIG_CORE cm7f)
set(CONFIG_DEVICE MIMXRT1064)
set(CONFIG_BOARD evkmimxrt1064)
set(CONFIG_KIT evkmimxrt1064)
set(CONFIG_DEVICE_ID MIMXRT1064xxxxA)
set(CONFIG_FPU DP_FPU)
set(CONFIG_DSP NO_DSP)
运行逐飞开源库示例
需要删除官方库的两个文件src/dcd.c,src/pin_mux.c,和对应的头文件。同时在CMake add_executable中删除对应行。
替换src/led_blinky.c为逐飞gpio示例,并复制isr.c到src目录下,CMake添加(下文不再强调)。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
uint8 gpio_status;
int main(void)
{
clock_init(SYSTEM_CLOCK_600M); // 不可删除
debug_init(); // 调试端口初始化
// 此处编写用户代码 例如外设初始化代码等
// 初始化GPIO B9 为输出 默认输出低电平
gpio_init(B9, GPO, 0, GPO_PUSH_PULL);
// 初始化GPIO D0 D1 为输入引脚
gpio_init(C4, GPI, 0, GPI_PULL_UP);
gpio_init(D1, GPI, 0, GPI_PULL_UP);
// 此处编写用户代码 例如外设初始化代码等
while(1)
{
gpio_set_level(B9, 1); // 设置引脚电平为高电平
system_delay_ms(100);
gpio_set_level(B9, 0); // 设置引脚电平为低电平
system_delay_ms(100);
gpio_toggle_level(B9); // 翻转引脚电平
system_delay_ms(100);
gpio_status = gpio_get_level(C4); // 获取引脚电平
system_delay_ms(100);
}
}
此时就能看见核心板上的led愉快地闪了。
3-使用FreeRTOS
要使用FreeRTOS需要在config.cmake中添加相关配置,这里使用上文的配置即可。
打开lib/zf_common/zf_common_vector.c,注释SVC_Handler、PendSV_Handler、SysTick_Handler。头文件中也要注释。
运行FreeRTOS示例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
static void hello_task(void *pv) {
for (;;) {
gpio_set_level(B9, 1);
vTaskDelay(1000 / portTICK_PERIOD_MS);
gpio_set_level(B9, 0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
int main(void) {
gpio_init(B9, GPO, 1, GPO_PUSH_PULL);
if (pdPASS != xTaskCreate(hello_task, "Hello", configMINIMAL_STACK_SIZE + 100,
NULL, configMAX_PRIORITIES - 1, NULL)) {
while (1) {
printf("Create Task failed");
}
}
vTaskStartScheduler();
}
又能看见led闪烁啦!!!
附:解决clangd无法识别编译选项
在项目根目录创建.clangd文件1
2
3CompileFlags:
Add: -Wno-unknown-warning-option
Remove: [-m*, -f*]