基于RTEMS的阿波罗STM32F429开发板(正点原子)适配

最近忙着出差也没写什么文档,先把前段时间做的一个简单的RTEMS适配过程文档发上来供大家参考。

1、文档概述

本文档主要为描述基于正点原子的阿波罗STM32F429开发板,开展RTEMS适配的过程,以及过程中常见工具的使用方法,过程中遇到的问题及解决问题的方法。以下内容有部分(很多截图)是直接复制《STM32F429开发指南》、《ARM Cortex-M3与Cortex-M4权威指南》等文档。

2、开发板介绍

本章主要描述正点原子的阿波罗STM32F429开发板的基本硬件资源以及基本的使用调试方法。

2.1 硬件资源

关于开发板硬件资源具体可以参考《STM32F429开发指南》,这里放两张截图,分别为开发板核心资源及开发板外部接口。

2.1.1 核心板资源

 基于RTEMS的阿波罗STM32F429开发板(正点原子)适配

                                                        图 1 STM32F429核心板资源

首先根据图 1可以看到,开发板上提供的核心资源是很多的,但想用起来这些外部资源还需要经过一系列的初始化,比如SPI RAM的使用可以参考《STM32F429开发指南 ——SDRAM 实验》。我们最关注除了CORTEX-M4核之外就是存储资源了,目前我们核心需要知道的是CPU内部存储资源及地址空间映射情况如图 2(图片来自《STM32F429xx CPU手册》p86):

       基于RTEMS的阿波罗STM32F429开发板(正点原子)适配

                                                                 图 2 CPU内存空间映射

         基于RTEMS的阿波罗STM32F429开发板(正点原子)适配

                                                    图 3 STM32F42x和 STM32F43x FLASH资源

根据图 2、图 3可以知道CPU内部可用的存储空间主要有:

 

地址段

大小

类型

描述

1

0x8000000-0x81FFFFF

2MB

FLASH

大小根据处理器型号不同,其中STM32F42x和STM32F43x的FLASH资源如图 3(来自《STM32F4XX中文参考手册》P60),也就是有两组1MB的空间,我们通常只配置其中的1MB。

2

0x1000 0000-0x1000FFFF

64KB

SRAM

只能供CPU通过数据总线访问

3

0x2000 0000-0x2001BFFF

112KB

SRAM

可供所有AHB主控总线访问,AHB主总线支持并发SRAM访问。即可以在CPU对112KB或64KB访问时,以太网MAC同时对16KB SRAM进行读写(也就是可以用于外设DMA读写?)(《STM32F4XX中文参考手册》P55)

4

0x2001 C000-0x2001FFFF

16KB

SRAM

5

0x2002 0000-0x2002 FFFF

64KB

SRAM

下面我们可以再看一下正点原子提供的示例工程中关于存储空间的配置(keil开发环境,project options for target ‘xx’)如图 4,因此后续使用RTEMS时,链接脚本中相关地址信息可以参考该配置。

         基于RTEMS的阿波罗STM32F429开发板(正点原子)适配

                                                              图 4 示例工程配置

2.1.2 底板资源

下图所示为STM32F429开发板的底板资源,接口众多还有很多跳帽用来短接各种线,适配初期我们需要使用的主要是“USB转串口”(接了USB_232后如果不使用LCD屏,可以不接电源输入,由USB口供电)、“JTAG/SWD接口”,当然几个按钮和蜂鸣器也可以在测试中使用。

关于跳帽,目前我们主要需要了解的是“USB串口/串口1”跳帽,该接口用于将PA9、PA10(串口1的管脚)同USB串口的RXD、TXD短接,这样在系统启动后可以通过USB串口输出串口1的信息(参考《STM32F429开发指南》 1.2.1-6)。

     基于RTEMS的阿波罗STM32F429开发板(正点原子)适配

                                                                                                 图 5 底板资源

2.2 软件资源

在《STM32F429开发指南》中介绍了提供的测试用例资源,因此这里我就不再介绍;本节主要介绍几个开发调试过程中可能使用到的软件。其中前四个软件(2.2.1-2.2.4)在指南中均有介绍,使用过程及方法直接参考《STM32F429开发指南》第四章或者****即可。后面的软件主要用于RTEMS开发过程,这里会对使用方法进行稍微详细点的描述。

