673835452 发表于 2021-12-16 10:19:50

STM32H750VB 外部程序QSPI模式,不成功。

本帖最后由 673835452 于 2021-12-16 10:33 编辑

STM32H750VB
硬件:使用W25Q128JV和W25Q64JV都试过了,   原理图和PCB图如下图所示,PCB做了等长处理

软件:目前烧录算法可以使用,并且开启校验模式。可以查到尝试ID,可以写读数据。
问题:STM32H750VB 内部128K存boot   外部qspi flash存app程序 。

目前无法跳转app,程序参考硬汉、野火、原子的都不行。运行到跳转字段时的时候晶振就不起振了。
boot mian函数:
int main(void)
{
/* USER CODE BEGIN 1 */
        MPU_Config();
        CPU_CACHE_Enable();
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
        //HAL_GPIO_WritePin(LOCK_GPIO_GPIO_Port,LOCK_GPIO_Pin,GPIO_PIN_SET);
MX_USART1_UART_Init();
// MX_SPI1_Init();
// MX_SPI2_Init();
/* USER CODE BEGIN 2 */
        printf("boot ok\r\n");
       
        clock_information();
//       
        MX_QUADSPI_Init();
        W25QXX_Init();
       
        printf("id:%X\r\n",W25QXX_MftrDeviceID());

        QSPI_EnableMemoryMappedMode();

        SCB_DisableICache();
        SCB_DisableDCache();

       

JumpToApp();/* 跳转到应用程序 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
boot映射代码:测试映射应该也没问题

uint8_t QSPI_EnableMemoryMappedMode(void)
{
QSPI_CommandTypeDef cmd;
QSPI_MemoryMappedTypeDef mem;

// Configure the command for the read instruction
cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE;
cmd.Instruction = W25X_FastRead;

cmd.AddressMode = QSPI_ADDRESS_4_LINES;
cmd.AddressSize = QSPI_ADDRESS_24_BITS;

cmd.DataMode = QSPI_DATA_4_LINES;

cmd.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;

cmd.DummyCycles = 8;

cmd.DdrMode = QSPI_DDR_MODE_DISABLE;
cmd.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
cmd.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;

// Configure the memory mapped mode
mem.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;
mem.TimeOutPeriod = 0;

if (HAL_QSPI_MemoryMapped(&hqspi, &cmd, &mem) != HAL_OK)
{
    return 1;
}

return 0;
}
boot跳转程序:
void JumpToApp(void)
{
        uint32_t i=0;
        void (*AppJump)(void);         /* 声明一个函数指针 */
        __IO uint32_t AppAddr = 0x90000000;/* APP 地址 0x90000000*/
   

    /* 关闭全局中断 */
        DISABLE_INT();
   
    /* 设置所有时钟到默认状态,使用HSI时钟 */
        HAL_RCC_DeInit();
   
        /* 关闭滴答定时器,复位到默认值 */
        SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;

        /* 关闭所有中断,清除所有中断挂起标志 */
        for (i = 0; i < 8; i++)
        {
                NVIC->ICER=0xFFFFFFFF;
                NVIC->ICPR=0xFFFFFFFF;
        }       

        /* 使能全局中断 */
        ENABLE_INT();

        /* 跳转到应用程序,首地址是MSP,地址+4是复位中断服务程序地址 */
        AppJump = (void (*)(void)) (*((uint32_t *) (AppAddr + 4)));

        /* 设置主堆栈指针 */
        __set_MSP(*(uint32_t *)AppAddr);
       
        /* 在RTOS工程,这条语句很重要,设置为特权级模式,使用MSP指针 */
        __set_CONTROL(0);

        /* 跳转到系统BootLoader */
        AppJump();

        /* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */
        while (1)
        {

        }
}app mian函数:
int main(void)
{
/* USER CODE BEGIN 1 */
        SCB->VTOR = QSPI_BASE;
//        __enable_irq();
        SCB_EnableICache();
        SCB_EnableDCache();
       
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
MPU_Config( );
        HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/*Initialize all configured peripherals */
MX_GPIO_Init();
        HAL_GPIO_WritePin(LOCK_GPIO_GPIO_Port,LOCK_GPIO_Pin,GPIO_PIN_RESET);
// MX_QUADSPI_Init();
MX_USART1_UART_Init();
//MX_SPI1_Init();
//MX_SPI2_Init();
/* USER CODE BEGIN 2 */
        printf("APP ok!\r\n");

/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
    /* USER CODE END WHILE */
                HAL_GPIO_WritePin(LOCK_GPIO_GPIO_Port,LOCK_GPIO_Pin,GPIO_PIN_SET);
                HAL_Delay(100);
                HAL_GPIO_WritePin(LOCK_GPIO_GPIO_Port,LOCK_GPIO_Pin,GPIO_PIN_RESET);
                HAL_Delay(100);
    /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}APP MDK 设置:


