RT-Thread&ART-PIBSP制作过程

Posted Rb菌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RT-Thread&ART-PIBSP制作过程相关的知识,希望对你有一定的参考价值。

ART-Pi 除了配备一颗 W25Q64JV 用于存放程序外,同时配备了另一颗 W25Q128JV 用于存放 WIFI 固件,蓝牙固件,等其它数据.官方建议这颗 W25Q128JV 的空间划分如下:

分区名起始地址分区大小用途说明
wifi_image0512KB保存 wifi 固件
bt_image512 * 1024512KB保存 bt 固件
download1 * 1024 * 10242048KB固件下载分区
easyflash3 * 1024 * 10241024KBeasyflash 参数保存区
filesystem4 * 1024 * 102412MB文件系统分区

一、修改MDK中链接脚本

因为ART-PI的程序是运行在片外flash中的,原本的BSP中的连接脚本是运行在片内flash中,这样会覆盖本身的bootloader,所以我们需要修改其程序运行地址。

点击mdk中的魔术棒,选择Linker,点击Edit进入该脚本编辑模式

LR_IROM1 0x90000000 0x00800000      ; load region size_region
  ER_IROM1 0x90000000 0x00800000    ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  
  RW_IRAM1 0x24000000 0x00080000    ; AXI SRAM 512K
   .ANY (+RW +ZI)
  

其中load region size_region为装载区域。

LR_IROM1, 名字,可以理解为一块存储器的名字。

0x90000000:起始地址。

0x00800000:代表size,(download+easyflash+filesystem=8M)也就是存储器的最大空间。

RW_IRAM1:RW data,初始化了的可读写变量的大小。

二、添加时钟配置

打开board.c,添加以下内容

/**
  * @brief System Clock Configuration
  * @retval None
  */
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_SCALE0);

  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_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 = 192;
  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 buses 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_4) != HAL_OK)
  
    Error_Handler();
  
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC|RCC_PERIPHCLK_USART3
                              |RCC_PERIPHCLK_UART4|RCC_PERIPHCLK_SPI4
                              |RCC_PERIPHCLK_SPI1|RCC_PERIPHCLK_SDMMC
                              |RCC_PERIPHCLK_ADC|RCC_PERIPHCLK_USB
                              |RCC_PERIPHCLK_LPTIM1|RCC_PERIPHCLK_FMC;
  PeriphClkInitStruct.PLL2.PLL2M = 2;
  PeriphClkInitStruct.PLL2.PLL2N = 64;
  PeriphClkInitStruct.PLL2.PLL2P = 2;
  PeriphClkInitStruct.PLL2.PLL2Q = 2;
  PeriphClkInitStruct.PLL2.PLL2R = 4;
  PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_3;
  PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
  PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
  PeriphClkInitStruct.PLL3.PLL3M = 5;
  PeriphClkInitStruct.PLL3.PLL3N = 160;
  PeriphClkInitStruct.PLL3.PLL3P = 8;
  PeriphClkInitStruct.PLL3.PLL3Q = 8;
  PeriphClkInitStruct.PLL3.PLL3R = 24;
  PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_2;
  PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE;
  PeriphClkInitStruct.PLL3.PLL3FRACN = 0;
  PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_PLL2;
  PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL2;
  PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL2;
  PeriphClkInitStruct.Spi45ClockSelection = RCC_SPI45CLKSOURCE_PLL3;
  PeriphClkInitStruct.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1;
  PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
  PeriphClkInitStruct.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSI;
  PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  
    Error_Handler();
  
  /** Enable USB Voltage detector
  */
  HAL_PWREx_EnableUSBVoltageDetector();

以上主要是对系统的时钟进行初始化配置。

三、修改board.h中的配置选项

之前board.h中的配置如下:

#define STM32_FLASH_START_ADRESS     ((uint32_t)0x08000000)
#define STM32_FLASH_SIZE             (128 * 1024)
#define STM32_FLASH_END_ADDRESS      ((uint32_t)(STM32_FLASH_START_ADRESS + STM32_FLASH_SIZE))

#define STM32_SRAM_SIZE           (128)
#define STM32_SRAM_END            (0x20000000 + STM32_SRAM_SIZE * 1024)

因为ATP-PI的外扩QSPI FLASH的开始地址为0x90000000,外扩的SPI FLASH的总大小为16M,之前的配置明显是不正确的,故我们修改如下:

/*-------------------------- CHIP CONFIG BEGIN --------------------------*/

#define CHIP_FAMILY_STM32
#define CHIP_SERIES_STM32H7
#define CHIP_NAME_STM32H750XBHX

/*-------------------------- CHIP CONFIG END --------------------------*/

/*-------------------------- ROM/RAM CONFIG BEGIN --------------------------*/
 #define ROM_START              ((uint32_t)0x90000000)
 #define ROM_SIZE               (16384)
 #define ROM_END                ((uint32_t)(ROM_START + ROM_SIZE * 1024))