2.2.1 MDK5(Keil_V5)

MDK 源自德国的 KEIL 公司,是 RealView MDK 的简称。在全球 MDK 被超过 10 万的嵌入式开发工程师使用。MDK是目前针对 ARM 处理器,尤其是 Cortex M 内核处理器的最佳开发工具。开发环境界面如图所示,对于RTEMS开发来说,这个环境只是用来运行开发光盘中自带测试用例,验证某些功能正确性,主要关心编译、下载、调试过程,因此这里就不再描述该开发环境的使用过程了。

     基于RTEMS的阿波罗STM32F429开发板(正点原子)适配                   

                                                            图 6 MDK5开发环境界面

2.2.2 CH340串口驱动

开发板连接出来的USB串口驱动。

2.2.3 STLINK驱动

仿真器驱动。

2.2.4 FLYMCU

Flymcu核心功能就是可以通过指定串口将文件烧写到目标板的FLASH中,这个烧写是依赖什么原理,目前没有研究(我猜是目标板端有烧写专用的BootLoader),烧写过程比较简单(保证hex文件中地址符号要求,即在0x20000000、0x8000000起始的段内),不再描述。

2.2.5 OPENOCD

OpenOCD——开放式片上调试器旨在为嵌入式目标器件提供调试,系统内编程和边界扫描测试,官方网站为http://openocd.org/

关于OpenOCD的原理目前也没有看到帖子描述的很清楚,不过根据官方文档该工具支持各种基于USB JTAG、USB STLINK、USB CMSIS DAP的目标板调试,工作原理如下图(盗图):

                                            基于RTEMS的阿波罗STM32F429开发板(正点原子)适配

                                                                                                                                     图 7 OpenOCD基本工作原理

 

简单描述一下,就是OpenOCD运行后会启动多个线程分别监视主机3333(GDBSERVER)、4444(TELNETD)、6666(TCL不了解)三个端口,本机可以通过GDB、TELNET连接以上端口,并发送相关命令。接收到命令后,OpenOCD根据当前启动的目标配置文件,选择将相应的命令封装为指定调试器(JTAG/ STLINK/CMSIS DAP)支持的USB消息包(控制传输?),并发送到指定调试器从而控制开发板运行。

对于openocd详细使用方法可以参考官方的《OpenOCD User’s Guide》。

2.2.6 ECLIPSE

Eclipse是著名的跨平台的*集成开发环境(IDE),目前很多厂商的开发环境都是基于Eclipse插件开发的方式实现的,这里之所以使用ECLIPSE主要是为了能够通过图形化的方式进行GDB调试,命令行虽然强大,但并不友好。JDK主要是提供Eclipse运行过程中需要使用的JAVA环境支持。

Eclipse作为开源开发环境,还是受到很多开发人员支持的,实际上当前如果想通过Eclipse开发MCU的应用程序,可以直接从https://gnu-mcu-eclipse.github.io/直接下载相关的插件安装包(工程支持、编译工具链、OPENOCD支持、QEMU模拟器支持),可以说是功能相当的全面了,不过我们目前不需要使用这些工具,后续如果有需要可以研究一下。可以下载的资源列表如下:

                                                                                  基于RTEMS的阿波罗STM32F429开发板(正点原子)适配

                                                                                                                                图 8 Eclips MCU支持资源

2.2.7 CYGWIN/MSYS/MSYS2

这三个环境其实都能够完成在Windows上的交叉工具链、RTEMS内核的编译,目前我用的比较多的还是CYGWIN。

2.2.8 TELNET客户端

Telnet客户端主要用于连接OpenOCD的TELNETD,向调试器/仿真器发送相关命令的,该过程其实可以通过GDB连接OpenOCD完成,不过后面还是会介绍一个通过telnet连接OpenOCD的常用命令,所以这里也列出了该软件。Windows系统下Telnet客户端可以直接在“启动或关闭Windows功能”界面中打开即可。

           基于RTEMS的阿波罗STM32F429开发板(正点原子)适配

                                                                                  图 9 Windows TELNET客户端

3、RTEMS适配