wye11083 发表于 2021-12-16 12:37:57

。。。你自己在app里把时钟都复位了,还指望晶振不变?

673835452 发表于 2021-12-16 13:37:51

wye11083 发表于 2021-12-16 12:37
。。。你自己在app里把时钟都复位了,还指望晶振不变?

你好SystemClock_Config(); 这是时钟初始化,cubemx 生成的
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_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 = 5;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
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();
}
}

wye11083 发表于 2021-12-16 15:15:40

673835452 发表于 2021-12-16 13:37
你好SystemClock_Config(); 这是时钟初始化,cubemx 生成的

app代码里面不要配时钟!闲着没事干了。app只执行用户算法代码。所有初始化都在bootloader里面做!

想想你的电脑,配置cpu /内存是在进入桌面之后你再手动配吗?这样的电脑你觉得有几个人能用起来?单片机一样的道理。

蓝蓝的恋 发表于 2021-12-16 16:09:09

时钟只能在boot里配置

amigenius 发表于 2021-12-16 17:27:09

楼上两位不对,BootLoader和App可以分别配置时钟,这个不影响,而且这样可以多个项目使用同一BootLoader。现在关键是您跳转后,App是否有开始执行??并且,App的中断向量起始地址需要在App的程序里面设置(MDK没得设),App能进入,就再重新配置时钟等,反正App里您可以视为一个完全独立的单机程序,唯一不同只是起始地址和向量表地址不同而已。

amigenius 发表于 2021-12-16 17:30:32

中断向量表基址在System_stm32h7xx.c里的SystemInit函数内,SCB->VTOR = FLASH_BANK1_BASE | VECT_TAB_OFFSET;       /* Vector Table Relocation in Internal FLASH */

saccapanna 发表于 2021-12-16 18:39:13

本帖最后由 saccapanna 于 2021-12-16 18:40 编辑

Boot 与 APP 解耦分离的思路是对的,两个程序各不相关。
但是要注意,你在 Boot 中,初始化时钟,然后 QSPI 的时钟使用的那一路?
不要在 APP 启动时,再把 QSPI 的时钟关闭了吧,QSPI的驱动和映射不能复位吧?不然相当于读取 QSPI 失效了,当然无法运行。

saccapanna 发表于 2021-12-16 18:44:42

也就是说,你可以重新初始化时钟,可以做一切硬件的初始化,但是无论做什么,你必须要确保 QSPI 工作正常,并且映射正常。除非,你把 FLASH 数据全部加载到 RAM 中运行,反正 STM32H750 SRAM 足够大。

radar_12345 发表于 2021-12-16 22:45:10

QSPI FLASH 数据全部加载到 RAM 有没有人成功过?不知道抗干扰怎么样?

ackyee 发表于 2021-12-17 10:05:17

没有做分散文件吧?

673835452 发表于 2021-12-17 11:16:26

saccapanna 发表于 2021-12-16 18:39
Boot 与 APP 解耦分离的思路是对的,两个程序各不相关。
但是要注意,你在 Boot 中,初始化时钟,然后 QSPI ...

APP启动没有把QSPI时钟复位,
BOOT复位时钟注释掉也不行。

673835452 发表于 2021-12-17 11:18:06

ackyee 发表于 2021-12-17 10:05
没有做分散文件吧?

bootapp 模式应该不需要做分散文件吧,参考别人的都没有做

初音之恋 发表于 2021-12-17 11:26:51

boot我只做自升级,所有配置都在APP,比如手机下载完成后自动安装,boot只负责安装或者固件初始化啥的,一般都是向量地址错了所以跑不起来

goodjob2 发表于 2021-12-18 00:48:17

QSPI时钟要用HCLK3的,不能用PLL之后的。另外,QSPI FLASH里的程序 ,不要再次初始化QSPI了

saccapanna 发表于 2021-12-18 14:09:49

radar_12345 发表于 2021-12-16 22:45
QSPI FLASH 数据全部加载到 RAM 有没有人成功过?不知道抗干扰怎么样?

理论是应该是完全没问题的,我目前128KB,没用外部FLASH,升级部分就是运行在RAM中的。
不过完全加载到 SRAM 运行没有试验过,稳定性不知道。
加载完毕后,配置 MMU,把RAM的一段空间,设置为只读,应该问题不大。
页: [1]
查看完整版本: STM32H750VB 外部程序QSPI模式,不成功。