硬汉嵌入式论坛

 找回密码
 立即注册
查看: 237|回复: 2
收起左侧

[开发工具] 离线烧录器-STM32H750-FLASH写入总是0,校验失败

[复制链接]

1

主题

1

回帖

4

积分

新手上路

积分
4
发表于 2025-6-20 15:21:54 | 显示全部楼层 |阅读模式
硬汉哥和各位网友好,有个问题咨询一下,自己由于工作原因,制作了一个离线烧录器。用来对产线产品进行批量烧录。使用的是GPIO模拟SWD协议,在之前开发F1、F4、U575的时候都是没问题的。最近想尝试制作H750版本的时候出了问题。
由于H750的FLASH是带ECC校验的,不知道该怎么写FLASH了。
以前M33内核U575的烧录的代码如下,是能够正常写入到单片机的FLASH的。
[C] 纯文本查看 复制代码
for( u32 tmp11 = 0;tmp11 < HowMany4K; tmp11++ )  // 写Flash的操作,每次操作8K字节
			{
						
				u32 Address = userfile.ProgramStartAddress + tmp11 * 0x1000;  // 起始操作地址
				W25QXX_Read( &stm32u5xx_flash_8k_tmp.IndexLen8[0] , userfile.ProgramSaveAtW25QAddress + tmp11 * 0x1000, 0x1000); // 4k大小在16进行下,就是0x1000
						
				writeAP( AP_CSW,0x43000012 );   // 长度为32bit,同时地址自动增加
				writeAP( AP_TAR, Address );  		// 要写入到FLASH上的地址!
				for( u32 tmp12 = 0;tmp12 < 0x1000; tmp12 += 4 ) // 写入4K,理论上brust模式每次可以写入8个4字,共128个字节,但是实测可以一直写,可能大文件需要在写入128个字节后去读取NSSR寄存器状态
				{
					#define SWD_AUTO_ADDRESS_ADD_VALUE 0x400   // 特别警告:STM32U5系列的地址自增大小为1024个
					if( ((Address + tmp12) % SWD_AUTO_ADDRESS_ADD_VALUE) == 0 ) // 说明到了1k临界点,需要重新写地址
					{
						writeAP( AP_TAR, Address + tmp12 );  // 地址!
					}
					writeAP(AP_DRW, stm32u5xx_flash_8k_tmp.IndexLen32[tmp12 / 4]); 
				}
				{ // 程序进度区!程序进度是8K大小!
					unsigned int tmp13 = 50 * (tmp11 + 1) / HowMany4K;
					ESP32_lvgl_mutex_lock();
					lv_bar_set_value(guider_ui.screen_3_bar_1,tmp13,LV_ANIM_ON);		//写入和校验各占50%进度条
					ESP32_lvgl_mutex_unlock();
					ESP_LOGI(TAG_DOWNLOAD,"the chip is programed %d %%...",(uint8_t)tmp13);
				}
				vTaskDelay(pdMS_TO_TICKS(1));		//在此处增加一个延时,以免占用线程太久,造成的速度损失测量后再确定
}


下面是具体的疑惑
一、使用上述的逻辑,对H750的FLASH进行写入,发现写进去的全是0.






二、用数据分析仪监控了一下STLINK是如何写入的,发现STLINK并不是直接将bin文件写入到内置0x08000000地址,而是直接将bin文件先写入到AXI_RAM中,好奇怪,这个地方难道是用上了AXI_RAM自带的ECC校验功能?
因为STLINK的协议过程很长,还没具体分析出在写入FLASH之前,是不是对AXI_RAM进行了一些设置。这个地方需要重点排查。
QQ截图20250620150356.png

三、当时已经没头绪了,所以就看了一下HAL库中是如何写FLASH的,发现HAL库文件在定义FLASH写入的时候是一次性固定写进去32个字,也就是256bit,这个和手册上描述的是相符的,256bit配10bit的ECC校验位。所以我想问一下,在FLASH写入256bit内容后,增加的10个bitECC校验位是在隐藏的FLASH区域内吗?还是说我写入256bit,那FLASH区域就直接减少266bit?下面的代码可以看到单次固定写8*4=32个字节
[C] 纯文本查看 复制代码
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
{
  HAL_StatusTypeDef status;
  __IO uint32_t *dest_addr = (__IO uint32_t *)FlashAddress;
  __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
  uint32_t bank;
  uint8_t row_index = FLASH_NB_32BITWORD_IN_FLASHWORD;

  /* Check the parameters */
  assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
  assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));

  /* Process Locked */
  __HAL_LOCK(&pFlash);