针对正点原子阿波罗STM32F429开发板的RTEMS(RTEMS-4.11.3)适配,主要包含交叉工具链编译、内核修改及编译(也可以调试)、应用编译及调试三个过程,中间针对内核的调试过程这里就不再描述了,其实后面可能还会尝试裁剪内核部分功能,如何裁剪以后再说吧。

3.1 交叉工具链编译

本来准备直接用自己以前编译过的一套工具链,结果发现调试内核时C库函数各种异常,发现以前编译工具链时为了加快编译过程(FOR XILINX)将GCC编译配置改了,所以编译出的工具链中不包含CORTEX-V7M的支持,因此这里重新编译了工具链。各源码版本如下:

序号

名称

版本

说明

1

Cygwin

version 2.850

工具链及内核编译环境

2

autoconf

2.69

根据配置文件xxx.ac、yyy.am自动生成Makefile的工具

3

automake

1.12.6

4

binutils

2.26

GNU二进制工具集,汇编器、链接器等

5

gmp

6.0.0

编译GCC需要使用的依赖库,且分别向上依赖

6

mpfr

3.1.2

7

mpc

1.0.3

8

gcc

4.9.3

GNU编译工具

9

gdb

7.9

GNU调试工具

 

修改的GCC编译配置文件为gcc-4.9.3\gcc\config\arm\t-rtems-eabi,注释掉下面两行(新版本GCC中用的是MULTILIB_REQUIRED道理差不多):

# MULTILIB_EXCEPTIONS += mthumb/march=armv7-m/mfpu=fpv4-sp-d16/mfloat-abi=hard

# MULTILIB_EXCEPTIONS += mthumb/march=armv7-m

根据CPU手册,STM32F429处理器应该使用fpv4-sp-d16的硬件浮点,不过RTEMS内核源码中stm32f4板级支持包编译选项中并未设置硬件浮点,也就是默认使用的是第二行的配置,因此这里两个都编译一下,后续可以根据需要选择配置。

基于CYGWIN/MSYS2的工具链编译过程是一样的,整个编译流程如下表,当然实际上以下编译过程可以直接通过脚本实现(可以查看build.sh)。

流程

主要工作

 

1

Autoconf、Automake配置、编译、安装

./configure

make –j4 (本人机器为4核,所以用4线程编译)

make install

2

Binutils配置、编译、安装

cat ../binutils-2.26-gas-reloc.patch |patch -p1

../binutils-2.26/configure --target=arm-rtems4.11 --prefix=/Rtems/host-arm --verbose --disable-nls --without-included-gettext --disable-win32-registry --disable-werror

make -j4

make install

3

GMP配置、编译、安装

../gmp-6.0.0/configure --prefix=/Rtems/host-arm

make -j4

make install

MPFR配置、编译、安装

../../../mpfr-3.1.2/configure --prefix=/Rtems/host-arm --with-gmp=/Rtems/ host-arm

make -j4

make install

MPC配置、编译、安装

../../../mpc-1.0.3/configure --prefix=/Rtems/host-arm --with-gmp=/Rtems/host-arm --with-mpfr=/Rtems/host-arm --enable-static --disable-shared

make -j4

make install

export PATH=/Rtems/host-arm/bin:$PATH

4

GCC+NEWLIB配置、编译、安装

cd ../newlib-2.2.0.20150423/

cat ../newlib-ARM-Optimize-IEEE-754-sqrt-implementation.patch |patch -p1

cat ../newlib-cygwin-git-f70d9ae6adc6ed7952806056349ba9f8ba3c65c8.patch|patch -p1

 

cd ../gcc-4.9.3/

cat ../gcc-4.9.3-20170404-1.patch |patch -p1

cat ../gcc-4.9.3-or1k.patch |patch -p1

ln -s ../newlib-2.2.0.20150423/newlib/

 

cd ../b-gcc

../gcc-4.9.3/configure --prefix=/Rtems/host-arm --target=arm-rtems4.11 --disable-libstdcxx-pch --with-gnu-as --with-gnu-ld --verbose --with-newlib --disable-nls --without-included-gettext --disable-win32-registry --enable-version-specific-runtime-libs --disable-lto --enable-newlib-io-c99-formats -enable-newlib-iconv --enable-newlib-iconv-encodings=big5,cp775,cp850,cp852,cp855,cp866,euc_jp,euc_kr,euc_tw,iso_8859_1,iso_8859_10,iso_8859_11,iso_8859_13,iso_8859_14,iso_8859_15,iso_8859_2,iso_8859_3,iso_8859_4,iso_8859_5,iso_8859_6,iso_8859_7,iso_8859_8,iso_8859_9,iso_ir_111,koi8_r,koi8_ru,koi8_u,koi8_uni,ucs_2,ucs_2_internal,ucs_2be,ucs_2le,

