ymodem的内部falsh和外部falsh的写入函数的不同,带来的外设传输1024字节不能传输问题

M2的ymodem写falsh(sFLASH_WritePage)

/**
​
- @brief  Writes more than one byte to the FLASH with a single WRITE cycle 
- (Page WRITE sequence).
- @note   The number of byte can't exceed the FLASH page size.
- @param  pBuffer: pointer to the buffer  containing the data to be written
- to the FLASH.
- @param  WriteAddr: FLASH's internal address to write to.
- @param  NumByteToWrite: number of bytes to write to the FLASH, must be equal
- or less than "sFLASH_PAGESIZE" value.
- @retval None
  */
  void sFLASH_WritePage(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
  {
    /*!< Enable the write access to the FLASH */
    sFLASH_WriteEnable();
​
  /*!< Select the FLASH: Chip Select low */
  sFLASH_CS_LOW();
  /*!< Send "Write to Memory " instruction */
  sFLASH_SendByte(sFLASH_CMD_WRITE);
  /*!< Send WriteAddr high nibble address byte to write to */
  sFLASH_SendByte((WriteAddr & 0xFF0000) >> 16);            //第一步
  /*!< Send WriteAddr medium nibble address byte to write to */
  sFLASH_SendByte((WriteAddr & 0xFF00) >> 8);               //第二步
  /*!< Send WriteAddr low nibble address byte to write to */
  sFLASH_SendByte(WriteAddr & 0xFF);
​
  /*!< while there is data to be written on the FLASH */
  while (NumByteToWrite--)                                   //第三步
  {
    /*!< Send the current byte */
    sFLASH_SendByte(*pBuffer);
    /*!< Point on the next byte to be written */
    pBuffer++;
  }
​
  /*!< Deselect the FLASH: Chip Select high */
  sFLASH_CS_HIGH();
​
  /*!< Wait the end of Flash writing */
  sFLASH_WaitForWriteEnd();
}
//nor_falsh,页编程

页编程两种方式:Page Program和Quad Page Program (32H)

SPI Flash仅支持页编程(GDP5Q28E页大小256字节),所有其它大批量数据的写入都是以页为单位。这里注意所说的页编程含义,页编程分为以上代码的三步。

页编程的含义恰恰就体现在第3步了,如果用户设置的“起始地址+数据长度”所确定的地址范围超过了此起始地址所在的页,地址自增不会超过页范围,而是重新回到了此页的首地进行编写。

注:擦除大小最小为一个扇区(4KB)

页回卷

许多SPI Flash设备来说,单次页编程操作通常限于页的最大容量。如果尝试写入的数据量超过了页的限制,那么超出的部分数据将不会被写入,或者可能导致写入操作失败。此外,如果未正确管理地址,写入操作可能会覆盖之前存储的数据,导致数据丢失。

如何处理超过页大小的数据写入?

1.分页写入: 首先,确定SPI Flash的页大小。 然后,将需要写入的数据分割成多个不超过页大小的数据块。 对于每个数据块,使用页编程命令将其写入到Flash的相应页中。 在写入每个数据块之前,确保指定了正确的页地址。

2.地址管理: 使用循环或递增的方式来管理地址,确保每次写入操作都指向正确的页。 在写入完一个页后,更新地址以指向下一个页。

3.错误处理: 检查写入操作的状态,确保数据已正确写入。 如果发生错误(如地址超出范围、写入失败等),则采取适当的错误处理措施。

4.考虑边界情况: 如果写入的数据量恰好是页大小的整数倍,则处理起来相对简单。 如果写入的数据量不是页大小的整数倍,则最后一个页可能只被部分写入。在这种情况下,需要特别小心以确保不会覆盖或丢失数据。

M2_BOOT的ymodem写入falsh函数(FLASH_If_Writ)

​
/**
​
- @brief  This function writes a data buffer in flash (data are 32-bit aligned).
- @note   After writing data buffer, the flash content is checked.
- @param  FlashAddress: start address for writing data buffer
- @param  Data: pointer on data buffer
- @param  DataLength: length of data buffer (unit is 32-bit word)
- @retval 0: Data successfully written to Flash memory
- 1: Error occurred while writing data in Flash memory
- 2: Written Data in flash memory is different from expected one
    */
  uint32_t FLASH_If_Write(__IO uint32_t* FlashAddress, uint32_t* Data ,uint32_t DataLength)
  {
    uint32_t i = 0;
    for (i = 0; (i < DataLength) && (*FlashAddress <= (USER_FLASH_END_ADDRESS-4)); i++)
    {
  /* Device voltage range supposed to be [2.7V to 3.6V], the operation will
     be done by word */
  if (FLASH_ProgramWord(*FlashAddress, *(uint32_t*)(Data+i)) == FLASH_COMPLETE)
  {
   /* Check the written value */
    if (*(uint32_t*)*FlashAddress != *(uint32_t*)(Data+i))
    {
      /* Flash content doesn't match SRAM content */
      return(2);
    }
    /* Increment FLASH destination address */
    *FlashAddress += 4;
  }
  else
  {
    /* Error occurred while writing data in Flash memory */
    return (1);
  }
    }
​
  return (0);
}

上述两个代码段的主要区别在于它们操作的Flash类型、数据写入的方式以及是否直接处理Flash的物理层细节。

第一个代码段 (sFLASH_WritePage)

  • 操作对象:很可能是通过SPI或其他串行接口连接的外部串行Flash。

  • 数据写入方式:按字节(byte)为单位进行写入,这反映了SPI Flash通常的写入模式。

  • 地址处理:直接通过发送地址字节来指定写入位置,包括地址的高位、中位和低位字节。

  • 物理层交互:直接控制Flash的片选(CS)信号、发送写入指令和地址字节,以及数据字节,这显示了与Flash硬件的直接交互。

  • 错误处理:通过sFLASH_WaitForWriteEnd()函数等待写入操作完成,但代码中未直接显示写入失败的错误处理逻辑(可能包含在sFLASH_WaitForWriteEnd()内部)。

  • 抽象级别:较低,需要处理与Flash硬件直接交互的所有细节。

第二个代码段 (FLASH_If_Write)

  • 操作对象:可能是微控制器(MCU)内部集成的Flash存储器,或者是一个通过某种接口(如SPI、QSPI等)连接的外部Flash,但函数内部使用了HAL库或类似的抽象层来隐藏物理层细节。

  • 数据写入方式:按uint32_t(即4字节)为单位进行写入,这可能是因为内部Flash或外部Flash接口支持按字(word)或更大的块大小进行写入。

  • 地址处理:通过指针算术来递增Flash地址,而不是直接发送地址字节。

  • 错误检查:在写入后验证Flash中的数据是否与预期匹配,增加了数据完整性的检查。

  • 抽象级别:较高,隐藏了与Flash硬件直接交互的细节。

总结

两个代码段的主要区别在于它们操作的Flash类型、数据写入的方式、地址处理的方式、错误检查的详细程度以及抽象级别的不同。第一个代码段更适合于处理内部Flash或高度抽象化的外部Flash接口,而第二个代码段则更直接地反映了与SPI Flash等外部串行Flash的交互过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值