#if defined (FLASH_OPTCR_PG_OTP)
  if((IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress)) || (IS_FLASH_PROGRAM_ADDRESS_OTP(FlashAddress)))
#else
  if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
#endif /* FLASH_OPTCR_PG_OTP */
  {
    bank = FLASH_BANK_1;
    /* Prevent unused argument(s) compilation warning */
    UNUSED(TypeProgram);
  }
#if defined (DUAL_BANK)
  else if(IS_FLASH_PROGRAM_ADDRESS_BANK2(FlashAddress))
  {
    bank = FLASH_BANK_2;
  }
#endif /* DUAL_BANK */
  else
  {
    return HAL_ERROR;
  }

  /* Reset error code */
  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;

  /* Wait for last operation to be completed */
  status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);

  if(status == HAL_OK)
  {
#if defined (DUAL_BANK)
    if(bank == FLASH_BANK_1)
    {
#if defined (FLASH_OPTCR_PG_OTP)
      if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
      {
        /* Set OTP_PG bit */
        SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
      }
      else
#endif /* FLASH_OPTCR_PG_OTP */
      {
        /* Set PG bit */
        SET_BIT(FLASH->CR1, FLASH_CR_PG);
      }
    }
    else
    {
      /* Set PG bit */
      SET_BIT(FLASH->CR2, FLASH_CR_PG);
    }
#else /* Single Bank */
#if defined (FLASH_OPTCR_PG_OTP)
      if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
      {
        /* Set OTP_PG bit */
        SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
      }
      else
#endif /* FLASH_OPTCR_PG_OTP */
      {
        /* Set PG bit */
        SET_BIT(FLASH->CR1, FLASH_CR_PG);
      }
#endif /* DUAL_BANK */

    __ISB();
    __DSB();

#if defined (FLASH_OPTCR_PG_OTP)
    if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
    {
      /* Program an OTP word (16 bits) */
      *(__IO uint16_t *)FlashAddress = *(__IO uint16_t*)DataAddress;
    }
    else
#endif /* FLASH_OPTCR_PG_OTP */
    {
      /* Program the flash word */
      do
      {
        *dest_addr = *src_addr;
        dest_addr++;
        src_addr++;
        row_index--;
     } while (row_index != 0U);
    }

    __ISB();
    __DSB();

    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);

#if defined (DUAL_BANK)
#if defined (FLASH_OPTCR_PG_OTP)
    if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
    {
      /* If the program operation is completed, disable the OTP_PG */
      CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
    }
    else
#endif /* FLASH_OPTCR_PG_OTP */
    {
      if(bank == FLASH_BANK_1)
      {
        /* If the program operation is completed, disable the PG */
        CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
      }
      else
      {
        /* If the program operation is completed, disable the PG */
        CLEAR_BIT(FLASH->CR2, FLASH_CR_PG);
      }
    }
#else /* Single Bank */
#if defined (FLASH_OPTCR_PG_OTP)
    if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
    {
      /* If the program operation is completed, disable the OTP_PG */
      CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
    }
    else
#endif /* FLASH_OPTCR_PG_OTP */
    {
      /* If the program operation is completed, disable the PG */
      CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
    }
#endif /* DUAL_BANK */
  }

  /* Process Unlocked */
  __HAL_UNLOCK(&pFlash);

  return status;
}

之前看硬汉哥的H7TOOL是支持离线烧录的,所以想咨询一下,如果不使用烧录算法,使用SWD模拟的情况下,该如何处理带ECC校验的FLASH写入。谢谢。

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2025-6-21 07:47:37 | 显示全部楼层
针对你第2个问题的回复:

通用的下载方式不是直接操作的FLASH,是通过将带有初始化,擦除,编程和校验函数的算法文件加载到目标芯片内部RAM里面,然后控制芯片执行对应的函数即可。
回复

使用道具 举报

1

主题

1

回帖

4

积分

新手上路

积分
4
 楼主| 发表于 2025-6-21 09:40:25 | 显示全部楼层
eric2013 发表于 2025-6-21 07:47
针对你第2个问题的回复:

通用的下载方式不是直接操作的FLASH,是通过将带有初始化,擦除,编程和校验函 ...

嗯嗯,是的,现在大部分都是依赖FLM算法文件进行操作。只不过之前写的程序是直接操作FLASH寄存器的,这次出了问题,只是想搞清楚到底应该怎么操作才合适。不过还是谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 19:57 , Processed in 0.073705 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表