ucs_4,ucs_4_internal,ucs_4be,ucs_4le,us_ascii,utf_16,utf_16be,utf_16le,utf_8,win_1250,win_1251,win_1252,win_1253,win_1254,win_1255,win_1256,win_1257,win_1258 --enable-libgomp --disable-lto --enable-threads --disable-plugin --enable-languages=c,c++ --with-gmp=/Rtems/host-arm --with-mpfr=/Rtems/host-arm --with-mpc=/Rtems/host-arm

make -j4

make install

5

GDB配置、编译、安装

../gdb-7.9/configure --target=arm-rtems4.11 --prefix=/Rtems/host-arm

3.2 内核修改及编译

工具链编译完就要开始编译内核了,内核源码选择RTEMS-4.11.3版本。

3.2.1 内核修改

针对正点原子的STM32F429开发板,我们需要修改的文件及修改的内容如下(核心是修改时钟配置,外部晶振为25MHZ,系统时钟配置为180MHZ),这里面在实际编译应用时还需要修改应用的链接脚本文件linkcmds.stm32f4文件,RAM、ROM的地址就按照前面所描述的地址资源进行修改即可。

序号

文件名

内容

1

stm32f4.cfg

CPU_CFLAGS = -march=armv7-m -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16

2

configure.ac

主要是修改时钟,使能UART1、UART3

AC_PREREQ([2.69])

AC_INIT([rtems-c-src-lib-libbsp-arm-stm32f4],[_RTEMS_VERSION],[https://devel.rtems.org/newticket])

AC_CONFIG_SRCDIR([bsp_specs])

RTEMS_TOP(../../../../../..)

 

RTEMS_CANONICAL_TARGET_CPU

AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.12.2])

RTEMS_BSP_CONFIGURE

 

RTEMS_PROG_CC_FOR_TARGET

RTEMS_CANONICALIZE_TOOLS

RTEMS_PROG_CCAS

 

RTEMS_CHECK_NETWORKING

AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")

 

RTEMS_BSPOPTS_SET([STM32F4_FAMILY_F4XXXX],[stm32f4*],[1])

RTEMS_BSPOPTS_HELP([STM32F4_FAMILY_F4XXXX],[Chip belongs to the STM32F4XXXX family.])

 

RTEMS_BSPOPTS_SET([STM32F4_HSE_OSCILLATOR],[*],[25000000])

RTEMS_BSPOPTS_HELP([STM32F4_HSE_OSCILLATOR],[HSE oscillator frequency in Hz])

 

RTEMS_BSPOPTS_SET([STM32F4_SYSCLK],[*],[ 180000000])

RTEMS_BSPOPTS_HELP([STM32F4_SYSCLK],[SYSCLK frequency in Hz])

 

RTEMS_BSPOPTS_SET([STM32F4_HCLK],[*],[ 180000000])

RTEMS_BSPOPTS_HELP([STM32F4_HCLK],[HCLK frequency in Hz])

 

RTEMS_BSPOPTS_SET([STM32F4_PCLK1],[*],[ 45000000])

RTEMS_BSPOPTS_HELP([STM32F4_PCLK1],[PCLK1 frequency in Hz])

 

RTEMS_BSPOPTS_SET([STM32F4_PCLK2],[*],[ 90000000])

RTEMS_BSPOPTS_HELP([STM32F4_PCLK2],[PCLK2 frequency in Hz])

 

RTEMS_BSPOPTS_SET([STM32F4_USART_BAUD],[*],[115200])

RTEMS_BSPOPTS_HELP([STM32F4_USART_BAUD],[baud for USARTs])

 

RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_1],[*],[1])

RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_USART_1],[enable USART 1])

 

RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_2],[*],[])

RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_USART_2],[enable USART 2])

 

RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_3],[*],[1])

RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_USART_3],[enable USART 3])

 

RTEMS_BSPOPTS_SET([STM32F4_ENABLE_UART_4],[*],[])

RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_UART_4],[enable UART 4])

 

RTEMS_BSPOPTS_SET([STM32F4_ENABLE_UART_5],[*],[])

RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_UART_5],[enable UART 5])

 

RTEMS_BSPOPTS_SET([STM32F4_ENABLE_USART_6],[*],[])

RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_USART_6],[enable USART 6])

 

RTEMS_BSPOPTS_SET([STM32F4_ENABLE_I2C1],[*],[])

RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_I2C1],[enable I2C 1])

 

RTEMS_BSPOPTS_SET([STM32F4_ENABLE_I2C2],[*],[])

RTEMS_BSPOPTS_HELP([STM32F4_ENABLE_I2C2],[enable I2C 2])

 

RTEMS_BSP_CLEANUP_OPTIONS(0, 0)

RTEMS_BSP_LINKCMDS

 

AC_CONFIG_FILES([Makefile])

AC_OUTPUT

3

bspstart.c

/* APB1 prescaler, APB1 clock must be < 45MHz */

  apbpre1 = ( sys_clk * 100 ) / 45;

 

  if ( apbpre1 <= 100 ) {

    apbpre1 = RCC_CFGR_PPRE1_BY_1;

  } else if ( apbpre1 <= 200 ) {

    apbpre1 = RCC_CFGR_PPRE1_BY_2;

  } else if ( apbpre1 <= 400 ) {

    apbpre1 = RCC_CFGR_PPRE1_BY_4;

  } else if ( apbpre1 <= 800 ) {

    apbpre1 = RCC_CFGR_PPRE1_BY_8;

  } else if ( apbpre1 ) {

    apbpre1 = RCC_CFGR_PPRE1_BY_16;

  }

 

  /* APB2 prescaler, APB2 clock must be < 90MHz */

  apbpre2 = ( sys_clk * 100 ) / 90;

 

  if ( apbpre2 <= 100 ) {

    apbpre2 = RCC_CFGR_PPRE2_BY_1;

  } else if ( apbpre2 <= 200 ) {

    apbpre2 = RCC_CFGR_PPRE2_BY_2;

  } else if ( apbpre2 <= 400 ) {

    apbpre2 = RCC_CFGR_PPRE2_BY_4;

  } else if ( apbpre2 <= 800 ) {

    apbpre2 = RCC_CFGR_PPRE2_BY_8;

  } else {

    apbpre2 = RCC_CFGR_PPRE2_BY_16;

  }

 

  rcc->cr |= RCC_CR_HSION;   /* turn on HSI */

 

  while ( ( !( rcc->cr & RCC_CR_HSIRDY ) ) ) ;

3.2.2  内核编译

修改完内核之后,内核编译过程如下:

cd rtems-4.11.3

./bootstrap –c

./bootstrap

 

cd ../b-rtems

../rtems-4.11.3/configure --target=arm-rtems4.11 --enable-rtemsbsp=stm32f4 --disable-posix --disable-tests --enable-networking --enable-libchip --prefix=/Rtems_tools/host-arm/rtems_stm32

make –j4

make install

4、应用调试

使用MDK调试应用程序比较简单,直接阅读正点原子的开发指南或者观看****即可,本章主要描述如何基于Eclipse进行RTEMS应用/内核调试。根据2.2.6我们可以下载包含“MCU Eclipse plug-ins”的Eclispe开发环境,该开发环境可以默认支持多种调试模式,因此在执行调试配置时更加简单。

ECLIPSE下配置RTEMS应用程序开发工程的过程这里就不再描述了,无非就是创建ECLIPSE交叉编译工程,配置好工具链、头文件路径、库文件路径,Eclipse调试时,调试配置选择GDB OpenOCD Debugging,调试配置如图 12、图 13,可以发现使用Eclipse调试时,不用在命令行手动启动openocd,完成配置后直接启动调试即可。

 

      基于RTEMS的阿波罗STM32F429开发板(正点原子)适配

                                                            图 10 Eclipse调试支持        

              

    基于RTEMS的阿波罗STM32F429开发板(正点原子)适配

                                                        图 11 DEBUG调试配置