本帖最后由 sujingliang 于 2024-7-21 11:13 编辑
一、准备工作
1、下载rt-thread env tools:
https://download-redirect.rt-thread.org/download/env_release/env-windows-v2.0.0.7z
2、下载rt-thread最新版:
https://www.rt-thread.org/download.html
1)https://github.com/RT-Thread/rt-thread
2)https://gitee.com/rtthread/rt-thread
git clone https://gitee.com/rtthread/rt-thread.git
3)https://pan.baidu.com/s/10_50j70OVGYrEWmm2X1qvQ
提取码:t22b
3、制作BSP参考:
STM32 系列 BSP 制作教程https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/tutorial/make-bsp/stm32-bsp/STM32%E7%B3%BB%E5%88%97BSP%E5%88%B6%E4%BD%9C%E6%95%99%E7%A8%8B
二、BSP制作过程
1、复制stm32h503-st-nucleo目录到stm32h533-st-nucleo
目前rt-thread源码中,没有stm32h533-st-nucleo的bsp,但是有stm32h503-st-nucleo、stm32h563-st-nucleo,这两个BSP是stm32h533-st-nucleo的一个系列产品,可以做为制作stm32h533-st-nucleo BSP的模板。
进入:c:\rt-thread\bsp\stm32目录下,复制stm32h503-st-nucleo一份,改名stm32h533-st-nucleo
2、用STM32CubeMX建立一份stm32h533-st-nucleo最简单工程模板,只包括USART2,生成mdk工程。
其中stm32h5xx_hal_msp.c文件只有USART2初始化内容,为了用于rt-thread CMD shell
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(huart->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInitStruct.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN USART2_MspInit 1 */
/* USER CODE END USART2_MspInit 1 */
}
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] UART MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{
if(huart->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspDeInit 0 */
/* USER CODE END USART2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART2_CLK_DISABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
/* USER CODE BEGIN USART2_MspDeInit 1 */
/* USER CODE END USART2_MspDeInit 1 */
}
}
copy STM32CubeMX生成的
inc、Src目录和.mxproject、CubeMX_Config.ioc文件到C:\rt-thread\bsp\stm32\stm32h533-st-nucleo\board\CubeMX_Config覆盖原文件
3、修改board.c文件
文件目录:C:\rt-thread\bsp\stm32\stm32h533-st-nucleo\board
将文件中void SystemClock_Config(void)函数改成:
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV2;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_PCLK3;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
/** Configure the programming delay
*/
__HAL_FLASH_SET_PROGRAM_DELAY(FLASH_PROGRAMMING_DELAY_0);
}
4、修改board.h文件
文件目录:C:\rt-thread\bsp\stm32\stm32h533-st-nucleo\board
512k和208k
#define STM32_FLASH_START_ADRESS ((uint32_t)0x08000000)
#define STM32_FLASH_SIZE (512 * 1024)
#define STM32_FLASH_END_ADDRESS ((uint32_t)(STM32_FLASH_START_ADRESS + STM32_FLASH_SIZE))
#define STM32_SRAM1_SIZE (208)
#define STM32_SRAM1_START (0x20000000)
#define STM32_SRAM1_END (STM32_SRAM1_START + STM32_SRAM1_SIZE * 1024)
4.1、修改link.sct文件目录:C:\rt-thread\bsp\stm32\stm32h533-st-nucleo\board\linker_scripts
0x00080000 和 0x00034000
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x08000000 0x00080000 { ; load region size_region
ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20000000 0x00034000 { ; RW data
.ANY (+RW +ZI)
}
}
5、修改Kconfig文件
文件目录:C:\rt-thread\bsp\stm32\stm32h533-st-nucleo\board
只有保留GPIO和USART
menu "Hardware Drivers Config"
menu "Onboard Peripheral Drivers"
endmenu
menu "On-chip Peripheral Drivers"
config BSP_USING_GPIO
bool "Enable GPIO"
select RT_USING_PIN
default y
menuconfig BSP_USING_UART
bool "Enable UART"
default y
select RT_USING_SERIAL
if BSP_USING_UART
config BSP_USING_UART2
bool "Enable UART2"
default y
endif
source "$(BSP_DIR)/../libraries/HAL_Drivers/drivers/Kconfig"
endmenu
menu "Board extended module Drivers"
endmenu
endmenu
6、更新SDK
copy c:\STM32Cube_FW_H5_V1.3.0\Drivers下的内容CMSIS、STM32H5xx_HAL_Driver两个目录到C:\rt-thread\bsp\stm32\libraries\STM32H5xx_HAL,替换原来的两个目录。
7、menuconfig
在C:\rt-thread\bsp\stm32\stm32h533-st-nucleo目录下打开env tools
键入:
menuconfig
只设置GPIO和UART
退出保存。
8、修改template.uvprojx
template.uvprojx是KEIL模板文件,用KEIL打开,修改DEVICE为STM32H533RETx,保存。
env tools 下键入:
scons --target mdk5
生成keil工程文件project.uvprojx
9、keil打开project.uvprojx,编译烧录
三、运行效果
1、main.c
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
/* defined the LED1 pin: PB0 */
#define LED1_PIN GET_PIN(A, 5)
int main(void)
{
int count = 1;
rt_kprintf("【STM32 Nucleo-64测评】3、rt-thread移植\r\n");
rt_kprintf("1、GREEN LED闪烁\r\n");
/* set LED0 pin mode to output */
rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
while (count++)
{
rt_pin_write(LED1_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED1_PIN, PIN_LOW);
rt_thread_mdelay(500);
}
return RT_EOK;
}
2、串口输出
另外板载LED闪烁
四、总结
1、keil编译时,context_rvds.S以下内容报error,将1行、4行注释后,编译通过,类似的内容在context_rvds.S出现3次,都注释了。
;#if defined (__VFP_FP__) && !defined(__SOFTFP__)
TST lr, #0x10 ; if(!EXC_RETURN[4])
VSTMFDEQ r1!, {d8 - d15} ; push FPU register s16~s31
;#endif
这段可能和浮点有关,注释后编译通过,有什么后果不太清楚。
2、 stm32xxx_hal_msp.c 中添加#include <drv_common.h>
STM32 的 HAL 库有一个 Error_Handler(); 函数用于记录 HAL 库错误的情况,这个函数由 STM32CubeMX 生成在 main.c 文件中。但是我们的 BSP 并不使用 STM32CubeMX 生成的 main.c 文件,因此我们需要手动定义这个函数。 这个函数已经由 RT-Thread 提供了缺省实现,定义在 STM32 BSP 中的 dev_common.c 中,如果没有特殊需要,可以直接使用该实现。因此,我们在 stm32xxx_hal_msp.c 文件中还需要手动加入一行头文件 #include <drv_common.h>。 3、上面的配置过程可能没有尽述,详细BSP配置最好参照官方《STM32 系列 BSP 制作教程》。
|