#define RAM_START              (0x24000000)
#define RAM_SIZE               (512)
#define RAM_END                (RAM_START + RAM_SIZE * 1024)

/*-------------------------- ROM/RAM CONFIG END --------------------------*/

/*-------------------------- CLOCK CONFIG BEGIN --------------------------*/

#define BSP_CLOCK_SOURCE                  ("HSE")
#define BSP_CLOCK_SOURCE_FREQ_MHZ         ((int32_t)0)
#define BSP_CLOCK_SYSTEM_FREQ_MHZ         ((int32_t)480)

/*-------------------------- CLOCK CONFIG END --------------------------*/

/*-------------------------- UART CONFIG BEGIN --------------------------*/

/** After configuring corresponding UART or UART DMA, you can use it.
 *
 * STEP 1, define macro define related to the serial port opening based on the serial port number
 *                 such as     #define BSP_USING_UATR1
 *
 * STEP 2, according to the corresponding pin of serial port, define the related serial port information macro
 *                 such as     #define BSP_UART1_TX_PIN       "PA9"
 *                             #define BSP_UART1_RX_PIN       "PA10"
 *
 * STEP 3, if you want using SERIAL DMA, you must open it in the RT-Thread Settings.
 *                 RT-Thread Setting -> Components -> Device Drivers -> Serial Device Drivers -> Enable Serial DMA Mode
 *
 * STEP 4, according to serial port number to define serial port tx/rx DMA function in the board.h file
 *                 such as     #define BSP_UART1_RX_USING_DMA
 *
 */

#ifdef BSP_USING_UART1
#define BSP_UART1_TX_PIN       "PA9"
#define BSP_UART1_RX_PIN       "PA10"
#endif

#ifdef BSP_USING_UART4
#define BSP_UART4_TX_PIN       "PA0"
#define BSP_UART4_RX_PIN       "PI9"
#endif

#ifdef BSP_USING_UART6
#define BSP_UART6_TX_PIN       "PC6"
#define BSP_UART6_RX_PIN       "PC7"
#endif

#define STM32_FLASH_START_ADRESS       ROM_START
#define STM32_FLASH_SIZE               ROM_SIZE
#define STM32_FLASH_END_ADDRESS        ROM_END

#define RAM_START              (0x24000000)
#define RAM_SIZE               (512)
#define RAM_END                (RAM_START + RAM_SIZE * 1024)

#define STM32_SRAM1_SIZE               RAM_SIZE
#define STM32_SRAM1_START              RAM_START
#define STM32_SRAM1_END                RAM_END

四、在main.c中添加QSPI地址映射

VTOR寄存器存放的是中断向量表的起始地址。所以我们可以在main函数添加如下代码实现中断向量表的起始地址的重设:

对于这个0x90000000地址怎么来的,打开参考手册,可以看到QSPI的起始地址为0x90000000

添加如下代码,使得设备初始化时进行中断向量表的起始地址的重设。

通过片外的QSPI存储我们的程序,片内的flash是用于存储bootloader,从而STM32_FLASH_START_ADRESS ((uint32_t)0x08000000)的地址则是用于bootloader来跳转到0x90000000地址来运行我们用户的APP代码。

#include "stm32h7xx.h"
static int vtor_config(void)

    /* Vector Table Relocation in Internal QSPI_FLASH */
    SCB->VTOR = QSPI_BASE;
    return 0;

INIT_BOARD_EXPORT(vtor_config);

五、配置MDK中的下载选项

打开mdk中的魔术棒,点击Debug选项

ART-Pi_W25Q64.FLM下载算法在 "sdk-bsp-stm32h750-realthread-artpi\\debug\\flm\\ART-Pi_W25Q64.FLM"这个目录下,把ART-Pi_W25Q64.FLM拷贝替换到MDK安装目录Keil_v5\\ARM\\Flash下,RAM for Algorithm 需要调整成 0x4000。STM32H750 执行片外 QSPI FLASH 上的程序需要有一个 bootloader 来跳转过去,出厂前已经默认烧录了 bootloader,可以运行,如果不小心擦除了,可以重新烧录 bootloader。

至此一个ART-PI的MDK BSP模板工程就做好了,接下来将使用该模板工程进行外设的配置与验证

以上是关于RT-Thread&ART-PIBSP制作过程的主要内容,如果未能解决你的问题,请参考以下文章

RT-Thread&ART-PIBSP制作过程

RT-Thread&BearPi 开发笔记 -- 为小熊派开发板制作 RT-Thread BSP 包

国产MCU移植手把手教你使用RT-Thread制作GD32F103系列BSP

国产MCU移植手把手教你使用RT-Thread制作GD32系列BSP

《嵌入操作系统 - RT-Thread开发笔记》手把手教你使用RT-Thread制作GD32系列BSP

手把手教你使用RT-Thread制作GD32系列BSP