跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
折叠
品牌标识

YunTu Forum

YTMicro.com
  1. 主页
  2. Discussion & Question
  3. YTM32B1H系列
  4. MCAL接口写完FLS后,偶发性出现一直不空闲问题

MCAL接口写完FLS后,偶发性出现一直不空闲问题

已定时 已固定 已锁定 已移动 YTM32B1H系列
16 帖子 2 发布者 269 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • Liam.LiuL 离线
    Liam.LiuL 离线
    Liam.Liu
    写于 最后由 编辑
    #1
    #define FLASH_WRITE_UNIT ( 32 )        // 固定写入单位
    #define FLASH_TIMEOUT    ( 10000000 )  // 超时时间
    bool bsw_fls_write_pflash1_1mb( uint32_t AddrOffset, const uint8_t* data, uint32_t len )
    {
        uint32_t startAddress                    = 0;
        uint32_t alignedLen                      = 0;
        uint32_t i                               = 0;
        uint32_t chunkSize                       = 0;
        uint32_t timeout                         = 0;
        uint8_t  alignedData[ FLASH_WRITE_UNIT ] = { 0xFF };  // 预填充 0xFF
        uint8_t  readBuffer[ FLASH_WRITE_UNIT ]  = { 0 };     // 读取缓存初始化
    
        if ( data == NULL || len == 0 )
        {
            return false;
        }
    
        startAddress = Fls_Config.SectorList[ FlsConf_FlsConfigSet_PFLASH1_1MB ].SectorStartAddress + AddrOffset;
        alignedLen   = ( ( len + ( FLASH_WRITE_UNIT - 1 ) ) / FLASH_WRITE_UNIT ) * FLASH_WRITE_UNIT;  // 向上取整到 32 字节对齐
    
        // 按 32 字节批量写入
        for ( i = 0; i < alignedLen; i += FLASH_WRITE_UNIT )
        {
            chunkSize = ( i + FLASH_WRITE_UNIT <= len ) ? FLASH_WRITE_UNIT : ( len - i );
            memset( alignedData, 0xFF, FLASH_WRITE_UNIT );  // 先填充 0xFF
            memcpy( alignedData, data + i, chunkSize );     // 复制实际数据
    
            // 超时等待 Flash 空闲
            timeout = FLASH_TIMEOUT;
            while ( --timeout > 0 )
            {
                Fls_MainFunction( );
                if ( Fls_GetStatus( ) == MEMIF_IDLE )
                {
                    break;
                }
    
                if ( timeout == 0 )
                {
                    return false;
                }
            }
    
            // 写入 Flash
            timeout = 50;
            while ( --timeout > 0 )
            {
                if ( !Fls_Write( startAddress + i, alignedData, FLASH_WRITE_UNIT ) )
                {
                    break;
                }
    
                if ( timeout == 0 )
                {
                    return false;  // 写入失败
                }
            };
    
            // 超时等待 Flash 空闲
            timeout = FLASH_TIMEOUT;
            while ( --timeout > 0 )
            {
                Fls_MainFunction( );
                if ( Fls_GetStatus( ) == MEMIF_IDLE )
                {
                    break;
                }
    
                if ( timeout == 0 )
                {
                    return false;
                }
            }
    
            memset( readBuffer, 0, FLASH_WRITE_UNIT );  // 确保读取缓冲区清空
    
            timeout = 50;
            while ( --timeout > 0 )
            {
                if ( !Fls_Read( startAddress + i, readBuffer, FLASH_WRITE_UNIT ) )
                {
                    break;
                }
    
                if ( timeout == 0 )
                {
                    return false;  // 写入失败
                }
            };
    
            // 等待读取完成
            timeout = FLASH_TIMEOUT;
            while ( --timeout > 0 )
            {
                Fls_MainFunction( );
                if ( Fls_GetStatus( ) == MEMIF_IDLE )
                {
                    break;
                }
    
                if ( timeout == 0 )
                {
                    return false;
                }
            }
    
            // 进行数据比对
            if ( memcmp( readBuffer, alignedData, FLASH_WRITE_UNIT ) != 0 )
            {
                return false;  // 校验失败
            }
        }
    
        return true;
    }
    

    以上是我写MCU内部FLS的功能代码,作用是把数据写入1mb的pflash1,以实现A/B SWAP。
    现在发现,在调用完Fls_Read后,在等待读取完成代码段中,Fls_GetStatus( )一直不返回MEMIF_IDLE,导致任务卡顿。

            timeout = 50;
            while ( --timeout > 0 )
            {
                if ( !Fls_Read( startAddress + i, readBuffer, FLASH_WRITE_UNIT ) )
                {
                    break;
                }
    
                if ( timeout == 0 )
                {
                    return false;  // 写入失败
                }
            };
    
            // 等待读取完成
            timeout = FLASH_TIMEOUT;
            while ( --timeout > 0 )
            {
                Fls_MainFunction( );
                if ( Fls_GetStatus( ) == MEMIF_IDLE )
                {
                    break;
                }
    
                if ( timeout == 0 )
                {
                    return false;
                }
            }
    

    请问是我这个函数代码的逻辑有问题吗?

    1 条回复 最后回复
    0
    • Liam.LiuL 离线
      Liam.LiuL 离线
      Liam.Liu
      写于 最后由 编辑
      #2

      测试反馈在升级操作,擦写pflash时,给板子进行断电重启。断电重启完再重新执行升级流程时,有较大概率复现。

      1 条回复 最后回复
      0
      • houjun_xiaoH 离线
        houjun_xiaoH 离线
        houjun_xiao YunTu
        写于 最后由 编辑
        #3

        正常情况下这个逻辑是没有问题的,但是你们这个写之前有擦除操作吗?代码里面没有体现擦除的动作,这个一定要求有。另外就是你可以在读取之前增加一个GetResult, 检查一下前面一次写的操作是否成功。按照你的现象描述,可能是因为写flash过程掉电,从而产生了ECC错误,上电之后如果没有擦除再写,那么所有写都是失败的,再读到产生ECC错误的位置,就会导致MCU进入busfault.

        Liam.LiuL 1 条回复 最后回复
        0
        • Liam.LiuL 离线
          Liam.LiuL 离线
          Liam.Liu
          在 回复了 houjun_xiao 最后由 编辑
          #4

          houjun_xiao 每次写之前都有擦除操作,也会判断是否空闲。现在代码逻辑上,读取之前已经有一个GetResult了。这个ECC错误,是只能通过擦除操作来清除吗?

          1 条回复 最后回复
          0
          • houjun_xiaoH 离线
            houjun_xiaoH 离线
            houjun_xiao YunTu
            写于 最后由 编辑
            #5

            单Bit的错误硬件自动纠错;多Bit的ECC错误,只能通过擦除才能清除。你可以先排查是不是因为这个问题导致的,建议在擦除和写完成后都增加一个GetResult判断操作结果。理论上正常的写入或擦除是不会出现ECC错误。

            Liam.LiuL 2 条回复 最后回复
            0
            • Liam.LiuL 离线
              Liam.LiuL 离线
              Liam.Liu
              在 回复了 houjun_xiao 最后由 编辑
              #6

              houjun_xiao 好的,我们按这个方法试试,谢谢!

              1 条回复 最后回复
              0
              • Liam.LiuL 离线
                Liam.LiuL 离线
                Liam.Liu
                在 回复了 houjun_xiao 最后由 编辑
                #7

                houjun_xiao 经过我们的测试,发现有部分MCU在执行完Fls_Erase、Fls_Write、Fls_Read后,就是特别容易出现Fls_GetStatus返回一直为BUSY,实际上,通过读取memory看到,擦写操作是已经完成的了。即使增加很多的延时等待,重复读Fls_GetStatus也一直没法解决。现在我们的操作是,增加一个Fls_Cancel操作,异常情况暂时是没再复现,但是不知道是不是已经根本性解决问题。

                /**
                 * @brief 擦除pflash1 1MB
                 */
                bool bsw_fls_erase_pflash1_1mb( void )
                {
                    uint32_t startAddress = 0;
                    uint32_t sectorSize   = 0;
                    uint32_t timeout      = FLASH_TIMEOUT;
                
                    startAddress          = Fls_Config.SectorList[ FlsConf_FlsConfigSet_PFLASH1_1MB ].SectorStartAddress;
                    sectorSize            = Fls_Config.SectorList[ FlsConf_FlsConfigSet_PFLASH1_1MB ].SectorSize;
                
                    // 超时等待 Flash 空闲
                    timeout               = FLASH_TIMEOUT;
                    while ( --timeout > 0 )
                    {
                        Fls_MainFunction( );
                        if ( Fls_GetStatus( ) == MEMIF_IDLE )
                        {
                            break;
                        }
                
                        if ( timeout == 0 )
                        {
                            return false;
                        }
                    }
                
                    Fls_Erase( startAddress, sectorSize );  // 开始擦除
                
                    timeout = FLASH_TIMEOUT;
                    while ( --timeout > 0 )
                    {
                        Fls_MainFunction( );
                        if ( Fls_GetStatus( ) == MEMIF_IDLE )
                        {
                            return true;  // 擦除成功
                        }
                
                        if ( timeout == FLASH_TIMEOUT / 2 )
                        {
                            Fls_Cancel( );
                            Fls_Erase( startAddress, sectorSize );  // 开始擦除
                        }
                    }
                
                    return false;  // 擦除失败(超时)
                }
                
                bool bsw_fls_write_func( uint32_t Addr, uint8_t* data, uint32_t len )
                {
                    uint32_t timeout = 0;
                
                    // 超时等待 Flash 空闲
                    timeout          = FLASH_TIMEOUT;
                    while ( --timeout > 0 )
                    {
                        Fls_MainFunction( );
                        if ( Fls_GetStatus( ) == MEMIF_IDLE )
                        {
                            break;
                        }
                
                        if ( timeout == 0 )
                        {
                            return false;
                        }
                    }
                
                    // 写入 Flash
                    timeout = 50;
                    while ( --timeout > 0 )
                    {
                        if ( !Fls_Write( Addr, data, FLASH_WRITE_UNIT ) )
                        {
                            break;
                        }
                
                        if ( timeout == 0 )
                        {
                            return false;  // 写入失败
                        }
                    };
                
                    return true;
                }
                /**
                 * @brief 写pflash1 1MB
                 * @param  AddrOffset       地址偏移
                 * @param  data             数据指针
                 * @param  len              数据长度
                 */
                bool bsw_fls_write_pflash1_1mb( uint32_t AddrOffset, const uint8_t* data, uint32_t len )
                {
                    uint32_t startAddress                    = 0;
                    uint32_t alignedLen                      = 0;
                    uint32_t i                               = 0;
                
                    uint32_t chunkSize                       = 0;
                    uint32_t timeout                         = 0;
                    uint8_t  alignedData[ FLASH_WRITE_UNIT ] = { 0xFF };  // 预填充 0xFF
                    uint8_t  readBuffer[ FLASH_WRITE_UNIT ]  = { 0 };     // 读取缓存初始化
                
                    if ( data == NULL || len == 0 )
                    {
                        return false;
                    }
                
                    startAddress = Fls_Config.SectorList[ FlsConf_FlsConfigSet_PFLASH1_1MB ].SectorStartAddress + AddrOffset;
                    alignedLen   = ( ( len + ( FLASH_WRITE_UNIT - 1 ) ) / FLASH_WRITE_UNIT ) * FLASH_WRITE_UNIT;  // 向上取整到 32 字节对齐
                
                    // 按 32 字节批量写入
                    for ( i = 0; i < alignedLen; i += FLASH_WRITE_UNIT )
                    {
                        chunkSize = ( i + FLASH_WRITE_UNIT <= len ) ? FLASH_WRITE_UNIT : ( len - i );
                        memset( alignedData, 0xFF, FLASH_WRITE_UNIT );  // 先填充 0xFF
                        memcpy( alignedData, data + i, chunkSize );     // 复制实际数据
                
                        // 写入 Flash
                        if ( !bsw_fls_write_func( startAddress + i, alignedData, FLASH_WRITE_UNIT ) )
                        {
                            return false;
                        }
                
                        // 超时等待 Flash 空闲
                        timeout = FLASH_TIMEOUT;
                        while ( --timeout > 0 )
                        {
                            Fls_MainFunction( );
                            if ( Fls_GetStatus( ) == MEMIF_IDLE )
                            {
                                break;
                            }
                
                            if ( timeout == FLASH_TIMEOUT / 2 )
                            {
                                Fls_Cancel( );
                                bsw_fls_write_func( startAddress + i, alignedData, FLASH_WRITE_UNIT );
                            }
                        }
                        Fls_Cancel( );
                
                        memset( readBuffer, 0, FLASH_WRITE_UNIT );  // 确保读取缓冲区清空
                
                        timeout = 50;
                        while ( --timeout > 0 )
                        {
                            if ( !Fls_Read( startAddress + i, readBuffer, FLASH_WRITE_UNIT ) )
                            {
                                break;
                            }
                
                            if ( timeout == 0 )
                            {
                                return false;  // 写入失败
                            }
                        };
                
                        // 等待读取完成
                        timeout = FLASH_TIMEOUT;
                        while ( --timeout > 0 )
                        {
                            Fls_MainFunction( );
                            if ( Fls_GetStatus( ) == MEMIF_IDLE )
                            {
                                break;
                            }
                
                            if ( timeout == 0 )
                            {
                                return false;
                            }
                        }
                        bsw_wdg_feed_func( );
                        // 进行数据比对
                        if ( memcmp( readBuffer, alignedData, FLASH_WRITE_UNIT ) != 0 )
                        {
                            return false;  // 校验失败
                        }
                    }
                
                    return true;
                }
                
                /**
                 * @brief 读pflash1 1MB
                 * @param  AddrOffset       地址偏移
                 * @param  data             数据指针
                 * @param  len              数据长度
                 */
                bool bsw_fls_read_pflash1_1mb( uint32_t AddrOffset, uint8_t* data, uint32_t len )
                {
                    uint32_t startAddress = 0;
                    uint32_t timeout      = 0;
                
                    if ( data == NULL || len == 0 )
                    {
                        return false;
                    }
                
                    startAddress = Fls_Config.SectorList[ FlsConf_FlsConfigSet_PFLASH1_1MB ].SectorStartAddress + AddrOffset;
                
                    // 超时等待 Flash 空闲
                    timeout      = FLASH_TIMEOUT;
                    while ( --timeout > 0 )
                    {
                        Fls_MainFunction( );
                        if ( Fls_GetStatus( ) == MEMIF_IDLE )
                        {
                            break;
                        }
                
                        if ( timeout == 0 )
                        {
                            return false;
                        }
                    }
                
                    timeout = 50;
                    while ( --timeout > 0 )
                    {
                        if ( !Fls_Read( startAddress, data, len ) )
                        {
                            break;
                        }
                
                        if ( timeout == 0 )
                        {
                            return false;  // 写入失败
                        }
                    };
                
                    timeout = FLASH_TIMEOUT;
                    while ( --timeout > 0 )
                    {
                        Fls_MainFunction( );
                        if ( Fls_GetStatus( ) == MEMIF_IDLE )
                        {
                            return true;  // 读取成功
                        }
                    }
                
                    return false;  // 超时或读取失败
                }
                
                1 条回复 最后回复
                0
                • houjun_xiaoH 离线
                  houjun_xiaoH 离线
                  houjun_xiao YunTu
                  写于 最后由 编辑
                  #8

                  在调用Fls_Erase,Write,Read之后,原则上是不需要调用Fls_Cancel(除非是应用本身程序有需求,如需要终止当前操作以执行优先级更高的新操作)。方便展示一下你们的YCT配置文件吗?

                  Liam.LiuL 2 条回复 最后回复
                  0
                  • Liam.LiuL 离线
                    Liam.LiuL 离线
                    Liam.Liu
                    在 回复了 houjun_xiao 最后由 编辑
                    #9

                    houjun_xiao 需要展示YCT哪部分

                    1 条回复 最后回复
                    0
                    • houjun_xiaoH 离线
                      houjun_xiaoH 离线
                      houjun_xiao YunTu
                      写于 最后由 编辑
                      #10

                      Fls模块配置的那一部分

                      1 条回复 最后回复
                      0
                      • Liam.LiuL 离线
                        Liam.LiuL 离线
                        Liam.Liu
                        在 回复了 houjun_xiao 最后由 编辑
                        #11

                        houjun_xiao
                        5e1fdb85-bdf7-4c02-8b60-872df41be0cb-image.png
                        a010dd06-5b76-4e9a-b294-f9c57ef8c326-image.png
                        8ac65e90-53ac-403c-837a-e9f0e8d700d6-image.png
                        2789f901-8b96-4e17-bf0d-678849df166c-image.png

                        1 条回复 最后回复
                        0
                        • houjun_xiaoH 离线
                          houjun_xiaoH 离线
                          houjun_xiao YunTu
                          写于 最后由 houjun_xiao 编辑
                          #12

                          image.png你们出现问题的频次大概是多久一次呢,我用你们测试的代码和配置测了一下,没有复现现象。我测试的时候删除了一部分无效调用Fls_MainFunction的代码,你可以对比一下。测试的MCU PLL为200MHz. 另外需要注意,测试写入和读取的时候,长度都是1M, 你需要确认一下这两个测试里面用到的指针的有效范围。

                          /* USER CODE BEGIN Header */
                          /* you can remove the copyright */
                          
                          /*
                           *  Copyright 2020-2023 Yuntu Microelectronics co.,ltd
                           *  All rights reserved.
                           * 
                           *  YUNTU Confidential. This software is owned or controlled by YUNTU and may only be
                           *  used strictly in accordance with the applicable license terms. By expressly
                           *  accepting such terms or by downloading, installing, activating and/or otherwise
                           *  using the software, you are agreeing that you have read, and that you agree to
                           *  comply with and are bound by, such license terms. If you do not agree to be
                           *  bound by the applicable license terms, then you may not retain, install,
                           *  activate or otherwise use the software. The production use license in
                           *  Section 2.3 is expressly granted for this software.
                           * 
                           * @file main.c
                           * @brief 
                           * 
                           */
                          
                          /* USER CODE END Header */
                          #include "Mcal.h"
                          /* Includes ------------------------------------------------------------------*/
                          
                          /* Private includes ----------------------------------------------------------*/
                          /* USER CODE BEGIN Includes */
                          /* USER CODE END Includes */
                          
                          /* Private typedef -----------------------------------------------------------*/
                          /* USER CODE BEGIN PTD */
                          /* USER CODE END PTD */
                          
                          /* Private define ------------------------------------------------------------*/
                          /* USER CODE BEGIN PD */
                          /* USER CODE END PD */
                          
                          /* Private macro -------------------------------------------------------------*/
                          /* USER CODE BEGIN PM */
                          /* USER CODE END PM */
                          
                          /* Private variables ---------------------------------------------------------*/
                          /* USER CODE BEGIN PV */
                          uint8 Fls_WriteData[2048] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
                          uint8 Fls_ReadData[8] = {0};
                          volatile uint8 Fls_EraseFailedCnt = 0;
                          volatile uint8 Fls_WriteFailedCnt = 0;
                          volatile uint32 Fls_EraseSusCnt = 0;
                          volatile uint32 Fls_WriteSusCnt = 0;
                          /* USER CODE END PV */
                          
                          /* Private function declare --------------------------------------------------*/
                          /* USER CODE BEGIN PFDC */
                          #define FLASH_TIMEOUT 10000000
                          #define FLASH_WRITE_UNIT 32
                          /* USER CODE END PFDC */
                          static void Board_Init(void);
                          
                          /* Private user code ---------------------------------------------------------*/
                          /* USER CODE BEGIN 0 */
                          /**
                           * @brief Custom implementation of memset
                           * @param dest Pointer to the destination memory
                           * @param value Value to set (converted to unsigned char)
                           * @param len Number of bytes to set
                           * @return Pointer to the destination memory
                           */
                           void memset(uint8 * dest, uint8 value, uint32 len) {
                            uint8 * ptr = dest;
                            while (len--) {
                                *ptr++ = value;
                            }
                          }
                          
                          /**
                          * @brief Custom implementation of memcpy
                          * @param dest Pointer to the destination memory
                          * @param src Pointer to the source memory
                          * @param len Number of bytes to copy
                          * @return Pointer to the destination memory
                          */
                          void memcpy(uint8 * dest, const uint8 * src, uint32 len) {
                            uint8 * d = dest;
                            const uint8 * s = src;
                            while (len--) {
                                *d++ = *s++;
                            }
                          }
                          
                          /**
                           * @brief Custom implementation of memcmp
                           * @param ptr1 Pointer to the first memory block
                           * @param ptr2 Pointer to the second memory block
                           * @param len Number of bytes to compare
                           * @return An integer less than, equal to, or greater than zero if the first n bytes of ptr1 
                           *         are found to be less than, to match, or be greater than the first n bytes of ptr2.
                           */
                           boolean memcmp(const uint8 * ptr1, const uint8 * ptr2, uint32 len) {
                            const uint8 * p1 =  ptr1;
                            const uint8 * p2 =  ptr2;
                          
                            while (len--) { 
                                if (*p1 != *p2) {
                                    return FALSE;
                                }
                                p1++;
                                p2++;
                            }
                            return TRUE;
                          }
                          /**
                           * @brief 擦除pflash1 1MB
                           */
                           boolean bsw_fls_erase_pflash1_1mb( void )
                           {
                               uint32 startAddress = 0;
                               uint32 sectorSize   = 0;
                               uint32 timeout      = FLASH_TIMEOUT;
                           
                               startAddress          = Fls_Config.SectorList[ FlsConf_FlsConfigSet_PFLASH_0 ].SectorStartAddress;
                               sectorSize            = Fls_Config.SectorList[ FlsConf_FlsConfigSet_PFLASH_0 ].SectorSize;
                           
                               Fls_Erase( startAddress, sectorSize );  // 开始擦除
                           
                               timeout = FLASH_TIMEOUT;
                               while ( --timeout > 0 )
                               {
                                   Fls_MainFunction( );
                                   if ( Fls_GetStatus( ) == MEMIF_IDLE )
                                   {
                                       return TRUE;  // 擦除成功
                                   }
                               }
                           
                               return FALSE;  // 擦除失败(超时)
                           }
                           
                           boolean bsw_fls_write_func( uint32 Addr, uint8* data, uint32 len )
                           {
                               uint32 timeout = 0;
                           
                               // 写入 Flash
                               timeout = 50;
                               while ( --timeout > 0 )
                               {
                                   if ( Fls_Write( Addr, data, FLASH_WRITE_UNIT ) != E_OK)
                                   {
                                       break;
                                   }
                           
                                   if ( timeout == 0 )
                                   {
                                       return FALSE;  // 写入失败
                                   }
                               };
                          
                              // 超时等待 Flash 空闲
                              timeout          = FLASH_TIMEOUT;
                              while ( --timeout > 0 )
                              {
                                  Fls_MainFunction( );
                                  if ( Fls_GetStatus( ) == MEMIF_IDLE )
                                  {
                                      break;
                                  }
                          
                                  if ( timeout == 0 )
                                  {
                                      return FALSE;
                                  }
                              }
                           
                               return TRUE;
                           }
                           /**
                            * @brief 写pflash1 1MB
                            * @param  AddrOffset       地址偏移
                            * @param  data             数据指针
                            * @param  len              数据长度
                            */
                           boolean bsw_fls_write_pflash1_1mb( uint32 AddrOffset, const uint8* data, uint32 len )
                           {
                               uint32 startAddress                    = 0;
                               uint32 alignedLen                      = 0;
                               uint32 i                               = 0;
                           
                               uint32 chunkSize                       = 0;
                               uint32 timeout                         = 0;
                               uint8  alignedData[ FLASH_WRITE_UNIT ] = { 0xFF };  // 预填充 0xFF
                               uint8  readBuffer[ FLASH_WRITE_UNIT ]  = { 0 };     // 读取缓存初始化
                           
                               if ( data == NULL_PTR || len == 0 )
                               {
                                   return FALSE;
                               }
                           
                               startAddress = Fls_Config.SectorList[ FlsConf_FlsConfigSet_PFLASH_0 ].SectorStartAddress + AddrOffset;
                               alignedLen   = ( ( len + ( FLASH_WRITE_UNIT - 1 ) ) / FLASH_WRITE_UNIT ) * FLASH_WRITE_UNIT;  // 向上取整到 32 字节对齐
                           
                               // 按 32 字节批量写入
                               for ( i = 0; i < alignedLen; i += FLASH_WRITE_UNIT )
                               {
                                   chunkSize = ( i + FLASH_WRITE_UNIT <= len ) ? FLASH_WRITE_UNIT : ( len - i );
                                   memset( alignedData, 0xFF, FLASH_WRITE_UNIT );  // 先填充 0xFF
                                   memcpy( alignedData, data + i, chunkSize );     // 复制实际数据
                           
                                   // 写入 Flash
                                   if ( !bsw_fls_write_func( startAddress + i, alignedData, FLASH_WRITE_UNIT ) )
                                   {
                                       return FALSE;
                                   }
                          
                          
                                   memset( readBuffer, 0, FLASH_WRITE_UNIT );  // 确保读取缓冲区清空
                           
                                   timeout = 50;
                           
                                    if ( Fls_Read( startAddress + i, readBuffer, FLASH_WRITE_UNIT ) != E_OK)
                                    {
                                        return FALSE;
                                    }
                           
                                   // 等待读取完成
                                   timeout = FLASH_TIMEOUT;
                                   while ( --timeout > 0 )
                                   {
                                       Fls_MainFunction( );
                                       if ( Fls_GetStatus( ) == MEMIF_IDLE )
                                       {
                                           break;
                                       }
                           
                                       if ( timeout == 0 )
                                       {
                                           return FALSE;
                                       }
                                   }
                                   // 进行数据比对
                                   if ( memcmp( readBuffer, alignedData, FLASH_WRITE_UNIT ) != TRUE )
                                   {
                                       return FALSE;  // 校验失败
                                   }
                               }
                           
                               return TRUE;
                           }
                           
                           /**
                            * @brief 读pflash1 1MB
                            * @param  AddrOffset       地址偏移
                            * @param  data             数据指针
                            * @param  len              数据长度
                            */
                           boolean bsw_fls_read_pflash1_1mb( uint32 AddrOffset, uint8* data, uint32 len )
                           {
                               uint32 startAddress = 0;
                               uint32 timeout      = 0;
                           
                               if ( data == NULL_PTR || len == 0 )
                               {
                                   return FALSE;
                               }
                           
                               startAddress = Fls_Config.SectorList[ FlsConf_FlsConfigSet_PFLASH_0 ].SectorStartAddress + AddrOffset;
                           
                               // 超时等待 Flash 空闲
                               timeout      = FLASH_TIMEOUT;
                               while ( --timeout > 0 )
                               {
                                   Fls_MainFunction( );
                                   if ( Fls_GetStatus( ) == MEMIF_IDLE )
                                   {
                                       break;
                                   }
                           
                                   if ( timeout == 0 )
                                   {
                                       return FALSE;
                                   }
                               }
                           
                               timeout = 50;
                               while ( --timeout > 0 )
                               {
                                   if ( !Fls_Read( startAddress, data, len ) )
                                   {
                                       break;
                                   }
                           
                                   if ( timeout == 0 )
                                   {
                                       return FALSE;  // 写入失败
                                   }
                               };
                           
                               timeout = FLASH_TIMEOUT;
                               while ( --timeout > 0 )
                               {
                                   Fls_MainFunction( );
                                   if ( Fls_GetStatus( ) == MEMIF_IDLE )
                                   {
                                       return TRUE;  // 读取成功
                                   }
                               }
                           
                               return FALSE;  // 超时或读取失败
                           }
                           
                          /* USER CODE END 0 */
                          
                          
                          /**
                           * @brief  The application entry point.
                           * @retval int
                           */
                          int main(void)
                          {
                              /* USER CODE BEGIN 1 */
                              Mcu_Init(&Mcu_Config);
                              Mcu_InitClock(0);
                          #if (MCU_NO_PLL == STD_OFF)
                              while (MCU_PLL_LOCKED != Mcu_GetPllStatus())
                              {
                                  /* Wait until PLL is locked */
                              }
                              Mcu_DistributePllClock();
                          #endif
                              /* USER CODE END 1 */ 
                              Board_Init();
                              /* USER CODE BEGIN 2 */
                              /*Operate the sector FlsConf_FlsConfigSet_DFLASH_0,the step is as follows:
                              *step I  :erase the sector,
                              *step II :write Fls_WriteData to the sector 0 to 7 byte,
                              *step III:read the sector 0 to 7 byte to Fls_ReadData,and check the data,
                              *step IV :compare the data in flash,
                              *step V  :if the Fls_WriteData and Fls_ReadData are equal,then the test is pass and erase the sector.
                              *step VI :verify the Flash blank or not
                              */
                          
                              /* USER CODE END 2 */
                          
                              /* Infinite loop */
                              /* USER CODE BEGIN WHILE */
                              while (1)
                              {
                                    
                                  if(bsw_fls_erase_pflash1_1mb() == TRUE)
                                  {
                                      Fls_EraseSusCnt++;
                                  }
                                  else
                                  {
                                    Fls_EraseFailedCnt++;
                                  }
                          
                                  if(Fls_GetStatus()== MEMIF_BUSY)
                                  {
                                      while(1)
                                      {
                                        __ASM("NOP");
                                      }
                                  }
                                  
                                  if(bsw_fls_write_pflash1_1mb(0, (uint8 *)0x2000000, 0x100000) == TRUE)
                                  {
                                      Fls_WriteSusCnt++;
                                  }
                                  else
                                  {
                                    Fls_WriteFailedCnt++;
                                  }
                          
                                  if(Fls_GetStatus()== MEMIF_BUSY)
                                  {
                                      while(1)
                                      {
                                        __ASM("NOP");
                                      }
                                  }
                                  /* USER CODE END WHILE */
                                  /* USER CODE BEGIN 3 */
                              }
                              /* USER CODE END 3 */
                          }
                          
                          static void Board_Init(void)
                          {
                              Fls_Init(&Fls_Config);
                          }
                          
                          /* USER CODE BEGIN 4 */
                          /* USER CODE END 4 */
                          
                          Liam.LiuL 1 条回复 最后回复
                          0
                          • Liam.LiuL 离线
                            Liam.LiuL 离线
                            Liam.Liu
                            在 回复了 houjun_xiao 最后由 编辑
                            #13

                            houjun_xiao 部分板子的复现概率还是挺高的,刚试了一下你这份改动的代码,也会出现错误:f5abb1e2-bbcd-4c91-910b-e85f6de557f9-image.png
                            查看了一下memory,写操作返回了成功,但是实际上没有写入数据

                            1 条回复 最后回复
                            0
                            • houjun_xiaoH 离线
                              houjun_xiaoH 离线
                              houjun_xiao YunTu
                              写于 最后由 编辑
                              #14

                              image.png
                              在AUTOSAR中,Fls的Write,Read,Erase操作API都是异步函数,实际执行这几个操作都是要靠Fls_MainFunction来调度和执行的。

                              Liam.LiuL 1 条回复 最后回复
                              0
                              • Liam.LiuL 离线
                                Liam.LiuL 离线
                                Liam.Liu
                                在 回复了 houjun_xiao 最后由 编辑
                                #15

                                houjun_xiao 这个理解的。我们设计代码时,参考了Fls_Demo以及FLS-FEE MCAL应用介绍_20241127.pptx的指导。发现写完之后读不出来或者就没写进去,但是底层写/读接口返回值都是正常,Fls_GetStatus接口返回为Busy,才加上了先Fls_Cancel,再进行重新读写的方案

                                1 条回复 最后回复
                                0
                                • houjun_xiaoH 离线
                                  houjun_xiaoH 离线
                                  houjun_xiao YunTu
                                  写于 最后由 编辑
                                  #16

                                  Fee的操作跟Fls是一样的,他的操作函数都是异步函数,需要调用Fee_MainFunction来进行调度和状态管理,同时由于Fee需要调用Fls的操作才能实现数据存储与读取,因此调用Fee_MainFunction的同时,也需要调用Fls_MainFunction

                                  1 条回复 最后回复
                                  0

                                • 云途论坛规则/Yuntu Forum Rules

                                  发帖前请查看

                                • YCT离线License申请流程

                                  帮助没办法联网的电脑使用YCT

                                • YT CONFIG TOOL调查问卷

                                  帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...

                                • demo
                                  12
                                  can
                                  8
                                  lin stack
                                  6
                                  yt-link
                                  5
                                  vscode
                                  3
                                  adc模块
                                  2
                                  i2c
                                  2
                                  uuid
                                  2
                                  Online Users
                                  Peihua_HanP
                                  Peihua_Han
                                  EkkoE
                                  Ekko
                                  mcM
                                  mc
                                  • 登录

                                  • 登录或注册以进行搜索。
                                  • 第一个帖子
                                    最后一个帖子
                                  0
                                  • 版块
                                  • 最新
                                  • 标签
                                  • 热门