一、阿波罗开发板BSP制作
1.1 RTT源码下载
推荐两种方法:
1.从RT_Thread官网www.rt-thread.org获取源码
2.git获取源码github.com/RT-Thread/rt-thread
两种方法均可获取RTT源码,依据个人习惯爱好来就行。
1.2 制作H743BSP
所需条件:
1.STM32CubeMX软件(引脚配置和时钟初始化),使用该工具需要电脑安装JAVA环境,不懂的可以知乎一下。www.oracle.com/java/technologies/javase-downloads.html;
2.RTT源码(我用的是4.0.1版本);
万事俱备,只欠东风,hua ~ hua~ hua
首先,我们来看一下RTT源码目录结构。
既然是制作开发板的BSP,我们就主要关注该文件夹下的内容。
发现在rt-thread\bsp\stm32\docs目录下有STM32系列BSP制作教程.md文件,可能是悟性太低,我读了几遍都没理解到精髓所在,所以最后自己手动开始制作了。
RT-Thread软件包中有大量的bsp文件,现在将STM32H743阿波罗开发板作为移植对象,首先新建一个工程文件夹(这里取的文件夹名为RT-Thread_Projects,可任取),里面有四个文件夹docs、libraries、projects、rt-thread-4.0.1,分别保存文档、库文件、bsp工程文件、RT-Thread系统文件,这四个文件夹的内容来源如下表所示(下载的rt-thread-4.0.1源码在下表使用rt-thread-4.0.1-source表示):
文件夹名 | 文件夹内容 |
---|---|
rt-thread | rt-thread-4.0.1-source中除bsp文件夹外所有内容; |
libraries | rt-thread-4.0.1-source\bsp\stm32\libraries中HAL_Drivers、STM32H7xx_HAL与Kconfig; |
docs | rt-thread-4.0.1-source\bsp\stm32\docs中内容; |
projects | rt-thread-4.0.1-source\bsp\stm32\libraries\templates中的stm32h7xx; |
整理好后的目录结构如下图所示:
STM32H743阿波罗开发板,官方有移植好的代码,在.\rt-thread-4.0.1-source\bsp\stm32\stm32h743-atk-apollo目录下,因为想了解移植过程,所以并没有直接使用官方移植好的代码,而是使用.\rt-thread-4.0.1-source\bsp\stm32\libraries \templates\stm32h7xx针对STM32H7系列的模板文件开始我们的系统移植,官方移植好的代码可以作为参考。
首先打开 .\RT-Thread_Projects\projects\stm32h7xx\board\CubeMX_Config目录下CubeMX_Config.ioc文件开始选择芯片型号并配置LED PIN与USART1,打开后芯片型号是STM32H743IITx,不用修改芯片型号,USART1、RCC时钟树也为配置好了,我们添加LED PIN(PB0和PB1)的引脚,配置如下图所示:
然后生成代码即可:
板级初始化需要用到CubeMX生成具体引脚的MspInit()与MspDeinit()函数,这两个函数生成在文件projects\stm32h7xx\board\CubeMX_Config\Src\stm32h7xx_hal_msp.c中,在生成工程时,要将其包含进去,SConscript脚本中调用CubeMX生成文件的相关代码如下:
// projects\stm32h7xx\board\SConscript
import rtconfig
from building import *
cwd = GetCurrentDir()
# add the general drivers.
src = Glob('board.c')
src += Glob('CubeMX_Config/Src/stm32h7xx_hal_msp.c')
path = [cwd]
path += [cwd + '/CubeMX_Config/Inc']
开始修改代码,先将projects\stm32h7xx\board\CubeMX_Config\Src\main.c中的SystemClock_Config复制到projects\stm32h7xx\board\board.c中(根据使能的外设与时钟不同,该段代码可能不同,具体根据自己的配置修改),代码如下:
#include "board.h"
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 5;
RCC_OscInitStruct.PLL.PLLN = 160;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_USART1
|RCC_PERIPHCLK_SDMMC|RCC_PERIPHCLK_QSPI;
PeriphClkInitStruct.QspiClockSelection = RCC_QSPICLKSOURCE_D1HCLK;
PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL;
PeriphClkInitStruct.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1;
PeriphClkInitStruct.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
}
RT-Thread的移植基本完成,使用ENV开发辅助工具通过图形化系统配置工具menconfig和编译构建环境scons重新生成工程,我们将工作目录切换到projects\stm32h7xx下,运行menuconfig系统图像配置命令出现如下的提示:
提示BSP_ROOT与RTT_ROOT未定义,且不能打开文件=="…/…/…/Kconfig",menuconfig就是调用Kconfig中的配置信息,结构找不到文件,且两个路径名变量BSP_ROOT与RTT_ROOT未定义,我们在创建工程时重新组织了目录结构,所以这是提示我们根据新的目录结构修改路径名变量定义。打开projects\stm32h7xx\Kconfig==文件,修改路径名变量定义后的代码如下:
// projects\stm32h7xx\Kconfig
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config RTT_DIR
string
option env="RTT_ROOT"
default "../../rt-thread-4.0.1"
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
source "$RTT_DIR/Kconfig"
source "$PKGS_DIR/Kconfig"
source "../../libraries/Kconfig"
source "board/Kconfig"
重新运行menuconfig正常进入系统图形配置界面,需要使能GPIO与USART1并保存配置,配置界面如下:
接下来使用编译构建环境scons重新生成工程,我使用的是MDK V5 IDE,执行命令scons --target = mdk5,命令执行结果如下:
跟前面运行Kconfig结构类似,也是因为我们重新组织了目录结构,导致找不到相关文件,需要重新定义路径名变量,打开projects\stm32h7xx\SConstruct修改RTT_ROOT和SDK_ROOT两个路径名变量,修改后的部分代码如下(该文件代码较长,只截取修改部分代码):
// projects\stm32h7xx\SConstruct
......
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../../rt-thread-4.0.1')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
......
SDK_ROOT = os.path.abspath('../../')
if os.path.exists(SDK_ROOT + '/libraries'):
libraries_path_prefix = SDK_ROOT + '/libraries'
else:
libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/libraries'
SDK_LIB = libraries_path_prefix
Export('SDK_LIB')
接下来重新运行scons --target=mdk5命令,编译正常完成,运行结果如下:
接下来就可以打开projects\stm32h7xx\project.uvprojx工程文件,在main.c中编写应用程序了。
二、移植FreeModbus
2.1 移植环境配置并下载FreeModbus源码
首先通过CubeMX使能USART2,如下图所示:
然后修改projects\stm32h7xx\下的Kconfig,代码如下
//projects\stm32h7xx\board\Kconfig
menuconfig BSP_USING_UART
bool "Enable UART"
default y
select RT_USING_SERIAL
if BSP_USING_UART
config BSP_USING_UART1
bool "Enable UART1"
config BSP_USING_UART2
bool "Enable UART2"
default y
在projects\stm32h7xx目录下打开ENV工具,menuconfig中使能UART2,如下图所示:
下载FreeModBus源码:在projects\stm32h7xx目录下打开ENV工具,使能FreeModBus
选择Master Mode:
具体配置:
退出menuconfig,输入 pkgs --update命令下载FreeModBus软件包:
输入scons --target=mdk5 -s重新生成工程;至此,FreeModBus已成功加入工程,完成移植,接下来就可以用ModBus Slave软件进行测试了。