cmvr_head/board/board.c

149 lines
5.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-06 SummerGift first version
*/
#include "board.h"
/**
* @brief System Clock Configuration 因为boot 开启了QSPI的时钟故这里也要开启。要和boot 保持一致,如何要和
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {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_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_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 = 48;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 5;
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_DIV1;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV4;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
int MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
HAL_MPU_Disable();
// Region 0: 默认 4GB NO_ACCESS保留你原来的
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x00000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; // 默认都禁执行
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
// Region 1: QSPI XIP 区域 0x9000_0000 (W25Q64 = 8MB)
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1; // 编号更大 => 优先级更高
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_8MB;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_PRIV_RO_URO; // 只读;
// 关键XIP 必须允许取指(不要 XN
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; // 可执行
// QSPI XIP 区域0x9000_0000~)的 MPU 属性按“Normal memory”处理以提升性能
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; // 不共享:对只读代码区一般不需要共享语义
// 注意STM32 没硬件缓存一致性DMA 一致性仍靠 clean/invalidate 或 non-cacheable buffer
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; // 可缓存:允许进入 D-Cache读数据更快XIP 性能更好)
// 升级写完新固件后跳转前建议 Invalidate I/D Cache避免跑到旧缓存
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; // 可缓冲:允许写缓冲/合并,提高总线访问效率(配合 cacheable 的常用组合)
// 不适用于外设寄存器区,但对 QSPI 映射的“内存型”区域一般没问题
HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
return 0;
}
#define RT_APP_PART_ADDR STM32_FLASH_START_ADDRESS
static int ota_app_vtor_reconfig(void)
{
SCB->VTOR = RT_APP_PART_ADDR;
return 0;
}
INIT_BOARD_EXPORT(ota_app_vtor_reconfig);
INIT_BOARD_EXPORT(MPU_Config);
// rt thread 的
// void __libc_init_array(void)
// {
// /* we not use __libc init_aray to initialize C++ objects */
// /* __libc_init_array is ARM code, not Thumb; it will cause a hardfault. */
// }
// 没有定义不能初始化C++ 的static 变量,故需要添加这个函数
typedef int (*init_func_t)(void);
extern init_func_t __preinit_array_start[];
extern init_func_t __preinit_array_end[];
extern init_func_t __init_array_start[];
extern init_func_t __init_array_end[];
int rt_cpp_init(void)
{
for (init_func_t *p = __preinit_array_start; p < __preinit_array_end; ++p) (*p)();
for (init_func_t *p = __init_array_start; p < __init_array_end; ++p) (*p)();
}
INIT_PLATFORM_EXPORT(rt_cpp_init);